Skip to content

fix(release): develop to main#604

Open
bedatty wants to merge 11 commits into
mainfrom
develop
Open

fix(release): develop to main#604
bedatty wants to merge 11 commits into
mainfrom
develop

Conversation

@bedatty

@bedatty bedatty commented Jul 22, 2026

Copy link
Copy Markdown
Contributor
Lerian

GitHub Actions Shared Workflows


Description

Type of Change

  • feat: New workflow or new input/output/step in an existing workflow
  • fix: Bug fix in a workflow (incorrect behavior, broken step, wrong condition)
  • perf: Performance improvement (e.g. caching, parallelism, reduced steps)
  • refactor: Internal restructuring with no behavior change
  • docs: Documentation only (README, docs/, inline comments)
  • ci: Changes to self-CI (workflows under .github/workflows/ that run on this repo)
  • chore: Dependency bumps, config updates, maintenance
  • test: Adding or updating tests
  • BREAKING CHANGE: Callers must update their configuration after this PR

Breaking Changes

None.

Testing

  • YAML syntax validated locally
  • Triggered a real workflow run on a caller repository using @this-branch or the beta tag
  • Verified all existing inputs still work with default values
  • Confirmed no secrets or tokens are printed in logs
  • Checked that unrelated workflows are not affected

Caller repo / workflow run:

Related Issues

Closes #

gandalf-at-lerian and others added 9 commits July 20, 2026 15:34
Move the post-release backmerge (backmerge_source -> backmerge_target)
out of the publish_release matrix job into a dedicated 'backmerge' job
that depends on generate_changelog.

Previously the backmerge ran inline in publish_release, which completes
before the separate generate_changelog job commits CHANGELOG.md to main.
As a result main->develop was backmerged without the changelog, leaving
develop missing it. The backmerge-sync composite fetches origin/<source>
fresh, so ordering the job after the changelog commit guarantees the
changelog is carried into the target branch.

Also wires the new job into the notify job's failed-job reporting.
When on_existing_tag: skip skips build/push because the tag already
exists, the cosign steps were also skipped since they depended on
steps.build-push.outputs.digest and should_build != 'false'. A
transient cosign/Rekor failure on an already-pushed tag then had no
retry path short of a full rebuild or a brand new release.

Add a 'Resolve digest for existing tag' step that resolves the
digest from the existing registry tag via docker buildx imagetools
inspect when the build was skipped, and gate the cosign steps on
enable_cosign_sign alone, feeding
steps.build-push.outputs.digest || steps.existing-digest.outputs.digest.

Closes #559
Address CodeRabbit finding on PR #603: when both DockerHub and GHCR
are enabled, the existing-tag digest resolution always picked
DockerHub (or GHCR alone) and reused that single digest for both
registries' refs. If a tag existed in only one registry, this could
construct a nonexistent ref for the other registry using the wrong
digest.

Resolve each enabled registry's digest independently and only emit a
ref for a registry when its own digest was actually found.
…t digests

Address CodeRabbit findings on PR #603:

