Skip to content

feat(release): add managed source releases - #237

Open
jsell-rh wants to merge 16 commits into
mainfrom
codex/source-release-strategy
Open

feat(release): add managed source releases#237
jsell-rh wants to merge 16 commits into
mainfrom
codex/source-release-strategy

Conversation

@jsell-rh

@jsell-rh jsell-rh commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Add a Release Please source-release process based on Conventional Commits.
  • Keep one release pull request open and update it after successful main builds.
  • Keep Jira tracking after the conventional type in pull request titles.
  • Keep pull request and merge-queue image builds component-selective.
  • Build all three component images once after the final VERSION merge.
  • Add local and CI build identities to the three images.
  • Expose the API build identity through service metadata.
  • Show the API and web-console build identities in the user menu.
  • Keep image promotion and Argo configuration out of scope.

Validation

  • make check
  • pnpm check:web
  • API integration tests with PostgreSQL
  • Actionlint for all GitHub Actions workflows
  • Tekton YAML parsing
  • Release Please 17.6.1 configuration validation
  • Local API and web-console container builds

Release PR checks

Release Please uses the built-in GITHUB_TOKEN. No app, repository variable, or repository secret is required. GitHub holds workflows for an automation-created Release PR until a user with write access selects Approve workflows to run. Approve the workflows for the current revision before merge.

@coderabbitai

coderabbitai Bot commented Sep 2, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Team

Run ID: 3e9cd93f-96fb-4fe0-ac5a-460222715281

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@jsell-rh

jsell-rh commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator Author

Amber review: comment

Amber review

Status: Complete

View the submitted review.

@jsell-rh jsell-rh left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Verdict

COMMENT. This is a carefully built, well-tested source-release and build-identity change: pinned actions, minimal token scopes, env-wrapped untrusted input, additive tests, and policy checks that all pass locally (make check, release_policy.py, check_image_build_policy.py, the Python unit tests, build-version.sh). No blockers or security regressions found; the main thing that needs a decision is a repo-wide PR-title policy that collides with the team's existing [HYPERSHELL-XXX] titling habit.

What I verified

  • make check gates (check-release-policy, check-image-build-policy) and the new Python unit tests pass in this tree.
  • scripts/build-version.sh local|ci produce dev-58b1e9a / v0.0.0-58b1e9a as designed, and degrade to dev-unknown without a SHA.
  • Release-file consistency (VERSION = .release-please-manifest.json . = build-version.env BUILD_PREFIX minus v) is internally consistent (0.0.0 / v0.0.0), and bootstrap-sha points at the current main tip.
  • Web-console changes are additive; the tracing "fail-closed to sampleRatio 0" guarantee is preserved, and no secret crosses the BFF->browser boundary (the browserRuntimeConfig key-set test still enforces this).
  • The /metadata endpoint is intentionally unauthenticated (security: [] + auth-bypass) but only exposes build version and build time -- no secret exposure.
  • Modified test assertions are all additive contract widenings (new build field), not silent guarantee removals.

Findings

[Major] New required PR-title gate conflicts with the repo's [HYPERSHELL-XXX] titling convention.
REL-01 + scripts/release_policy.py require every PR title to start with <type>(<scope>)!: <desc>, and the title becomes the squash subject that Release Please parses. Nearly all recent merged commits and open PRs use a [HYPERSHELL-XXX] ... prefix, which this regex rejects. See the Cross-PR section -- this needs a maintainer decision before/at merge.

[Minor] scripts/check_image_build_policy.py couples the policy to an exact Dockerfile substring.
The check matches a literal ${VCS_REF%????...} (exactly 33 ?) and full label strings. A harmless Dockerfile reformat (whitespace, quoting) will fail the gate with a message that doesn't point at the real cause. Consider matching on the semantic pieces (org.opencontainers.image.revision, HYPERSHELL_BUILD_VERSION) rather than the exact expansion literal.

[Minor / informational] Extended ${VAR%pattern} expansion in ENV/LABEL relies on the BuildKit Dockerfile frontend.
It works because each Dockerfile declares # syntax=docker/dockerfile:1, but it silently no-ops under a legacy builder. Fine as-is given the syntax pin; just noting the dependency.

Cross-PR coordination

Merging this PR turns the Conventional-Commit PR-title check (lint-pull-request-title, backed by scripts/release_policy.py check-title and REL-01) into a required gate whose regex requires the title to begin with a lowercase <type>. The prevailing repository practice prefixes titles with a Jira key, e.g. [HYPERSHELL-XXX] feat: ..., which this regex rejects; because the title also becomes the squash-merge subject, such titles would additionally break Release Please's changelog/version parsing on main. Maintainers must decide the convention -- either drop the bracketed prefix going forward, or widen the regex to permit an issue-key affix -- and then coordinate retitling of the in-flight PRs that currently use the prefix so they can pass the new required check once this merges: #235, #232, #227, #210, and #208. #214 and #109 are also affected because their titles are not in conventional form at all.

Findings Summary (ordered by severity, highest first):

  1. [Major] New required PR-title gate conflicts with the established [HYPERSHELL-XXX] prefix used across history and open PRs - Cross-PR / Process (release_policy.py L32)
  2. [Minor] Image build policy check pinned to exact Dockerfile substrings is brittle - Maintainability (check_image_build_policy.py L56)
  3. [Minor] ${VAR%pattern} in ENV/LABEL depends on the BuildKit frontend - Portability (components/*/Dockerfile)

Convention Checklist:

Convention Result
No panic() in production code Pass
Errors wrapped with fmt.Errorf context Pass
No secrets in logs or responses Pass
Input validated (title, VERSION, SHA, build version) Pass
SecurityContext (no pod specs changed) N/A
OpenAPI client regenerated, not hand-edited Pass
Conventional commit messages Pass
Test diff scrutiny (no silent guarantee removal) Pass
Image references consistent across manifests Pass

Comment thread scripts/release_policy.py
Comment thread scripts/check_image_build_policy.py Outdated
@jsell-rh

jsell-rh commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator Author

Amber review

Status: Stopped

The pull request head changed before Amber posted the review. A later job can review the new head.

@jsell-rh

jsell-rh commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator Author

Amber review is addressed.

  • Jira keys are now valid after the Conventional Commits prefix, for example feat(api): [HYPERSHELL-123] description.
  • The image metadata check now parses logical Dockerfile assignments and reports specific semantic errors.
  • The BuildKit variable expansion remains intentional. Each component Dockerfile pins the Dockerfile frontend syntax.
  • The generated API metadata documentation now matches the generator output.
  • AGENTS.md, CLAUDE.md, and the release guide now contain the pull request title rule.
  • The user menu reads the console version once and shows separate API and console image versions.
  • The anonymous metadata response remains intentional. Its version and shared framework build time are non-secret operator data.

Release Please now uses the built-in GITHUB_TOKEN. No app credentials are required. A user with write access must approve the workflow runs for the current Release PR revision before merge.

@jsell-rh

jsell-rh commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator Author

Amber review

Status: Stopped

The pull request head changed before Amber posted the review. A later job can review the new head.

@jsell-rh

jsell-rh commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator Author

Amber review: comment

Amber review

Status: Complete

View the submitted review.

@jsell-rh jsell-rh left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Verdict

This is a well-structured, well-tested release-automation change: Release Please wiring, a conventional PR-title gate, build-identity embedding across images, a public /metadata endpoint, and a web-console version display, all with matching Python/Go/TS tests that pass locally. The code is convention-compliant and I found no blocking defects; my notes are minor, plus one cross-PR coordination item that needs a maintainer decision because this PR introduces a new required PR-title check that conflicts with the title format several open PRs currently use.

I verified make-level policy checks locally: release_policy.py check-files, check_image_build_policy.py, and the three Python unittest suites all pass. The build-identity ldflags target (rh-trex-ai/pkg/api.Version/BuildTime) is consistent across the Makefiles and Dockerfiles, the removed local api.Version/api.BuildTime vars have no remaining references, and the SDK generator correctly excludes the x-sdk-exclude singleton (with a guard test).

Findings

Minor — Security (info disclosure): openapi.yaml:23,91
The /metadata endpoint is made unauthenticated (security: [], added to auth-bypass-paths) and returns version and build_time. Exposing an exact build version and build timestamp to anonymous callers makes version fingerprinting (matching a deployment to known CVEs) easier. This is intentional and the values are not secrets, so it's minor — but consider whether the precise build_time needs to be anonymous, or whether the version string alone suffices for the console/health use case. Confidence: Medium.

Minor — Design: components/web-console/app/features/shell/user-menu.tsx:26
readBrowserRuntimeConfig() is invoked during render, which re-reads the injected meta tag and JSON.parses it on every render of UserMenu. It's cheap and correct, but reading the runtime config once (e.g. a memoized/composition-provided value) would keep the parse off the render path and match the "read runtime config at composition boundary" intent. Confidence: Medium.

Test Diff Scrutiny

The modified assertions in browser-runtime-config.test.ts, bff/test/config.test.ts, and bff/test/app.test.ts are additive: they add the new build field to expected objects while preserving the existing tracing guarantees (invalid ratio still falls back to 0, invalid build version is ignored without disturbing tracing). No pre-existing guarantee was flipped from accepted→rejected, and the optional→required change (HYPERSHELL_BUILD_VERSION validation) is on a brand-new optional field, so no backfill/migration is required.

Cross-PR coordination

This PR adds lint-pull-request-title as a required lint gate and codifies a specific convention (docs/releasing.md, AGENTS.md, CLAUDE.md, scripts/release_policy.py): the PR title must start with a Conventional Commits type and any Jira key must appear after the colon. Because the PR title becomes the squash commit subject that Release Please parses, this is a plan/interface change, not just a lint preference.

Several open pull requests use the opposite title form (Jira key before the type, e.g. [HYPERSHELL-NNN] feat: ..., or no conventional type at all). I confirmed the following titles fail the new checker and would be blocked by the required gate once this merges, until retitled: #235, #232, #227, #210, #208, #214, #109.

Maintainers should decide the rollout/merge order and notify those authors to retitle: either merge #237 and require the affected PRs to update their titles, or coordinate the change so in-flight work isn't blocked unexpectedly. This is a decision about sequencing and communication, not a defect in this PR.

Findings Summary (ordered by severity, highest first)

  1. [Minor] Unauthenticated /metadata exposes version + build_time (version fingerprinting) - Security (openapi.yaml L23, L91)
  2. [Minor] readBrowserRuntimeConfig() parsed on every UserMenu render - Design (user-menu.tsx L26)

Convention Checklist

Convention Result
No panic() in production code Pass
Errors wrapped with fmt.Errorf context Pass
No secrets in logs or responses Pass
Input validated (build version, VCS ref, PR title) Pass
Image references consistent across manifests Pass
OpenAPI client not manually edited Pass
Conventional commit messages Pass
Test diff scrutiny (no flipped guarantees) Pass

Comment thread components/api-server/openapi/openapi.yaml
Comment thread components/web-console/app/features/shell/user-menu.tsx Outdated
@jsell-rh

jsell-rh commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator Author

Amber review: comment

Amber review

Status: Complete

View the submitted review.

@jsell-rh jsell-rh left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Verdict

COMMENT. This is a well-structured, spec-backed source-release feature (Release Please + build identity + API/console version surfacing) with thorough tests and self-enforcing policy checks. I found no blockers or security-critical defects; the notes below are minor, and there are cross-PR coordination items that maintainers should sequence before merge.

What I verified

  • release_policy.py check-files, check_image_build_policy.py, and release_policy.py check-title on the PR's own title all pass in the PR tree.
  • Removing Version/BuildTime from components/api-server/pkg/api/api.go and retargeting the ldflags to rh-trex-ai/pkg/api is safe: no production code references the old symbols, and the metadata handler/route is supplied by the framework via MetadataID: "hypershell".
  • The generated OpenAPI client (ServiceMetadata, api_default.go, docs) is consistent with the source spec (spec SHA updated), i.e. regenerated rather than hand-edited.
  • Modified tests are additive (they add the build field / metadata assertions); no pre-existing guarantee was flipped or removed.

Minor findings

  1. Public, unauthenticated /api/hypershell/v1/metadata. The endpoint is now security: [] and added to auth-bypass-paths in both the development_oidc env and the kind/openshift overlays. That exposes version (release prefix + short Git SHA) and build_time to anonymous callers. This is a reasonable design for a version banner, but it is a deliberate information-disclosure decision (build identity can help correlate a deployment to known CVEs). Please confirm it is intended; if so, consider limiting the response to version only.

  2. Local dev build version drops the dirty-tree indicator. The previous Makefile logic appended -modified when the working tree was dirty; scripts/build-version.sh local now emits only dev-<shortsha>. During iterative swap-component/kind debugging, an image built from uncommitted changes now reports a clean-looking version, which can mislead. Consider re-adding a dirty marker for local mode.

  3. Obscure revision truncation in the Dockerfiles. ${VCS_REF%?????????????????????????????????} (33 ?) silently depends on VCS_REF being a full 40-char SHA; a non-40-char value (e.g. unknown) passes through unchanged. It is validated by check_image_build_policy.py, but a short comment explaining the "strip 33 to keep 7" intent would help future readers.

Cross-PR coordination

The following require maintainer sequencing or a design decision before merge:

  • #150 redesigns the same scripts/kind/build-images.sh build invocation, keeping the old --build-arg GIT_VERSION and the ${BUILD_DIR}/components/api-server build context. This PR changes the api-server build context to the repository root and rewrites components/api-server/Dockerfile to COPY components/api-server/go.mod .... The two designs are incompatible: whichever merges second must adopt this PR's repo-root context and BUILD_PREFIX/VCS_REF build args, or the api-server image will fail to build / lose its build identity. Decide a merge order and reconcile the build command.

  • #217 switches the OpenShift api-server to API_ENV=development_oidc in deploy/openshift/kustomization.yaml, while this PR edits the same overlay's --auth-bypass-paths patch (and the development_oidc env's own Flags()) to add /api/hypershell/v1/metadata. That creates two sources of truth for the OpenShift auth-bypass paths. Maintainers should decide which mechanism owns the bypass list and ensure the /metadata path survives so the console's unauthenticated version fetch works under whichever environment #217 selects.

  • #232 introduces a scripts/cluster/ driver abstraction (its own up.sh/swap.sh) over the kind scripts and separately restructures deploy/openshift/kustomization.yaml and the .github/workflows/e2e.yml change-detection block that this PR also modifies. Its OpenShift/registry build path must propagate this PR's new BUILD_PREFIX/VCS_REF build args and repo-root Docker build context (and the shared e2e detection / openshift-overlay edits must be merged coherently), or images built through that driver will not build or will lack build identity. Coordinate ownership of the build/swap tooling and the shared overlay/e2e edits.

Findings Summary (ordered by severity, highest first)

  1. [Minor] Unauthenticated /metadata exposes build version/build_time to anonymous callers - Security / API design (openapi.yaml L23, e_development_oidc.go, deploy overlays)
  2. [Minor] Local dev build version no longer marks a dirty working tree - Observability / Dev UX (scripts/build-version.sh L16-17)
  3. [Minor] Obscure ${VCS_REF%???...} truncation depends on a full 40-char SHA - Readability (components/*/Dockerfile)

