Skip to content

feat(chart): set the service info from values - #285

Merged
uniqueg merged 6 commits into
devfrom
feat/282-service-info
Nov 11, 2026
Merged

uniqueg merged 6 commits into
devfrom
feat/282-service-info

Conversation

@uniqueg

@uniqueg uniqueg commented Nov 11, 2026 •

Copy link
Copy Markdown
Member

Summary

The chart renders GET /service-info from values now, so it can be set when installing a packaged chart:

  • New values serviceInfo.*: id, name, description, organization.name, organization.url, contactUrl, documentationUrl, createdAt, updatedAt, environment and storage. They are rendered into the existing ConfigMap <prefix>-service-info, under the same key service-info.yaml and mount path.
  • serviceInfo.existingConfigMap mounts a ConfigMap of the operator's instead, and the chart then renders none.
  • The file charts/tesk/service-info/service-info.yaml is removed.
  • The chart sets type (org.ga4gh, TES, 1.0.0) and version (the tag of tesk-api's image) itself. A new helper tesk.apiImageTag gives the tag to the image and to version alike.
  • What tesk-api v1.2.0's parser needs (SnakeYAML loadAs(TesServiceInfo); a parse error leaves GET /service-info empty, with probes still passing):
    • Text fields are double-quoted (tesk.yamlText).
    • createdAt and updatedAt are unquoted YAML 1.1 timestamps, checked by the schema ($defs/timestamp) and by the template.
    • Characters that YAML doesn't allow fail with the value's key.
    • Whole numbers from values files are rendered as written, and fail above 2^53.
  • The fields that the GA4GH spec requires (id, name, organization.*) fail if empty. Empty optional fields are left out.
  • A checksum/service-info pod annotation restarts the API on changes, as tesk-api re-reads the file only hourly.
  • The notes remind operators to describe their deployment while serviceInfo.id is the default.
  • Docs:
    • The configuration reference has a new section with all values and an example.
    • The deployment guide replaces "edit the file" with serviceInfo.
    • The upgrade notes (0.3.0) say how to move an edited file into values, or into an existing ConfigMap.

Decisions

  • File vs. values (the question that feat(chart): set the service info from values #282 leaves open): values replace the file, and the file is removed. Keeping both would mean guessing which one wins, as the chart can't tell an edited file from the default one. Removing the file is the least surprising option:
    • An operator who edited it gets a git conflict on update, rather than having the edits silently ignored.
    • Releases without their own serviceInfo render the same content as before (see the next point).
    • Operators who manage the file themselves use existingConfigMap.
    • This is documented in the upgrade notes.
  • Defaults reproduce the old file: id, name, description, organization, createdAt, environment: dev and storage are unchanged. There are three deliberate differences:
  • NOTES: a NOTE: while the id is the default, rather than a WARNING:, since it applies to every default install.
  • No version bump: this goes into the unreleased 0.3.0. docs/releases/0.3.0.md gets a Features bullet and, as operators who edited the file must move their edits, a Breaking changes bullet. Both are appended at the ends of their sections, away from feat(chart): set the OIDC provider and groups #284's edits.
  • Independent of feat(chart): set the OIDC provider and groups #284 (feat(chart): set tesk-api's OIDC and group settings #281): both PRs are based on dev, and their changes don't overlap. git merge-tree of the two branches merges cleanly, and the chart tests pass on the merged tree (509 tests at the time of the check).

Verification

Local runs with Helm v3.22.1, as pinned in CI:

  • helm lint charts/tesk --strict: passed.
  • helm template with the defaults and with the docs' examples: rendered.
  • REQUIRE_HELM=1 pytest tests/test_chart.py: 470 passed (the dev branch has 425). The new tests cover:
    • the defaults, every field from a values file, and empty optional fields
    • required fields and timestamps (as PyYAML reads them, YAML 1.1 like SnakeYAML; invalid ones with and without the schema)
    • text that YAML would read otherwise (numbers, booleans, dates, control characters)
    • version against the image tag, numeric tags, existingConfigMap, the checksum and the NOTES reminder
  • coverage run -m pytest --ignore=tests/test_chart.py: 156 passed, 100% coverage.
  • pre-commit run --all-files: passed.
  • mkdocs build --strict: passed; the anchor #service-info-serviceinfo, which NOTES links to, exists.
  • Not run locally: the kind install (Chart install). The sandbox blocks the Docker socket and kind isn't installed. CI runs it; it checks that GET /service-info returns an id and type.group: org.ga4gh from a real tesk-api 1.2.0, which exercises the parse.

After the Sourcery fixes (33d3871): 478 chart tests passed locally, pre-commit, helm lint --strict and mkdocs build --strict passed. CI on 33d3871: all checks passed (CI passed, Chart, Chart install on kind, Lint, Test, Docs, Release readiness, PR title, CodeQL, Codecov, Sourcery, Read the Docs).

Review

Full review (Helm chart): adversarial-reviewer and quality-reviewer, then a second adversarial round. Fixed:

  • Timestamps now use the YAML 1.1 pattern: a one-digit month or day without a time passed the check, but tesk-api reads it as text.
  • existingConfigMap is decided in one helper. Before, false or 0 dropped the ConfigMap but kept mounting it. The schema now also requires a string for it.
  • The image tag logic is shared between the image and version.
  • Characters that YAML rejects are now escaped or fail with the key. Numbers above 2^53 fail.
  • Whole-number image tags from values files are rendered as written. This also fixes the older rendering of the image line as 2.026111e+07.
  • Tests and docs were tightened.

Sourcery (5 threads, all answered and resolved):

  • Fixed: numeric image tags at or above 2^53 fail instead of rendering a rounded tag.
  • Fixed: dates and times that don't exist (e.g., 2021-02-30, 24:00:00) fail, as SnakeYAML would read them as other ones.
  • Fixed in the docs: with existingConfigMap, the other fields are not used but still checked against the schema.

Declined review findings

  • Sourcery: a size check against the 1 MiB ConfigMap limit. The API server's error is clear, and the chart checks no object sizes elsewhere.

  • Sourcery: allowing exactly ±2^53. 2^53 + 1 is read as 2^53 too, so the bound must exclude it (as in tesk.secretValue).

  • The NOTES reminder compares against the literal default id instead of reading values.yaml, which templates can't do. A test now pins the literal to VALUES, and comments at both places refer to each other.

Open questions

None.

Closes #282

🤖 Generated with Claude Code

https://claude.ai/code/session_011FSoqMpmDCfbACLj3uy6xV

Summary by Sourcery

Configure and validate the API service information through Helm values while supporting operator-managed ConfigMaps and automatic pod refreshes.

New Features:

  • Configure GA4GH service information through Helm values, including support for supplying an operator-managed ConfigMap instead of chart-generated data.

Bug Fixes:

  • Keep the API image tag and service-info version consistent while preserving numeric tags accurately and rejecting values that cannot be represented exactly.
  • Validate and safely render service-info text and timestamps so invalid YAML or values that tesk-api cannot parse fail during installation.

Enhancements:

  • Restart API pods when chart-managed service information changes and provide an installation note when the deployment still uses the default service ID.
  • Set service-info type and version from chart metadata and the API image tag, while omitting empty optional fields and enforcing required fields.

Documentation:

  • Document service-info values, packaged-chart configuration, migration to values or an existing ConfigMap, and the 0.3.0 upgrade implications.

Tests:

  • Add comprehensive chart coverage for defaults, value rendering, validation, existing ConfigMaps, image-tag/version handling, checksums, and installation notes.

Chores:

  • Remove the file-based service-info configuration from the chart.

uniqueg and others added 3 commits November 10, 2026 22:55
Render GET /service-info from the new values serviceInfo.* (id, name,
description, organization, contactUrl, documentationUrl, createdAt,
updatedAt, environment, storage) instead of the file
charts/tesk/service-info/service-info.yaml, which needed a checkout of
the chart; serviceInfo.existingConfigMap mounts a ConfigMap of the
operator's instead. The defaults reproduce the old file, except for the
contact and documentation URLs (now this repository and its docs). The
chart sets type (TES 1.0.0) and version (tesk-api's image tag) itself.

Text fields are quoted, and createdAt and updatedAt are rendered as YAML
timestamps and checked, as tesk-api reads them as dates and answers
without service info if the file can't be read. The fields required by
the GA4GH specification fail if empty. A change restarts the API's pod,
and the notes remind operators while the id is the default.

Document the values, the removed file and the upgrade.

Closes #282

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011FSoqMpmDCfbACLj3uy6xV
Check createdAt and updatedAt against YAML 1.1's timestamp pattern (a
two-digit month and day without a time), as SnakeYAML reads other dates
as text, which tesk-api can't parse; one schema definition. Decide the
mounted ConfigMap in one helper, so that the volume and the chart's
ConfigMap agree, and take the service info's version and the image tag
from one helper. Escape DEL and NEL in text, and fail on whole numbers
too large to be exact. Test the version against the image tag, the
timestamps as YAML reads them, and the fields by name; document quoting
of numeric text and the unchanged defaults.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011FSoqMpmDCfbACLj3uy6xV
Fail with the value's key on characters that YAML doesn't allow and JSON
doesn't escape (C1 controls but NEL, U+FFFE, U+FFFF), and name the key
in the error for numbers too large to be exact. Render whole-number
image tags from values files as written, for the image and the service
info's version alike.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011FSoqMpmDCfbACLj3uy6xV
@sourcery-ai

sourcery-ai Bot commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

Reviewer's Guide

API

Define the chart’s public service-info values contract, including validation for timestamps and the other fields.

  • charts/tesk/values.schema.json L50-57, L543-619

Implementation

Implement service-info rendering and shared helpers for selecting its ConfigMap, formatting values, and deriving the API image tag.

  • charts/tesk/templates/_helpers.tpl L60-95, L363-470

Use the shared helpers to render or mount the service-info ConfigMap and restart the API when its rendered contents change.

  • charts/tesk/templates/common/service-info-cm.yaml L1-13
  • charts/tesk/templates/common/tesk-deployment.yaml L9-13, L29-38, L233

Show an installation reminder while the default service ID is in use, except when an operator supplies an existing ConfigMap.

  • charts/tesk/templates/_helpers.tpl L265-272

Configuration

Add defaults and operator-facing values for rendering service info or mounting an existing ConfigMap, and remove the chart’s former service-info source file.

  • charts/tesk/values.yaml L249-284
  • charts/tesk/service-info/service-info.yaml (deleted)

Documentation

Document the service-info values, defaults, example, ConfigMap option, and object-name behavior in the configuration reference.

  • docs/configuration.md L142-197, L254, L293 (removed lines)

Update deployment and upgrade guidance to move service-info edits into values or an operator-managed ConfigMap.

  • docs/deployment.md L54-59
  • docs/upgrading.md L439-483

Record the removed file as a breaking change and the new values-based service info as a feature for the 0.3.0 release.

  • docs/releases/0.3.0.md L13, L25

Tests

Cover service-info defaults, value rendering and validation, image-version consistency, ConfigMap selection, checksums, notes, and removal of the old source file.

  • tests/test_chart.py L1363-1366, L1374-1797 (+3 small edits)

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@codecov

codecov Bot commented Nov 11, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (1b2c168) to head (b750b7f).

Additional details and impacted files
@@            Coverage Diff            @@
##               dev      #285   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            2         2           
  Lines          422       422           
=========================================
  Hits           422       422           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

List the service info values under Features, and the removed file under
Breaking changes, as operators who edited it must move their edits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011FSoqMpmDCfbACLj3uy6xV
@uniqueg
uniqueg marked this pull request as ready for review November 11, 2026 00:28
@sourcery-ai

sourcery-ai Bot commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

Linked issues

Checked at commit b750b7f

#282 feat(chart): set the service info from values · 5 of 5 met

# Requirement Status Notes
1 Render the service info from values into the ConfigMap ✅ Met The chart renders the serviceInfo fields into service-info.yaml in the existing ConfigMap and preserves the mount path.
2 Let operators use serviceInfo.existingConfigMap instead ✅ Met When set, the chart omits its ConfigMap and mounts the named one.
3 Keep type and version as the chart knows them ✅ Met The chart sets the TES type and derives version from the API image tag.
4 Update the contact and documentation URLs while keeping id and environment as defaults to override ✅ Met The values defaults use the current repository and docs URLs, retain the default ID and dev environment, and the notes remind operators to set deployment-specific values.
5 Add chart tests, a configuration reference and upgrade notes; decide whether the file remains or is replaced ✅ Met Tests and configuration and upgrade documentation are added; the chart file is removed, with migration options documented.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 5 issues

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="charts/tesk/templates/_helpers.tpl" line_range="85-89" />
<code_context>
+{{- if or (kindIs "invalid" $tag) (eq (toString $tag) "") -}}
+{{- $tag = .Chart.AppVersion -}}
+{{- end -}}
+{{- if and (kindIs "float64" $tag) (eq (floor $tag) $tag) -}}
+{{- printf "%.0f" $tag -}}
+{{- else -}}
+{{- toString $tag -}}
+{{- end -}}
+{{- end -}}
+
</code_context>
<issue_to_address>
**Wrong image tag is deployed**

When an unquoted whole-number image tag in a values file is rounded by Helm, `tesk.apiImageTag` formats the rounded float, so the Deployment requests a different image tag and the service-info version reports that rounded tag; the API image cannot pull the requested tag.

Reject numeric image tags that may have lost precision and require them to be supplied as strings.
</issue_to_address>

### Comment 2
<location path="charts/tesk/templates/_helpers.tpl" line_range="364" />
<code_context>
+{{- /* YAML 1.1 timestamps, as SnakeYAML resolves them (two-digit month
+and day without a time); the same pattern as `$defs/timestamp` in
+values.schema.json, which checks them first */ -}}
+{{- $timestamp := "^([0-9]{4}-[0-9]{2}-[0-9]{2}|[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}([Tt]|[ \t]+)[0-9]{1,2}:[0-9]{2}:[0-9]{2}(\\.[0-9]*)?([ \t]*(Z|[-+][0-9]{1,2}(:[0-9]{2})?))?)$" -}}
+{{- range $field := list "createdAt" "updatedAt" -}}
+{{- $value := index $info $field -}}
</code_context>
<issue_to_address>
**Invalid dates change in service info**

When `serviceInfo.createdAt` or `serviceInfo.updatedAt` contains a shape-matching but impossible calendar date or time, `tesk.serviceInfo` accepts the value because `$timestamp` checks only its shape, then emits it unquoted; SnakeYAML normalizes the invalid timestamp and `/service-info` reports a different date from the configured value.

Validate calendar components before emitting the timestamp.

Also at `charts/tesk/templates/_helpers.tpl:367-368`.
</issue_to_address>

### Comment 3
<location path="charts/tesk/templates/common/service-info-cm.yaml" line_range="12" />
<code_context>
 data:
-{{ (.Files.Glob "service-info/*").AsConfig | indent 2 }}
+  service-info.yaml: |
+    {{- . | nindent 4 }}
+{{- end }}
</code_context>
<issue_to_address>
**Large values exceed ConfigMap limit**

When A service-info value or collection makes the rendered ConfigMap data exceed 1 MiB, the template inserts service-info values into the ConfigMap without a size check. If the rendered data exceeds Kubernetes’ 1 MiB ConfigMap limit, the API server rejects the ConfigMap and Helm cannot complete the install or upgrade.

Validate the rendered ConfigMap data size and fail with a clear Helm error before Kubernetes rejects the resource.
</issue_to_address>

### Comment 4
<location path="charts/tesk/templates/_helpers.tpl" line_range="424" />
<code_context>
+{{- $value := .value -}}
+{{- $text := toString $value -}}
+{{- if and (kindIs "float64" $value) (eq (floor $value) $value) -}}
+{{- if not (and (lt $value 9007199254740992.0) (gt $value -9007199254740992.0)) -}}
+{{- fail (printf "%s is a number too large to be exact: quote it in the values file or use --set-string" .key) -}}
+{{- end -}}
</code_context>
<issue_to_address>
**Exact boundary values are rejected**

When a text field is supplied as the unquoted number `9007199254740992` or `-9007199254740992`, `tesk.yamlText` uses strict comparisons that reject both exactly representable `float64` boundary values, so Helm fails to render the service-info value.

Allow values equal to either 2^53 boundary in the precision check.
</issue_to_address>

### Comment 5
<location path="charts/tesk/templates/_helpers.tpl" line_range="354" />
<code_context>
+*/}}
+{{- define "tesk.serviceInfo" -}}
+{{- $info := default dict .Values.serviceInfo -}}
+{{- if not (include "tesk.isSet" $info.existingConfigMap) -}}
+{{- $organization := default dict $info.organization -}}
+{{- range $field, $value := dict "id" $info.id "name" $info.name "organization.name" $organization.name "organization.url" $organization.url -}}
</code_context>
<issue_to_address>
**Ignored values still block installation**

