Skip to content

feat(release): publish manifest revision with image bundles - #297

Merged
jsell-rh merged 1 commit into
mainfrom
feat/release-bundle-manifests
Sep 16, 2026
Merged

jsell-rh merged 1 commit into
mainfrom
feat/release-bundle-manifests

Conversation

@jsell-rh

Copy link
Copy Markdown
Collaborator

Add manifests.git.url and manifests.git.revision to each release bundle so Kargo can promote shared manifests with the image set. Select the newest component source commit in the accepted Snapshot, verify that all component revisions are its ancestors, and check the three required manifest paths. Do not select the head of main, which can advance while a release waits.

Changes under deploy/ and changes to the publisher now trigger the API-server push build. This lets a manifest-only change produce a Snapshot and release bundle while retaining unchanged component images. The new manifest field is additive to the version 1 bundle format. The existing registry, credentials, and tenant final pipeline configuration are reused.

Merge and sync https://github.com/openshift-online/hypershell-gitops/pull/153 first. Then merge this PR. Its Tekton change starts the build that can produce the first bundle with a manifest revision. The shared refs affect all consumers; the companion promotion checks deployment health only for hyp1.

Validation: all 20 publisher tests passed, including the embedded pipeline, fixed revision selection after main advances, manifest-only changes, invalid or divergent source histories, missing manifests, and publication checks before registry access. Git fixture tests clear inherited Git environment variables so they also run safely from a commit hook. Repository policy checks and Tekton YAML parsing passed.

@coderabbitai

coderabbitai Bot commented Sep 16, 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: Advanced

Run ID: 734119c0-edbf-475c-b173-0bce384c4b60

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.

@amber-review-bot

amber-review-bot commented Sep 16, 2026 •

Copy link
Copy Markdown
Collaborator

Amber review: comment

Amber review

Status: Complete

View the submitted review.

@jsell-rh
jsell-rh added this pull request to the merge queue Sep 16, 2026

@amber-review-bot amber-review-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Verdict

This PR cleanly extends the v1 release bundle with an additive manifests.git field and picks a fixed Snapshot manifest revision instead of a moving main head, which is the right call for reproducible promotions. The publisher, pipeline embedding, and test coverage are solid; my one substantive concern is that the revision-selection loop is order-dependent on non-linear history, and there is a cross-PR merge-order coordination item on the shared Tekton trigger.

Findings

[Major] manifest_source selection is order-dependent on non-linear history - scripts/release_bundle.py:124-144 (and the embedded copy in pipelines/release-bundle/pipeline.yaml).

The loop iterates revisions in lexical SHA order and only compares each revision against the running selected. When the component revisions are totally ordered (a strictly linear main), this correctly returns the newest and is deterministic. But when the set contains a divergent pair that nonetheless has a common descendant in the set (e.g. {X, A, C} where X and A are siblings both merged before C), the outcome depends purely on the lexical order of the SHAs: some orderings promote selected to C and succeed, while others compare X against A first and raise "divergent histories." Same inputs, different result, decided by an essentially random SHA sort - for a publisher whose stated contract is reproducibility, that determinism gap is worth closing.

Practical impact is low today because the repo squashes to main (linear history, every commit totally ordered, so the divergent-pair case cannot arise). But the code and test_divergent_component_revisions_stop_selection deliberately handle merge/divergence, so non-linear history is treated as in-scope. Suggested deterministic fix: after computing selected, assert that every revision is an ancestor of selected (single well-defined rule), and fail otherwise - this makes success/failure independent of iteration order. Confidence: Medium.

[Minor] Non-linear-history behavior is asserted but its intent is not documented. The README and the # Divergent histories cannot form one manifest/image release unit. comment imply divergence should always fail, yet a divergent set with a unifying descendant can currently succeed (see above). A one-line note on the intended rule (newest commit that is a descendant of all component revisions; otherwise fail) would make the contract explicit. Confidence: Medium.

Notes (not blocking)

  • The manifest existence check uses git cat-file -e <rev>:<path>/kustomization.yaml against a --filter=blob:none clone. I verified this is fine: the check resolves the tree entry (trees are fetched), so a present path passes and a missing path fails as intended; the tests exercise this over a full clone, but the production partial-clone path behaves equivalently for path existence.
  • The CEL trigger now rebuilds the API-server image on any deploy/*** change to mint a Snapshot for manifest-only edits. That is intentional per the description; just noting it trades some build churn for manifest-only release coverage.

Cross-PR coordination

Another open pull request rewrites this same component's build pipeline and the same pipelinesascode.tekton.dev/on-cel-expression trigger in .tekton/hypershell-api-server-main-push.yaml: the "managed source releases" PR (#237). That PR is based on a pre-release-bundle revision of the file (it still sets dockerfile: Dockerfile / path-context: components/api-server and knows nothing of the release-bundle pipelineSpec), and it adds a different path token (VERSION) to the same CEL list that this PR extends with deploy/***, pipelines/release-bundle/***, and the two publisher scripts. Maintainers need to decide the merge order and ensure #237 rebases onto the merged release-bundle pipeline so that this PR's deploy/** and release-bundle triggers (and the release-bundle-aware pipeline body) are preserved rather than reverted by the stale rewrite. This is a plan/ordering decision, not a plain text merge conflict.

Previous concerns

There are no prior Amber findings in the review history to reconcile for this pull request.

Findings Summary (ordered by severity, highest first)

  1. [Major] Revision selection in manifest_source is order-dependent for non-linear history, giving non-deterministic success/failure - Correctness / Reproducibility (release_bundle.py L124-144)
  2. [Minor] Intended divergence rule is asserted in tests but not documented, and diverges from actual behavior - Docs / Spec Completeness (release_bundle.py L137, README)

Convention Checklist

Convention Result
No panic() / explicit errors (Python raises on failed subprocess) Pass
No secrets in logs or responses (auth.json 0o600, not logged) Pass
Input validated (digest/revision regex, namespace/name checks) Pass
Reproducible/deterministic publisher output Fail
Test diff scrutiny (no flipped/removed guarantees; changes additive) Pass
Embedded pipeline matches source (render/bootstrap test) Pass
Conventional commit message Pass

Comment thread scripts/release_bundle.py
run("git", "merge-base", "--is-ancestor", revision,
"refs/remotes/origin/main", cwd=source_directory)
selected = revisions[0]
for revision in revisions[1:]:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Major] Order-dependent revision selection.

This loop walks revisions in lexical SHA order and only compares each revision against the running selected. For a strictly linear history this correctly returns the newest commit deterministically. But for a divergent set that still has a common descendant in the set (e.g. {X, A, C} with X/A siblings both merged before C), the result depends on SHA order: some orderings promote selected to C and succeed, others compare X vs A first and raise "divergent histories." Same inputs, different outcome. Squash-merges keep main linear today so it is latent, but since divergence is explicitly handled/tested, consider a deterministic rule: after choosing selected, assert every revision is an ancestor of selected and fail otherwise.

Merged via the queue into main with commit 49cd038 Sep 16, 2026
25 checks passed
@jsell-rh
jsell-rh deleted the feat/release-bundle-manifests branch September 16, 2026 02:01
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.

2 participants