- Resolve digest for existing tag: distinguish a genuine 'tag not
  found' from an inspect/lookup failure (transient network error,
  auth issue) by emitting a ::warning:: with the actual error in the
  latter case, instead of silently treating both as 'no digest'.
  Kept fail-open (skip that registry, don't abort the job) to match
  this file's existing convention for the same tradeoff in the
  pre-flight tag-existence check just above.
- Report cosign signing status: stop collapsing to a single DIGEST
  value that discarded one registry's digest when both were
  resolved; REFS already lists each registry's fully-qualified ref
  with its own digest, so the redundant/lossy single-digest line was
  removed instead of duplicating that same registry-qualified data.
…rding

Address CodeRabbit findings on PR #603:

- Resolve digest for existing tag: percent-encode the captured
  'docker buildx imagetools inspect' output (%, CR, LF) before
  embedding it in a ::warning:: line, so it can't corrupt or spoof a
  workflow command annotation.
- Report cosign signing status: cosign-sign signs refs one by one, so
  a failure partway through the list doesn't mean every ref is
  unsigned. Reworded the summary to reflect that signing didn't
  complete for every ref instead of asserting all refs are unsigned.
@bedatty
bedatty requested a review from a team as a code owner July 22, 2026 14:37
@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 773002de-e1e0-4b6c-b9a3-dd26ccac409a

📥 Commits

Reviewing files that changed from the base of the PR and between c073d03 and 07c4d0d.

📒 Files selected for processing (1)
  • .github/workflows/build.yml
 __________________________________________________
< My OKRs are all about finding bugs in your code. >
 --------------------------------------------------
  \
   \   (\__/)
       (•ㅅ•)
       /   づ

Walkthrough

The build workflow retries cosign signing for existing tags by resolving registry digests. The release workflow moves post-release backmerge after changelog generation and reports backmerge failures through notifications.

Changes

Build signing recovery

Layer / File(s) Summary
Existing digest resolution
.github/workflows/build.yml, docs/build-workflow.md
Skipped builds inspect DockerHub and GHCR tags for digests, and documentation describes the signing retry behavior.
Cosign fallback and reporting
.github/workflows/build.yml
Cosign references use build or registry-resolved digests, signing runs when enabled, and failure reporting reflects per-reference results.

Release backmerge sequencing

Layer / File(s) Summary
Post-release backmerge job
.github/workflows/release.yml
Post-release backmerge runs in a dedicated job after changelog generation with publication, branch, and prerequisite-result gates.
Backmerge failure notification
.github/workflows/release.yml
The notify job waits for backmerge and includes backmerge failures in Slack messages.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related issues

Possibly related PRs

Suggested labels: build, security, changelog

Suggested reviewers: gandalf-at-lerian

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The template is mostly unfilled: the Description and Testing sections are empty and Related Issues is incomplete. Add a real summary of the workflow changes, complete the testing section, and replace the placeholder issue reference with an actual issue or remove it.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is specific and matches the release/workflow backmerge fix at a high level.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch develop

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

@lerian-studio lerian-studio added size/S PR changes 50–199 lines documentation Improvements or additions to documentation workflow Changes to one or more reusable workflow files labels Jul 22, 2026
@lerian-studio

lerian-studio commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

🔍 PR Validation Summary

✅ PR Mergeable — no blocking failures

Check Status Blocking
Source Branch ✅ success yes
PR Title ✅ success yes
PR Description ✅ success yes
PR Size ✅ success no
Auto Labels ✅ success no
PR Metadata ✅ success no

🔍 View workflow run

@lerian-studio

lerian-studio commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

🔍 Lint Analysis

Check Files Scanned Status
YAML Lint 2 file(s) ✅ success
Action Lint 2 file(s) ✅ success
Pinned Actions 2 file(s) ✅ success
Markdown Link Check 1 file(s) ✅ success
Spelling Check 3 file(s) ✅ success
Shell Check 2 file(s) ✅ success
README Check 2 file(s) ✅ success
Composite Schema no changes ⏭️ skipped
Deployment Matrix no changes ⏭️ skipped

🔍 View full scan logs

@lerian-studio

lerian-studio commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

🛡️ CodeQL Analysis Results

Languages analyzed: actions

Found 1 issue(s): 1 Medium

Severity Rule File Message
🟡 Medium actions/untrusted-checkout/medium .github/workflows/build.yml:300 Potential unsafe checkout of untrusted pull request on non-privileged workflow.

🔍 View full scan logs | 🛡️ Security tab

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Warning

CodeRabbit couldn't request changes on this pull request because it doesn't have sufficient GitHub permissions.

Please grant CodeRabbit Pull requests: Read and write permission and re-run the review.

👉 Steps to fix this

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/build.yml (1)

531-561: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Sign step can run with empty image-refs when all digest resolution fails.

The sign step's guard was relaxed to just inputs.enable_cosign_sign (line 570), but steps.cosign-refs.outputs.refs can be empty precisely in the new skip-mode path this PR adds: if docker buildx imagetools inspect fails or returns no digest for every enabled registry, DOCKERHUB_FINAL/GHCR_FINAL are both empty, REFS stays "", and the sign step still invokes the cosign-sign composite. That composite documents image-refs as a required input with no default, per its README: .Manifest: provides the manifest or manifest list confirms the digest-extraction approach is sound, but the composite's contract states image-refs | Newline-separated fully qualified image references to sign (e.g., docker.io/org/app@sha256:abc...) | Yes | — — no defined behavior for an empty value. Before this change, the sign step only ran after a successful build, so refs was always non-empty; now the exact "recover from a transient failure" scenario this PR targets can also be the one where the sign step fires with nothing to sign, likely hard-failing the job (continue_gitops_on_signing_failure defaults false) even though the earlier per-registry ::warning:: messages already explained why no digest was found.

Guard the sign step against an empty refs list; the existing per-registry warnings already cover user-facing diagnostics for that case.

🔧 Proposed fix
       - name: Sign container images with cosign
-        if: inputs.enable_cosign_sign
+        if: inputs.enable_cosign_sign && steps.cosign-refs.outputs.refs != ''
         id: cosign-sign

Also applies to: 569-578

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/build.yml around lines 531 - 561, Update the cosign sign
step guard near the cosign-refs output so it runs only when
inputs.enable_cosign_sign is enabled and steps.cosign-refs.outputs.refs is
non-empty. Preserve the existing signing behavior when valid image references
are produced, while skipping the composite action when digest resolution leaves
refs empty.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/build.yml:
- Around line 507-529: Extract the duplicated registry digest inspection in the
DockerHub and GHCR sections into a shared helper that accepts the image
reference and output key, then invoke it for both registries. In that helper,
capture stdout separately from stderr so only valid JSON reaches jq; retain the
existing warnings for missing digests and inspection failures, using
escape_for_warning for failure details.

In @.github/workflows/release.yml:
- Around line 500-507: Add a successful publish_release result requirement to
the backmerge job’s if condition alongside the existing publish_release_status
check. Keep the current always(), input, branch, and downstream-job conditions
unchanged so backmerge only runs after the entire release matrix succeeds.
- Line 508: Update the reusable-workflow job’s runs-on setting to use the
mandated blacksmith-4vcpu-ubuntu-2404 runner instead of the inputs.runner_type
expression, while leaving the rest of the job unchanged.

---

Outside diff comments:
In @.github/workflows/build.yml:
- Around line 531-561: Update the cosign sign step guard near the cosign-refs
output so it runs only when inputs.enable_cosign_sign is enabled and
steps.cosign-refs.outputs.refs is non-empty. Preserve the existing signing
behavior when valid image references are produced, while skipping the composite
action when digest resolution leaves refs empty.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 491d194b-daf9-45b4-a037-83334ead5022

📥 Commits

Reviewing files that changed from the base of the PR and between 081670f and 18d0f46.

📒 Files selected for processing (3)
  • .github/workflows/build.yml
  • .github/workflows/release.yml
  • docs/build-workflow.md

Comment thread .github/workflows/build.yml
Comment thread .github/workflows/release.yml
Comment thread .github/workflows/release.yml
Address CodeRabbit finding on PR #604: 'docker buildx imagetools
inspect ... 2>&1' merged stderr into the same variable later fed to
jq on the success path. Any stderr chatter on an otherwise-successful
call (deprecation notice, credential-helper output) would corrupt the
JSON and produce a false 'no digest' warning.

Extracted the duplicated DockerHub/GHCR inspect logic into a
resolve_digest() helper that captures stdout and stderr separately
(stderr to a temp file, consumed only for the warning message on
failure), so a successful call is never at risk of stderr noise
breaking the digest parse.
@bedatty
bedatty deployed to create_release July 22, 2026 15:09 — with GitHub Actions Active

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Warning

CodeRabbit couldn't request changes on this pull request because it doesn't have sufficient GitHub permissions.

Please grant CodeRabbit Pull requests: Read and write permission and re-run the review.

👉 Steps to fix this

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/build.yml:
- Around line 503-520: Update resolve_digest and its callers to propagate a
distinct lookup-failure status instead of treating failures as an empty digest.
Preserve empty-digest handling for genuinely absent tags, but ensure lines
554-563 detect any existing registry whose resolution failed, prevent partial
cosign success, and invoke the reporting/failure path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 62b03d2a-3e08-4dfc-b17f-e92887218e7d

📥 Commits

Reviewing files that changed from the base of the PR and between 18d0f46 and c073d03.

📒 Files selected for processing (1)
  • .github/workflows/build.yml

Comment thread .github/workflows/build.yml
Address CodeRabbit finding on PR #604: when on_existing_tag: skip
retries signing across multiple registries, a genuine registry
lookup failure (as opposed to a confirmed-absent tag) collapsed to
an empty digest just like a normal 'not found', so that registry
was silently excluded from signing. If the OTHER enabled registry
resolved fine, cosign-sign succeeded for it, and the failure report
step (gated only on cosign-sign's own outcome) never ran -- leaving
one registry's already-published image unsigned with no visible
failure signal beyond a log warning.

resolve_digest() now also reports whether the lookup itself failed
(vs. the tag being genuinely absent). Build cosign image references
aggregates that into a has_lookup_error output, and Report cosign
signing status now fires on either cosign-sign failing OR a lookup
error, so a partially-unverified multi-registry signing run is
always visibly reported instead of looking like a clean success.
@bedatty
bedatty requested a deployment to create_release July 22, 2026 16:29 — with GitHub Actions In progress
@lerian-studio lerian-studio added size/M PR changes 200–499 lines and removed size/S PR changes 50–199 lines labels Jul 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/M PR changes 200–499 lines workflow Changes to one or more reusable workflow files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants