Skip to content

refactor: redesign release notes layout#434

Merged
Aureliolo merged 7 commits intomainfrom
fix/release-notes-layout
Mar 15, 2026
Merged

refactor: redesign release notes layout#434
Aureliolo merged 7 commits intomainfrom
fix/release-notes-layout

Conversation

@Aureliolo
Copy link
Copy Markdown
Owner

Summary

Redesigns the GitHub Release notes layout for better UX and consistency.

Before

## Changelog
## Installation (CLI — raw.githubusercontent.com URLs, hardcoded version)
### Checksums
### Provenance Verification (SLSA Level 3)  ← duplicate heading
## Container Images (digests, cosign, provenance inline)
### Provenance Verification (SLSA Level 3)  ← duplicate heading

After

## Changelog
---
## CLI Installation (synthorg.io/get/ URLs, pin-to-version as secondary)
   → Getting Started link
---
## Container Images (pull table + digests only)
---
## Verification (combined, assembled by finalize-release)
### CLI Checksums (SHA-256)
### Container Image Signatures (cosign)
### Provenance (SLSA Level 3) — CLI + container commands combined

Changes

  • CLI first, containers second — CLI install is the primary action most users want
  • Use synthorg.io/get/ URLs — shorter, matches getting started page, always serves latest script
  • "Install latest" as primary — no more hardcoded version in the main command. Pin-to-version shown as a secondary note
  • Getting Started guide link — directs new users to synthorg.io/get/
  • Combined Verification section — finalize-release extracts hidden data (HTML comments) from both CLI and Docker sections and assembles one clean Verification block at the end
  • No duplicate headings — SLSA provenance for CLI + containers in one block
  • Fix \$ rendering — PowerShell $env: no longer shows a visible backslash

How it works

  1. CLI workflow embeds checksums + SLSA commands in <!-- CLI_VERIFICATION_DATA --> HTML comments (invisible in rendered markdown)
  2. Docker workflow embeds cosign + SLSA commands in <!-- CONTAINER_VERIFICATION_DATA --> HTML comments
  3. Finalize-release extracts both, strips the markers, and appends a visible ## Verification section before publishing

Test plan

  • Verify next release has correct layout (CLI Installation → Container Images → Verification)
  • Verify checksums table renders correctly in Verification section
  • Verify cosign + SLSA commands are combined in one block
  • Verify no duplicate headings
  • Verify synthorg.io/get/ URLs work in install commands

- CLI Installation section first (above Container Images)
- Use synthorg.io/get/ URLs instead of raw.githubusercontent.com
- Show "install latest" as primary, pin-to-version as secondary
- Link to Getting Started guide
- Fix \$ escaping in PowerShell command
- Verification data embedded as HTML comments in each section
- Finalize-release extracts and assembles combined Verification
  section at end (checksums + cosign + SLSA provenance combined)
- No more duplicate "Provenance Verification" headings
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Note

Gemini is unable to generate a summary for this pull request due to the file types involved not being currently supported.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 15, 2026

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 15, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Reworks release-note generation: CLI and Container workflows embed hidden verification blocks (CLI_VERIFICATION_DATA / CONTAINER_VERIFICATION_DATA), CLI install URLs now point to synthorg.io, and finalize-release.yml extracts, merges, strips, and appends a unified VERIFICATION section before publishing the release.

Changes

Cohort / File(s) Summary
CLI Installation & Verification
.github/workflows/cli.yml
Renamed release-note step; replaced INSTALL_NOTES with CLI_SECTION; introduced hidden CLI_VERIFICATION_DATA block (provenance moved there); switched per-platform install commands to https://synthorg.io/get/install.{sh,ps1}; rewrote idempotent-strip logic to remove the CLI section with awk; assemble and write notes via temp file and gh release edit.
Container Verification Block
.github/workflows/docker.yml
Converted narrative provenance/verification into a CONTAINER_VERIFICATION_DATA marker wrapping verification commands; replaced sed removal with awk to delete only the Container Images block; minor comment/formatting adjustments.
Release Finalization & Assembly
.github/workflows/finalize-release.yml
New multi-stage assembly: extract CLI_VERIFICATION_DATA and CONTAINER_VERIFICATION_DATA from body, parse checksums/signatures/SLSA provenance (emit warnings if missing), build unified VERIFICATION block, strip old markers, update release notes via temp file and gh release edit, then attempt publish with TOCTOU handling and fail-on-update-error when verification data exists.

Sequence Diagram(s)

sequenceDiagram
    participant WF_CLI as WF: cli.yml
    participant WF_DOCKER as WF: docker.yml
    participant WF_FINAL as WF: finalize-release.yml
    participant GH as GitHub Releases
    participant ASSETS as Release Assets

    WF_CLI->>ASSETS: upload CLI artifacts
    WF_CLI->>GH: append CLI_VERIFICATION_DATA to draft body
    WF_DOCKER->>ASSETS: upload container artifacts
    WF_DOCKER->>GH: append CONTAINER_VERIFICATION_DATA to draft body
    WF_FINAL->>GH: read draft release body (extract verification blocks)
    WF_FINAL->>WF_FINAL: parse and merge CLI checksums, container signatures, SLSA provenance
    WF_FINAL->>GH: gh release edit with assembled VERIFICATION (temp file)
    WF_FINAL->>GH: attempt to publish draft (handle concurrent publish / TOCTOU)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'refactor: redesign release notes layout' directly and clearly summarizes the main change: restructuring the GitHub Release notes layout for better UX and consistency.
Description check ✅ Passed The description provides comprehensive context on the release notes redesign, including before/after structure, specific changes, implementation details, and a test plan—all directly related to the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/release-notes-layout
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch fix/release-notes-layout
📝 Coding Plan
  • Generate coding plan for human review comments

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

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/finalize-release.yml:
- Around line 101-109: When extracting container verification blocks from BODY
in the section that assigns CONTAINER_COSIGN and CONTAINER_SLSA, add validation
after those assignments to detect empty results despite the marker being
present; if CONTAINER_COSIGN or CONTAINER_SLSA is empty, emit a GitHub Actions
warning (e.g., echo "::warning::...") identifying which extraction failed and
the presence of the CONTAINER_VERIFICATION_DATA marker so maintainers are
notified and the release step can be inspected.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4738e046-9d41-4d43-b637-73f1f44c7888

📥 Commits

Reviewing files that changed from the base of the PR and between b45533c and 064bbe0.

📒 Files selected for processing (3)
  • .github/workflows/cli.yml
  • .github/workflows/docker.yml
  • .github/workflows/finalize-release.yml
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Build Web
  • GitHub Check: Build Backend
  • GitHub Check: Greptile Review
  • GitHub Check: Analyze (python)
🔇 Additional comments (4)
.github/workflows/docker.yml (1)

362-377: LGTM!

The verification data is correctly wrapped in HTML comment markers for extraction by finalize-release.yml. The structure with two distinct bash code blocks (cosign commands first, SLSA attestation second) aligns with the extraction logic in the finalize workflow.

.github/workflows/cli.yml (1)

327-368: LGTM!

The restructured CLI section correctly:

  • Uses the new synthorg.io/get/ distribution URLs
  • Embeds verification data (checksums + SLSA attestation) in HTML comments for extraction by finalize-release.yml
  • Maintains idempotency by stripping existing ## CLI Installation section before appending

The checksum table format with pipe-delimited rows aligns with the grep -E '^\|' extraction pattern in finalize-release.

.github/workflows/finalize-release.yml (2)

124-143: LGTM!

The SLSA block merging logic correctly combines CLI and container attestation commands into a single code block when both exist. The sed '1d;$d' strips the code fence markers before recombining, producing a clean unified block.


145-158: LGTM!

The cleanup logic correctly strips:

  1. Both HTML comment verification data blocks
  2. Any existing ## Verification section (ensuring idempotency)

Using a temp file for --notes-file is the right approach to avoid shell quoting issues with the multi-line content.

@greptile-apps
Copy link
Copy Markdown

greptile-apps bot commented Mar 15, 2026

Greptile Summary

This PR redesigns the GitHub Release notes layout by moving verification data (checksums, cosign, SLSA) into hidden HTML comments that finalize-release extracts and assembles into a single, clean ## Verification section — eliminating duplicate headings and producing a more user-friendly layout. The approach is well-architected and correctly addresses several issues from prior review threads (paragraph-mode awk, sed-to-EOF deletion, SLSA gate condition, printf vs echo).

Key changes:

  • cli.yml: Switches install URLs to synthorg.io/get/, embeds checksums + SLSA commands in <!-- CLI_VERIFICATION_DATA -->, and uses a buffered awk for idempotent cleanup. The awk has a logic bug: because CLI_SECTION places a blank line between --- and ## CLI Installation, the buffer is flushed by the blank line on a re-run, leaking the old --- separator into CLEANED_BODY and producing a duplicate divider after every subsequent run.
  • docker.yml: Wraps cosign + SLSA commands in <!-- CONTAINER_VERIFICATION_DATA --> and switches idempotency cleanup to section-scoped awk. The IMAGES block is missing a leading --- separator, making the Container Images section visually inconsistent with the CLI and Verification sections.
  • finalize-release.yml: New extraction + assembly logic uses the <!-- FINALIZE_VERIFICATION --> sentinel (safer anchor), line-by-line awk for multi-block code extraction, and a proper error gate before publishing. The Replace the filename with any archive from this release. prose note embedded in CLI_VERIFICATION_DATA is silently dropped because the extraction only captures ^\| rows and fenced code blocks.

Confidence Score: 3/5

  • Safe to merge with the awk idempotency bug fixed; cosmetic issues can be addressed in a follow-up.
  • The finalize-release assembly logic is well-thought-out and correctly addresses the major issues from prior review rounds. However, the awk separator-buffering bug in cli.yml will cause a double --- divider to accumulate in the release notes on every re-run of the CLI workflow, which is a functional regression from the previous sed approach. The missing --- before Container Images and the dropped prose note are minor but worth fixing for consistency with the stated design.
  • .github/workflows/cli.yml — the idempotency awk needs to buffer the blank line that follows --- in addition to the --- itself.