Convention Checklist

Convention Result
No panic() in production code Pass
Errors wrapped / propagated (Go + Python policy scripts) Pass
No secrets in logs or responses Pass
Input validated (SemVer / SHA / build-version regex) Pass
Image references consistent across manifests Pass
OpenAPI client regenerated, not hand-edited Pass
Conventional commit / PR title Pass
Test Diff Scrutiny (no flipped assertions) Pass

Comment thread components/api-server/openapi/openapi.yaml
Comment thread scripts/build-version.sh
Comment thread components/api-server/Dockerfile
@jsell-rh

jsell-rh commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator Author

Amber review: comment

Amber review

Status: Complete

View the submitted review.

@jsell-rh jsell-rh left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Verdict

This PR adds a well-structured Release Please source-release process, a build-identity pipeline across the three images, and a public API metadata endpoint surfaced in the web console. The implementation is clean and test-backed; my findings are minor plus one cross-PR policy decision that maintainers should settle before merge.

Confidence: High on the structural review, Medium on a couple of the minor robustness notes.

Findings

[Minor] Public, unauthenticated metadata endpoint exposes build identity - Security
components/api-server/openapi/openapi.yaml:23 marks GET /metadata security: [], and the endpoint is added to the auth-bypass lists (e_development_oidc.go, deploy/kind + deploy/openshift overlays). The response now includes the image build version (which embeds the short git SHA) and is reachable by anonymous callers. This is a common and generally acceptable pattern (health/openapi are already public, and a build version is not a secret), but note the web console only reads it after authentication, so the anonymous exposure is broader than the consumer needs. Confirm this is intended; if so, no change required.

[Minor] ldflags inject version into a third-party module package - Maintainability
components/api-server/Makefile:18 and components/api-server/Dockerfile:30 now -X into github.com/openshift-online/rh-trex-ai/pkg/api.Version/.BuildTime rather than a HyperShell-owned symbol (the local pkg/api.Version/BuildTime vars were removed in api.go). This works and is covered by metadata_test.go, but it couples the build to an upstream symbol name; if rh-trex-ai renames or drops those vars, the -X silently no-ops and the binary ships an empty version with no build failure. Consider a build-time assertion or keeping the metadata test in a spot that runs in CI to catch upstream drift.

[Minor] Build-version regex duplicated across hand-maintained files - Config vs. Code
The same version pattern lives in components/web-console/bff/src/config.ts:39 and components/web-console/app/composition/browser-runtime-config.ts:25 (and a sibling form in scripts/build-version.sh). A future change to the versioning scheme (e.g., a new prefix) must be edited in several disconnected places or validation silently diverges. Consider centralizing the pattern.

[Minor] Obscure VCS_REF shortening - Readability/Robustness
components/api-server/Dockerfile:42 (and the control-plane/web-console Dockerfiles) shorten the SHA with ${VCS_REF%?????????????????????????????????} (33 ?). It is correct for a 40-char SHA and check_image_build_policy.py guards the count, but if VCS_REF is not exactly 40 hex chars (e.g., the unknown default) the label/ENV silently keep the full value. The comment helps; a brief note that this relies on a validated 40-char ref would make the intent clearer.

Notes

  • Test diffs are additive: the modified browser-runtime-config.test.ts, bff/test/config.test.ts, and openapi_embed_test.go hunks extend expectations to the new build/ServiceMetadata shape rather than flipping any prior guarantee. No removed contracts.
  • The api-server Dockerfile build-context change (components/api-server -> repo root) is consistent with the matching Tekton path-context: . update and the other two components.

Cross-PR coordination

This PR enforces a new pull-request-title contract: scripts/release_policy.py check-title (wired into .github/workflows/lint.yml as a required gate and documented in CLAUDE.md/AGENTS.md) requires the Conventional Commits type at the start of the title and mandates that any Jira key appear after the colon (feat(release): [HYPERSHELL-123] ...), explicitly forbidding a leading [HYPERSHELL-nnn]. Multiple in-flight PRs use the opposite, currently prevailing ordering (leading [HYPERSHELL-nnn], sometimes with no type: at all) - for example #235, #227, #232, and #214. Once this PR merges, those titles will fail the new lint gate and cannot merge until retitled. Maintainers need to decide which title format is canonical for the repo and, if this PR's rule stands, coordinate retitling of the affected open PRs (and align the historical [HYPERSHELL-nnn]-first convention). This is a shared-policy decision, not a file conflict.

Findings Summary (ordered by severity, highest first):

  1. [Minor] Public unauthenticated metadata endpoint exposes build identity to anonymous callers - Security (openapi.yaml L23)
  2. [Minor] Version ldflags inject into third-party rh-trex-ai/pkg/api symbol; upstream drift fails silently - Maintainability (Makefile L18, Dockerfile L30)
  3. [Minor] Build-version regex duplicated across hand-maintained files - Config vs. Code (config.ts L39, browser-runtime-config.ts L25)
  4. [Minor] Obscure 33-? VCS_REF shortening relies on an unvalidated 40-char ref in the Docker layer - Readability (Dockerfile L42)