When `serviceInfo.existingConfigMap` is set while another `serviceInfo` value is malformed, helm validates `values.schema.json` before rendering, so setting `serviceInfo.existingConfigMap` does not bypass the schema checks on the other `serviceInfo` fields. A malformed value such as `createdAt: yesterday` therefore prevents installation even though the template skips rendering those fields and the documentation says they are ignored.

Make schema validation conditional on `existingConfigMap` being unset, or otherwise avoid validating fields that are documented as ignored in this mode.
</issue_to_address>

Sourcery assessment

Approval pending. 5 findings to address first.

Blocking findings: charts/tesk/templates/_helpers.tpl:89, charts/tesk/templates/_helpers.tpl:364, charts/tesk/templates/common/service-info-cm.yaml:12, charts/tesk/templates/_helpers.tpl:424, charts/tesk/templates/_helpers.tpl:354


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

Comment thread charts/tesk/templates/_helpers.tpl Resolved
Comment thread charts/tesk/templates/_helpers.tpl Resolved
Comment thread charts/tesk/templates/_helpers.tpl Resolved
Comment thread charts/tesk/templates/_helpers.tpl Resolved
uniqueg and others added 2 commits November 11, 2026 01:38
Fail on dates and times that look like YAML timestamps but don't exist
(e.g., 2021-02-30, 24:00:00), which SnakeYAML would read as other ones,
and on numeric image tags above 2^53, which Helm would round. Say that
the other serviceInfo values are still checked against the schema with
an existing ConfigMap.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011FSoqMpmDCfbACLj3uy6xV
@uniqueg
uniqueg merged commit aa74687 into dev Nov 11, 2026
23 checks passed
@uniqueg
uniqueg deleted the feat/282-service-info branch November 11, 2026 10:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(chart): set the service info from values

1 participant