Important Files Changed

Filename Overview
.github/workflows/cli.yml Redesigns CLI release notes section: switches to synthorg.io/get/ URLs, embeds checksums + SLSA data in an HTML comment for finalize-release to extract. The idempotency awk has a logic bug where the --- separator leaks on re-runs due to an intervening blank line not being buffered alongside the separator.
.github/workflows/docker.yml Moves cosign + SLSA commands into a <!-- CONTAINER_VERIFICATION_DATA --> HTML comment; switches idempotency cleanup from sed to awk to avoid deleting to EOF. Missing a --- separator at the top of the IMAGES block, inconsistent with the other sections and the PR description's layout spec.
.github/workflows/finalize-release.yml New assembly logic extracts hidden CLI and container verification data from HTML comments and combines them into a single visible ## Verification section before publishing. Uses a <!-- FINALIZE_VERIFICATION --> sentinel (safer than the previous ## Verification anchor) and line-by-line awk for the cosign block to handle the blank line between the two cosign verify commands. Addresses most issues flagged in prior review threads.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: .github/workflows/cli.yml
Line: 370-376

Comment:
**`---` separator leaks and duplicates on idempotent re-run**

The awk only buffers a `---` line and flushes it the moment any non-`## CLI Installation` line follows. Because `CLI_SECTION` puts a blank line between `---` and `## CLI Installation`:

```
---
          ← blank line
## CLI Installation
```

the sequence on a re-run is:
1. `---` → buffered
2. blank line → **buffer is flushed** (`---` is printed); blank line is also printed (`!skip` is 1 at this point)
3. `## CLI Installation``skip=1`, but `buf` was already cleared in step 2

`CLEANED_BODY` therefore ends with a stray `---` + blank line, and `CLI_SECTION` is then appended starting with its own `---`, resulting in a double `---` separator after every subsequent run.

To fix this, the blank line between `---` and the heading must also be buffered so the buffer is only released when it is confirmed not to precede the `## CLI Installation` heading:

```bash
CLEANED_BODY="$(printf '%s' "$EXISTING_BODY" | awk '
  /^---$/ { buf=$0; sep=""; next }
  /^$/ && buf != "" { sep=$0; next }
  /^## CLI Installation$/ { buf=""; sep=""; skip=1; next }
  { if(buf!="") { print buf; if(sep!="") print sep }; buf=""; sep="" }
  /^## / { skip=0 }
  !skip
')"
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: .github/workflows/cli.yml
Line: 359-363

Comment:
**`Replace the filename...` instruction silently dropped from Verification section**

The line `Replace the filename with any archive from this release.` appears after the closing ` ``` ` fence, still inside `<!-- CLI_VERIFICATION_DATA … -->`. In `finalize-release.yml` the extraction for `CLI_SLSA` is:

```bash
sed -n '/^```bash$/,/^```$/p'
```

This range stops at the closing fence, so everything after it — including this prose note — is discarded. The published Verification section will only show the raw `gh attestation verify` command with no guidance about substituting other filenames.

If this instruction should survive to the release notes, either move it inside the code fence as a comment, or add it explicitly as a static line in the `finalize-release.yml` `### Provenance` block next to the `Verify with the GitHub CLI` text.

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: .github/workflows/docker.yml
Line: 349-351

Comment:
**Missing `---` separator before `## Container Images`**

The PR description's "After" layout shows a `---` divider before every major section:

```
## CLI Installation
---
## Container Images
---
## Verification
```

`finalize-release.yml` adds `---` before `## Verification`, and `cli.yml` adds `---` before `## CLI Installation`, but the `IMAGES` block in `docker.yml` starts directly with `## Container Images` — no leading `---`. The rendered release notes will be missing the divider between the CLI and Container sections.

Adding a leading `---` to the `IMAGES` block (and updating the corresponding awk cleanup to buffer it like cli.yml does) would make the layout match the spec.

How can I resolve this? If you propose a fix, please make it concise.

Last reviewed commit: 8d24e02

…ings)

- finalize-release: replace broken awk RS= paragraph mode with line-by-line
  awk for extracting container code blocks (infra-reviewer, Greptile)