Convention Checklist:

Convention Result
No panic() in production code Pass
Errors wrapped with fmt.Errorf context Pass (N/A - no new Go error paths)
No secrets in logs or responses Pass
Input validated Pass
Image references consistent across the stack Pass
OpenAPI client not manually edited Pass (regenerated; SDK spec SHA updated)
Test diff scrutiny (no silently removed guarantees) Pass
Conventional commit messages Pass

Comment thread components/api-server/openapi/openapi.yaml
Comment thread components/api-server/Makefile
Comment thread components/web-console/bff/src/config.ts
Comment thread components/api-server/Dockerfile
@jsell-rh

jsell-rh commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator Author

Amber review: comment

Amber review

Status: Complete

View the submitted review.

@jsell-rh jsell-rh left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Verdict

COMMENT - This is a well-structured, thoroughly tested change that introduces Release Please source releases, deterministic image build identities, and surfaces the API/console versions in the UI. I found no blockers; the notes below are minor, plus one cross-PR coordination item that maintainers should sequence before merge.

What I reviewed

  • Build identity flow: scripts/build-version.sh, the three Dockerfiles, root Makefile, components/api-server/Makefile, and the Kind build/swap scripts.
  • Release policy tooling: scripts/release_policy.py, scripts/check_image_build_policy.py, their unit tests, release-please-config.json, .release-please-manifest.json, VERSION, build-version.env, and the new/updated workflows.
  • API surface: openapi.yaml ServiceMetadata schema + embedded-spec test, generated OpenAPI model, pkg/api/api.go (removal of local Version/BuildTime), and x-sdk-exclude handling in scripts/sdk-generator/parser.go.
  • Web console: api-version adapter/hook, browser-runtime-config, BFF config.ts, user-menu.tsx, i18n messages, and their tests.

I re-ran the shipped Python policy suites and both policy checks locally: release_policy.py check-files, check_image_build_policy.py, and python3 -m unittest for the three test modules all pass. I confirmed no remaining references to the removed hypershell .../pkg/api.Version/.BuildTime symbols, so the ldflags retarget to rh-trex-ai/pkg/api does not break compilation.

Test Diff Scrutiny

The modified assertions in pre-existing tests (browser-runtime-config.test.ts, bff/test/config.test.ts, user-menu.test.tsx) are additive schema-shape updates (build: {} added alongside existing tracing). The fail-closed tracing guarantee is preserved (invalid/missing config still yields sampleRatio: 0), and new negative cases (invalid build version rejected, API-unavailable falls back to "unknown") were added rather than flipping an existing guarantee. No removed guarantees detected.

Findings

[Minor] Unauthenticated metadata endpoint discloses build identity - Security / Info disclosure
/api/hypershell/v1/metadata gains security: [] (components/api-server/openapi/openapi.yaml:23) and is added to auth-bypass-paths in both the dev OIDC env and the Kind/OpenShift kustomizations. This lets any anonymous caller read the API build version (short commit) and build_time. That is a deliberate choice so the BFF can proxy same-origin without a token, and the exposure (short SHA + timestamp) is low risk, but the console only reads it while authenticated - so please confirm the endpoint is intended to be reachable without auth rather than proxied with the caller's session. No secret values are exposed. Confidence: Medium.

[Minor] Build version string is a soft contract across many layers - Maintainability
The build-version grammar (dev-<7hex>[-modified] / v<semver>-<7hex>) is independently re-encoded as a regex in bff/src/config.ts and browser-runtime-config.ts, as a ${VCS_REF%...} (33-char trim) expansion in three Dockerfiles, as SHORT_REVISION_TRIM=33 in check_image_build_policy.py, and in build-version.sh. The image-build-policy check guards the Dockerfiles, but the TS regexes are separate copies. Consider a short comment cross-referencing the canonical definition so a future format change updates every copy. Confidence: High.

Convention Checklist

Convention Result
No panic() in production code Pass
Errors wrapped with fmt.Errorf context Pass (n/a - minimal new Go)
No secrets in logs or responses Pass
Input validated (VCS_REF / build version) Pass
OpenAPI client not manually edited Pass (generated model + x-sdk-exclude)
Image references consistent across the stack Pass
Conventional commit / PR title Pass
Config separate from code Pass

Findings Summary (ordered by severity, highest first)

  1. [Minor] Unauthenticated /metadata discloses build identity - Security (openapi.yaml L23)
  2. [Minor] Build-version grammar duplicated across layers - Maintainability

Cross-PR coordination

Two other open pull requests rewrite the same local image-build path with a build-arg contract that is incompatible with this PR, so maintainers must decide a merge order and reconcile the interface:

  • #150 rewrites scripts/kind/build-images.sh (and Makefile) to build from the working tree, but keeps the old --build-arg GIT_VERSION=... contract and the components/api-server build context. This PR removes GIT_VERSION, requires a valid 40-character VCS_REF build-arg (the Dockerfile builder now hard-fails without it), and moves the api-server build context to the repository root. Whichever merges second must adopt this PR's VCS_REF/BUILD_PREFIX/BUILD_SUFFIX build args and the new context, or local image builds break.
  • #232 introduces a new scripts/cluster/ framework whose component_spec()/push_component_image() builds all three images using the old contract (GIT_VERSION and BUILD_CONTEXT="components/api-server" for api-server; no build args for control-plane and web-console). Under this PR's Dockerfiles those builds fail because VCS_REF is required and the api-server context changed. The new OpenShift/cluster build path needs the same build-arg treatment this PR adds to the Kind scripts; maintainers should sequence the two and align on one build-identity interface.

Comment thread components/api-server/openapi/openapi.yaml
Comment thread components/web-console/bff/src/config.ts
@jsell-rh

jsell-rh commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator Author

Amber review: comment

Amber review

Status: Complete

View the submitted review.

@jsell-rh jsell-rh left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Verdict

This is a large but disciplined, spec-driven change (specs/platform/source-release.spec.md) that adds Release Please source releases, deterministic image build identity, and API/console version surfacing. The code is well-tested and internally consistent, with no blocking or critical defects; the main action items are cross-PR merge coordination and a small maintainability note.

I reviewed against CLAUDE.md, the security spec, and the control-plane conventions. The unauthenticated /metadata endpoint (security: [], added to auth-bypass-paths) is intentional and explicitly mandated by REL-09, and it exposes only non-secret build identity — not a finding. Test-diff scrutiny: the modified assertions in browser-runtime-config.test.ts, bff/test/config.test.ts, and bff/test/app.test.ts are additive (they thread the new build field through existing expectations) and preserve the prior fail-closed tracing guarantees; no contract was silently removed.

Highlights

  • Build identity is validated at multiple layers: VCS_REF is required and checked as a 40-char lowercase SHA in all three Dockerfiles, build-version.sh enforces the format, and check-image-build-policy / check-release-policy are wired into make check.
  • Removing the local api.Version/api.BuildTime vars in favor of the rh-trex-ai globals is clean, and metadata_test.go plus the linked_metadata-tagged test prove the ldflags actually land in the binary.
  • SDK exclusion via x-sdk-exclude is correctly enforced in the generator and covered by TestParseSpecExcludesSingletonMetadata.

Minor

  • The REL-07 build-version regex is duplicated verbatim in components/web-console/bff/src/config.ts and components/web-console/app/composition/browser-runtime-config.ts. This is defensible given the BFF/browser boundary, but the two copies must be kept in lockstep with the spec if the format ever changes. Consider a shared constant or a comment cross-referencing the sibling copy. (Confidence: High)

Cross-PR coordination

  • #232 — This PR replaces the GIT_VERSION build-arg contract with required, validated VCS_REF/BUILD_PREFIX/BUILD_SUFFIX args across all three Dockerfiles and adds check-image-build-policy to make check. #232 adds a new component build path that still passes --build-arg GIT_VERSION=.... Whichever merges second will break: #232's image builds will fail against the new Dockerfiles, and its build call sites must be updated to the new build-arg contract. Both PRs also edit deploy/openshift/kustomization.yaml's api-server env/auth block. Maintainers need to decide merge order and update the trailing PR to the new build-arg contract.
  • #150#150 independently rewrites scripts/kind/build-images.sh and the Makefile build variables (the same build path this PR restructures), keeping the old build_version/GIT_VERSION model. The two rewrites are incompatible; the trailing PR must be rebased onto the new VCS_REF/BUILD_PREFIX/BUILD_SUFFIX flow and its "working-tree by default" behavior reconciled with build-version.sh's dirty-state handling. A merge-order decision and integration are required.
  • #217#217 switches the OpenShift overlay to run the api-server under API_ENV=development_oidc and replaces the whole env array. This PR depends on auth-bypass configuration (both e_development_oidc.go and the overlay's --auth-bypass-paths) to keep the newly unauthenticated /metadata endpoint reachable. Coordinate so the metadata bypass survives the env switch and the two edits to the same overlay are reconciled.

Findings Summary (ordered by severity, highest first)

  1. [Minor] REL-07 build-version regex duplicated across the BFF and browser layers; keep the two copies in sync with the spec - Maintainability (bff config.ts L40, browser-runtime-config.ts L26)

Convention Checklist

Convention Result
No panic() in production code Pass
Errors wrapped with fmt.Errorf context Pass
No secrets in logs or responses Pass
Input validated (VCS_REF SHA, build-version format) Pass
Unauthenticated endpoint scope (build identity only) Pass
OpenAPI client not manually edited (regenerated) Pass
Reconcile / update-or-create patterns N/A
Image references consistent across manifests Pass
Conventional commit messages Pass
Test diff scrutiny (no silently removed guarantees) Pass


// REL-07 in specs/platform/source-release.spec.md defines this format.
const buildVersionPattern =
/^(?:dev-[0-9a-f]{7}(?:-modified)?|v(?:0|[1-9][0-9]*)\.(?:0|[1-9][0-9]*)\.(?:0|[1-9][0-9]*)-[0-9a-f]{7})$/u;

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

[Minor] Maintainability — This REL-07 build-version regex is a verbatim copy of the one in components/web-console/bff/src/config.ts (L40). The duplication is defensible across the BFF/browser boundary, but both must be updated together if the build-version format in specs/platform/source-release.spec.md changes. Consider a shared constant or a cross-reference comment so the two copies do not drift.

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.

1 participant