- finalize-release: add ::warning when extraction produces empty result (CodeRabbit)
- finalize-release: wrap body edit in error handling for concurrent race (Greptile)
- cli.yml, docker.yml: bounded section deletion with awk instead of sed to
  EOF — prevents destroying each other's sections on re-runs (infra-reviewer)
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/finalize-release.yml:
- Around line 170-180: The current flow may publish the release even if the
prior gh release edit "$TAG" --notes-file "$tmpfile" failed, causing an
immutable release missing Verification info; modify the script to track the
success of that edit (e.g., set a boolean/exit_on_failure flag when the gh
release edit --notes-file "$tmpfile" succeeds) and only proceed to the publish
step gh release edit "$TAG" --repo "$GITHUB_REPOSITORY" --draft=false if the
edit succeeded or verification is not expected; if verification data was
expected and the edit failed, exit non‑zero instead of emitting a warning to
avoid publishing an incomplete release.
- Around line 92-99: When the CLI_VERIFICATION_DATA marker is present in BODY
but extraction yields empty strings, add validation warnings: after computing
CLI_CHECKSUMS and CLI_SLSA inside the if that tests echo "$BODY" | grep -q
"CLI_VERIFICATION_DATA", check each variable with [ -z "$CLI_CHECKSUMS" ] and [
-z "$CLI_SLSA" ] and emit echo "::warning::..." messages indicating the
checksums table or SLSA commands could not be extracted; place these checks
immediately before the closing fi so they mirror the existing container
extraction warnings and reference the CLI_CHECKSUMS and CLI_SLSA variables and
the CLI_VERIFICATION_DATA marker.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 463e7886-2603-4d83-9a85-e5868fa91fd2

📥 Commits

Reviewing files that changed from the base of the PR and between 064bbe0 and aef6e78.

📒 Files selected for processing (3)
  • .github/workflows/cli.yml
  • .github/workflows/docker.yml
  • .github/workflows/finalize-release.yml
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Build Backend
  • GitHub Check: Greptile Review
  • GitHub Check: Analyze (python)
🔇 Additional comments (9)
.github/workflows/finalize-release.yml (3)

146-148: SLSA block merging logic is sound.

The approach of stripping fence markers with sed '1d;$d' and reconstructing a combined block handles the merge correctly. The blank line between CLI and container commands improves readability.


159-175: Robust body cleanup and update implementation.

The approach of:

  1. Stripping both HTML comment markers via separate sed invocations
  2. Removing any prior ## Verification section to EOF
  3. Writing to a tmpfile to avoid shell escaping issues
  4. Graceful warning on edit failure (concurrent race handling)

is well-designed. The tmpfile pattern is the correct approach for complex multi-line content.


101-123: Container verification extraction with validation - well implemented.

The line-by-line awk approach (replacing RS= paragraph mode) correctly handles blank lines within code blocks. The added warnings at lines 117-122 address the previous review feedback for detecting extraction failures.

.github/workflows/docker.yml (2)

362-377: CONTAINER_VERIFICATION_DATA marker structure is correct.

The two-block structure (cosign verification followed by SLSA attestation) aligns with the extraction logic in finalize-release.yml that expects the first ````bash` block to be cosign and the second to be SLSA.


385-388: Bounded awk deletion is a robust improvement.

The awk pattern correctly implements section-specific deletion that stops at the next ## heading, preventing accidental deletion of subsequent sections. This addresses the commit message's goal of "bounded section deletion."

.github/workflows/cli.yml (4)

327-363: CLI_SECTION structure aligns with finalize-release extraction.

The structure includes:

  • User-visible installation instructions (will remain in final notes)
  • Hidden CLI_VERIFICATION_DATA marker containing:
    • Checksums table (extracted via grep -E '^\|')
    • SLSA command block (extracted via sed -n '/^```bash$/,/^```$/p')

This correctly interfaces with the extraction logic in finalize-release.yml.


365-369: Consistent bounded awk deletion pattern.

The cleanup logic mirrors the approach in docker.yml, using awk to delete only the CLI Installation section up to the next ## heading. The use of printf '%s' preserves content without adding trailing newlines.


371-374: Tmpfile pattern for safe content writing.

The approach of writing to a tmpfile and using --notes-file avoids shell escaping issues with complex markdown content. The cleanup with rm -f is correctly placed.


336-341: synthorg.io distribution URLs are operational and accessible.

Both installation endpoints are serving content with correct types: install.sh returns application/x-sh and install.ps1 returns appropriate content. No issues detected.

- Include CLI_SLSA and CONTAINER_SLSA in gate so provenance is
  published even when checksums/cosign are empty
- Use <!-- FINALIZE_VERIFICATION --> sentinel instead of ## Verification
  heading for idempotent strip (avoids collision with changelog headings)
- Add CLI extraction warnings (mirrors container block)
- Gate publish on successful body edit when verification data expected
- finalize-release: use printf + sed '/^```$/d' to strip fences
  (echo adds trailing newline that makes sed '$d' miss the fence)
- finalize-release: remove dead EDIT_OK variable
- cli.yml: buffer preceding --- in awk so separator doesn't accumulate
  and reorder sections on re-runs
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/finalize-release.yml:
- Around line 165-172: The cleanup currently unconditionally strips existing
verification sections from BODY and then appends VERIFICATION, which can wipe
out the last copy if VERIFICATION is empty; change the logic so you only remove
a matching verification block when you have a replacement: check if VERIFICATION
is non-empty before running the sed deletions that remove <!--
CLI_VERIFICATION_DATA ... -->, <!-- CONTAINER_VERIFICATION_DATA ... --> and <!--
FINALIZE_VERIFICATION --> and only append VERIFICATION when it contains content;
if VERIFICATION is empty, leave BODY untouched (do not run the CLEANED sed
pipeline and do not overwrite FINAL).
- Around line 94-95: The shell conditional using a pipeline (echo "$BODY" | grep
-q "PATTERN") can produce SIGPIPE (exit 141) under set -euo pipefail; replace
those piped greps with here-strings to avoid spawning/closing an intermediate
echo process — e.g. change occurrences like if echo "$BODY" | grep -q
"CLI_VERIFICATION_DATA"; then to if grep -q "CLI_VERIFICATION_DATA" <<<"$BODY";
then and likewise change the CONTAINER check (grep -q
"CONTAINER_VERIFICATION_DATA" <<<"$BODY") and any other similar piped grep
checks so variables BODY, CLI_CHECKSUMS and CONTAINER_INNER detection logic use
here-strings instead of echo | grep.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: e01de222-1d65-49ca-b1e7-e8767d54dcd1

📥 Commits

Reviewing files that changed from the base of the PR and between aef6e78 and 0da2ba8.

📒 Files selected for processing (1)
  • .github/workflows/finalize-release.yml
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Build Web
  • GitHub Check: Build Backend
  • GitHub Check: Greptile Review
  • GitHub Check: Analyze (python)

- Replace echo | grep/sed pipelines with here-strings to avoid
  SIGPIPE (exit 141) under set -euo pipefail
- Only strip and re-append verification section when VERIFICATION
  is non-empty — prevents destroying existing content with no replacement
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

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/cli.yml (1)

377-380: ⚠️ Potential issue | 🟡 Minor

Missing cleanup on gh release edit failure.

If gh release edit fails, the script will exit (due to set -euo pipefail) without removing the temp file. Consider using a trap or conditional cleanup:

🔧 Proposed fix
           tmpfile="$(mktemp)"
+          trap 'rm -f "$tmpfile"' EXIT
           printf '%s' "$FULL_BODY" > "$tmpfile"
           gh release edit "$TAG" --repo "$GITHUB_REPOSITORY" --notes-file "$tmpfile"
-          rm -f "$tmpfile"

This is a minor issue since the temp file in /tmp would be cleaned up eventually, but using a trap is cleaner.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/cli.yml around lines 377 - 380, The tmp file created as
tmpfile with mktemp isn't guaranteed to be removed if gh release edit "$TAG"
fails; update the script to ensure cleanup by installing a trap that removes
"$tmpfile" on EXIT (or ERR) before creating tmpfile, or run gh release edit in a
conditional block that removes "$tmpfile" in both success and failure paths;
reference the tmpfile variable and the gh release edit "$TAG" invocation when
adding the trap/cleanup to guarantee removal even if the command fails.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/cli.yml:
- Around line 358-360: Add a short explanatory line after the example artifact
verification command (the code block containing "gh attestation verify
synthorg_linux_amd64.tar.gz -R Aureliolo/synthorg") stating that the command is
generic and works for any archive/artifact by replacing the filename (e.g.,
synthorg_linux_amd64.tar.gz) with the desired artifact name; update the SLSA
verification block to include this note so readers know the example applies to
all archives.
- Around line 344-346: The instruction uses bash-style syntax `set
SYNTHORG_VERSION=${TAG}` which can confuse Windows/PowerShell users; update the
text around the SYNTHORG_VERSION mention (the line containing
`SYNTHORG_VERSION=${TAG}`) to either provide platform-specific examples (bash:
export SYNTHORG_VERSION=${TAG} · PowerShell: $env:SYNTHORG_VERSION = "<TAG>" ·
cmd: set SYNTHORG_VERSION=<TAG>) or simplify to a neutral statement like "Set
the SYNTHORG_VERSION environment variable to the desired tag (e.g. TAG)" so
readers on any OS know what to set without mistaken syntax.

In @.github/workflows/finalize-release.yml:
- Around line 113-122: The awk extraction uses an echo pipe which can raise
SIGPIPE when awk exits early; update the two assignments CONTAINER_COSIGN and
CONTAINER_SLSA to feed the variable via a here-string (use <<<
"$CONTAINER_INNER") into the awk script instead of echo | awk, keeping the same
awk program bodies and retaining the trailing || true for compatibility.

---

Outside diff comments:
In @.github/workflows/cli.yml:
- Around line 377-380: The tmp file created as tmpfile with mktemp isn't
guaranteed to be removed if gh release edit "$TAG" fails; update the script to
ensure cleanup by installing a trap that removes "$tmpfile" on EXIT (or ERR)
before creating tmpfile, or run gh release edit in a conditional block that
removes "$tmpfile" in both success and failure paths; reference the tmpfile
variable and the gh release edit "$TAG" invocation when adding the trap/cleanup
to guarantee removal even if the command fails.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: b8888573-6613-4890-bdff-d0b0b86db7ff

📥 Commits

Reviewing files that changed from the base of the PR and between 0da2ba8 and e5f9b0a.

📒 Files selected for processing (2)
  • .github/workflows/cli.yml
  • .github/workflows/finalize-release.yml
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Build Backend
  • GitHub Check: Build Web
  • GitHub Check: Greptile Review
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2026-03-15T01:53:24.085Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T01:53:24.085Z
Learning: When review agents find valid issues (including pre-existing issues in surrounding code, suggestions, and findings adjacent to the PR's changes), fix them all. No deferring, no 'out of scope' skipping.

Applied to files:

  • .github/workflows/finalize-release.yml
🔇 Additional comments (5)
.github/workflows/finalize-release.yml (4)

87-105: LGTM! CLI verification extraction with proper SIGPIPE handling.

The use of here-strings (<<< "$BODY") correctly avoids the pipefail/SIGPIPE issue previously identified. Validation warnings for empty extraction results are appropriately in place.


150-154: Edge case: merging assumes both SLSA blocks are well-formed.

The merge logic strips the opening \``bashline from both blocks and removes any```` lines. If CLI_SLSA or CONTAINER_SLSA extraction produced malformed output (e.g., missing fences), the merge could produce invalid markdown.

Given that the extraction patterns (sed -n '/^```bash$/,/^```$/p') should always produce well-formed blocks when they match, this is low risk but worth noting. The validation warnings earlier help catch extraction failures.


168-191: LGTM! Proper conditional handling prevents data loss.

The logic correctly:

  1. Only strips and replaces when there's new verification data
  2. Fails fast if verification data would be lost on update failure
  3. Cleans up temp file in all paths

193-207: LGTM! TOCTOU race condition is handled correctly.

The re-check after a failed publish correctly distinguishes between a concurrent successful publish and an actual failure.

.github/workflows/cli.yml (1)

368-374: LGTM! The awk idempotent stripping logic is well-designed.

The buffering approach correctly handles:

  • Removing the --- separator only when followed by ## CLI Installation
  • Stripping all content from ## CLI Installation to the next ## heading
  • Preserving all other content on re-runs

… here-strings

- cli.yml: platform-specific SYNTHORG_VERSION examples (bash + PowerShell)
- cli.yml: note that SLSA verify command works for any archive
- cli.yml: trap EXIT for tmpfile cleanup on failure
- finalize-release.yml: here-strings for awk (SIGPIPE safety)
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/cli.yml:
- Around line 344-347: In the unquoted heredoc started with <<NOTES the
PowerShell example currently uses an extra backslash sequence
(\\\$env:SYNTHORG_VERSION='${TAG}') which renders a visible backslash; change
that sequence to a single backslash (\$env:SYNTHORG_VERSION='${TAG}') so the
rendered output shows $env:SYNTHORG_VERSION without a preceding backslash;
update the text inside the <<NOTES heredoc accordingly.

In @.github/workflows/finalize-release.yml:
- Around line 178-191: The workflow currently manually removes the temporary
file via rm -f "$tmpfile" in success and failure branches (tmpfile created with
tmpfile="$(mktemp)" and used for gh release edit "$TAG" --notes-file
"$tmpfile"), which is fragile; add a shell EXIT trap immediately after creating
tmpfile to ensure cleanup on any exit (success, failure, or interrupt) and then
remove the explicit rm -f "$tmpfile" calls from the branches so the trap is the
single source of cleanup; ensure the trap references the same tmpfile variable
and is set before calling gh release edit and before any early exits that depend
on VERIFICATION.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4d3cbf75-c4b7-46c2-8bb2-54422ee47d25

📥 Commits

Reviewing files that changed from the base of the PR and between e5f9b0a and dbffff0.

📒 Files selected for processing (2)
  • .github/workflows/cli.yml
  • .github/workflows/finalize-release.yml
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Build Backend
  • GitHub Check: Build Web
  • GitHub Check: Greptile Review
  • GitHub Check: Analyze (python)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2026-03-15T01:53:24.085Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T01:53:24.085Z
Learning: When review agents find valid issues (including pre-existing issues in surrounding code, suggestions, and findings adjacent to the PR's changes), fix them all. No deferring, no 'out of scope' skipping.

Applied to files:

  • .github/workflows/finalize-release.yml
🔇 Additional comments (6)
.github/workflows/cli.yml (2)

367-376: LGTM!

The awk logic correctly buffers separator lines and strips the CLI Installation section along with its preceding ---, preventing separator accumulation on re-runs.


379-382: LGTM!

The EXIT trap ensures the tmpfile is cleaned up on any exit path, including failures. This is a robust improvement.

.github/workflows/finalize-release.yml (4)

94-105: LGTM!

The here-string approach (<<< "$BODY") avoids the SIGPIPE issue with echo | grep -q under pipefail. Validation warnings for empty extractions help diagnose malformed release bodies.


144-162: LGTM!

The SLSA block merging logic correctly strips markdown fences from both CLI and container blocks, then combines them into a single unified code block. The conditional structure handles all combinations (CLI-only, container-only, both).


165-176: LGTM!

The guard correctly preserves the existing body when no verification data is extracted, preventing the scenario where a rerun strips existing verification without replacement.


180-190: LGTM!

The error handling correctly distinguishes between critical failures (verification data would be lost) and non-critical ones (no verification data to protect), preventing incomplete releases from being published.

Comment on lines +344 to +347
> **Pin to this release:** set \`SYNTHORG_VERSION=${TAG}\` before running
> (bash: \`export SYNTHORG_VERSION=${TAG}\` · PowerShell: \`\\\$env:SYNTHORG_VERSION='${TAG}'\`).
>
> **New to SynthOrg?** See the [Getting Started guide](https://synthorg.io/get/).
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

PowerShell escaping still produces a visible backslash.

In the unquoted heredoc <<NOTES, the sequence \\\$ is processed as: \\\, then \$$, resulting in \$env:SYNTHORG_VERSION — still showing a backslash before $env:. This contradicts the PR objective to fix PowerShell escaping.

To produce $env:SYNTHORG_VERSION (no visible backslash), use a single backslash:

🔧 Proposed fix
          > **Pin to this release:** set \`SYNTHORG_VERSION=${TAG}\` before running
-          > (bash: \`export SYNTHORG_VERSION=${TAG}\` · PowerShell: \`\\\$env:SYNTHORG_VERSION='${TAG}'\`).
+          > (bash: \`export SYNTHORG_VERSION=${TAG}\` · PowerShell: \`\$env:SYNTHORG_VERSION='${TAG}'\`).
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
> **Pin to this release:** set \`SYNTHORG_VERSION=${TAG}\` before running
> (bash: \`export SYNTHORG_VERSION=${TAG}\` · PowerShell: \`\\\$env:SYNTHORG_VERSION='${TAG}'\`).
>
> **New to SynthOrg?** See the [Getting Started guide](https://synthorg.io/get/).
> **Pin to this release:** set \`SYNTHORG_VERSION=${TAG}\` before running
> (bash: \`export SYNTHORG_VERSION=${TAG}\` · PowerShell: \`\$env:SYNTHORG_VERSION='${TAG}'\`).
>
> **New to SynthOrg?** See the [Getting Started guide](https://synthorg.io/get/).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/cli.yml around lines 344 - 347, In the unquoted heredoc
started with <<NOTES the PowerShell example currently uses an extra backslash
sequence (\\\$env:SYNTHORG_VERSION='${TAG}') which renders a visible backslash;
change that sequence to a single backslash (\$env:SYNTHORG_VERSION='${TAG}') so
the rendered output shows $env:SYNTHORG_VERSION without a preceding backslash;
update the text inside the <<NOTES heredoc accordingly.

- cli.yml: \\$ -> \$ in heredoc for correct $env: rendering
- finalize-release.yml: trap EXIT for tmpfile cleanup, remove manual rm calls
@Aureliolo Aureliolo merged commit 239aaf7 into main Mar 15, 2026
36 checks passed
@Aureliolo Aureliolo deleted the fix/release-notes-layout branch March 15, 2026 10:08
Comment on lines +370 to +376
CLEANED_BODY="$(printf '%s' "$EXISTING_BODY" | awk '
/^---$/ { buf=$0; next }
/^## CLI Installation$/ { buf=""; skip=1; next }
{ if(buf!="") print buf; buf="" }
/^## / { skip=0 }
!skip
')"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

--- separator leaks and duplicates on idempotent re-run

The awk only buffers a --- line and flushes it the moment any non-## CLI Installation line follows. Because CLI_SECTION puts a blank line between --- and ## CLI Installation:

---
          ← blank line
## CLI Installation

the sequence on a re-run is:

  1. --- → buffered
  2. blank line → buffer is flushed (--- is printed); blank line is also printed (!skip is 1 at this point)
  3. ## CLI Installationskip=1, but buf was already cleared in step 2

CLEANED_BODY therefore ends with a stray --- + blank line, and CLI_SECTION is then appended starting with its own ---, resulting in a double --- separator after every subsequent run.

To fix this, the blank line between --- and the heading must also be buffered so the buffer is only released when it is confirmed not to precede the ## CLI Installation heading:

CLEANED_BODY="$(printf '%s' "$EXISTING_BODY" | awk '
  /^---$/ { buf=$0; sep=""; next }
  /^$/ && buf != "" { sep=$0; next }
  /^## CLI Installation$/ { buf=""; sep=""; skip=1; next }
  { if(buf!="") { print buf; if(sep!="") print sep }; buf=""; sep="" }
  /^## / { skip=0 }
  !skip
')"
Prompt To Fix With AI
This is a comment left during a code review.
Path: .github/workflows/cli.yml
Line: 370-376

Comment:
**`---` separator leaks and duplicates on idempotent re-run**

The awk only buffers a `---` line and flushes it the moment any non-`## CLI Installation` line follows. Because `CLI_SECTION` puts a blank line between `---` and `## CLI Installation`:

```
---
          ← blank line
## CLI Installation
```

the sequence on a re-run is:
1. `---` → buffered
2. blank line → **buffer is flushed** (`---` is printed); blank line is also printed (`!skip` is 1 at this point)
3. `## CLI Installation``skip=1`, but `buf` was already cleared in step 2

`CLEANED_BODY` therefore ends with a stray `---` + blank line, and `CLI_SECTION` is then appended starting with its own `---`, resulting in a double `---` separator after every subsequent run.

To fix this, the blank line between `---` and the heading must also be buffered so the buffer is only released when it is confirmed not to precede the `## CLI Installation` heading:

```bash
CLEANED_BODY="$(printf '%s' "$EXISTING_BODY" | awk '
  /^---$/ { buf=$0; sep=""; next }
  /^$/ && buf != "" { sep=$0; next }
  /^## CLI Installation$/ { buf=""; sep=""; skip=1; next }
  { if(buf!="") { print buf; if(sep!="") print sep }; buf=""; sep="" }
  /^## / { skip=0 }
  !skip
')"
```

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines 359 to +363
\`\`\`bash
gh attestation verify synthorg_linux_amd64.tar.gz -R Aureliolo/synthorg
\`\`\`
Replace the filename with any archive from this release.
CLI_VERIFICATION_DATA -->
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Replace the filename... instruction silently dropped from Verification section

The line Replace the filename with any archive from this release. appears after the closing ``` fence, still inside <!-- CLI_VERIFICATION_DATA … -->. In finalize-release.yml the extraction for CLI_SLSA is:

sed -n '/^```bash$/,/^```$/p'

This range stops at the closing fence, so everything after it — including this prose note — is discarded. The published Verification section will only show the raw gh attestation verify command with no guidance about substituting other filenames.

If this instruction should survive to the release notes, either move it inside the code fence as a comment, or add it explicitly as a static line in the finalize-release.yml ### Provenance block next to the Verify with the GitHub CLI text.

Prompt To Fix With AI
This is a comment left during a code review.
Path: .github/workflows/cli.yml
Line: 359-363

Comment:
**`Replace the filename...` instruction silently dropped from Verification section**

The line `Replace the filename with any archive from this release.` appears after the closing ` ``` ` fence, still inside `<!-- CLI_VERIFICATION_DATA … -->`. In `finalize-release.yml` the extraction for `CLI_SLSA` is:

```bash
sed -n '/^```bash$/,/^```$/p'
```

This range stops at the closing fence, so everything after it — including this prose note — is discarded. The published Verification section will only show the raw `gh attestation verify` command with no guidance about substituting other filenames.

If this instruction should survive to the release notes, either move it inside the code fence as a comment, or add it explicitly as a static line in the `finalize-release.yml` `### Provenance` block next to the `Verify with the GitHub CLI` text.

How can I resolve this? If you propose a fix, please make it concise.

Aureliolo added a commit that referenced this pull request Mar 15, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.2.4](v0.2.3...v0.2.4)
(2026-03-15)


### Bug Fixes

* attach cosign signatures and provenance bundle to release assets
([#438](#438))
([f191a4d](f191a4d))
* create git tag explicitly for draft releases
([#432](#432))
([1f5120e](1f5120e))
* docker healthcheck, CI optimization, and container hardening
([#436](#436))
([4d32bca](4d32bca))
* ensure security headers on all HTTP responses
([#437](#437))
([837f2fc](837f2fc))
* make install scripts usable immediately without terminal restart
([#433](#433))
([b45533c](b45533c))
* migrate pids_limit to deploy.resources.limits.pids
([#439](#439))
([66b94fd](66b94fd))


### Refactoring

* redesign release notes layout
([#434](#434))
([239aaf7](239aaf7))


### Maintenance

* **site:** replace hero CTA with license link and scroll arrow
([#440](#440))
([56af41c](56af41c))
* **web:** adopt @vue/tsconfig preset
([#435](#435))
([7d4b214](7d4b214))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
This was referenced Mar 15, 2026
Aureliolo added a commit that referenced this pull request Mar 15, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.2.4](v0.2.3...v0.2.4)
(2026-03-15)


### Bug Fixes

* attach cosign signatures and provenance bundle to release assets
([#438](#438))
([f191a4d](f191a4d))
* create git tag explicitly for draft releases
([#432](#432))
([1f5120e](1f5120e))
* docker healthcheck, CI optimization, and container hardening
([#436](#436))
([4d32bca](4d32bca))
* ensure security headers on all HTTP responses
([#437](#437))
([837f2fc](837f2fc))
* make install scripts usable immediately without terminal restart
([#433](#433))
([b45533c](b45533c))
* migrate pids_limit to deploy.resources.limits.pids
([#439](#439))
([66b94fd](66b94fd))
* use cosign --bundle flag for checksums signing
([#443](#443))
([19735b9](19735b9))


### Refactoring

* redesign release notes layout
([#434](#434))
([239aaf7](239aaf7))


### Maintenance

* **main:** release 0.2.4
([#431](#431))
([63b03c4](63b03c4))
* remove stale v0.2.4 changelog section from failed release
([#446](#446))
([769de10](769de10))
* reset version to 0.2.3 for re-release
([#444](#444))
([8579993](8579993))
* **site:** replace hero CTA with license link and scroll arrow
([#440](#440))
([56af41c](56af41c))
* **web:** adopt @vue/tsconfig preset
([#435](#435))
([7d4b214](7d4b214))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
This was referenced Mar 15, 2026
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