Skip to content

feat(github-release): document .sigstore.json extension + release-prep PR pattern#21

Merged
CybotTM merged 4 commits intomainfrom
feat/sigstore-and-release-prep-pattern
May 5, 2026
Merged

feat(github-release): document .sigstore.json extension + release-prep PR pattern#21
CybotTM merged 4 commits intomainfrom
feat/sigstore-and-release-prep-pattern

Conversation

@CybotTM
Copy link
Copy Markdown
Member

@CybotTM CybotTM commented May 5, 2026

Summary

Two lessons surfaced during the netresearch/t3x-nr-passkeys-be v0.9.0 release that the skill was either missing or only half-documenting. This PR captures both — and fixes the template/checkpoint that embodied the wrong pattern.

Lesson 1 — .sigstore.json extension for cosign output

OSSF Scorecard's Signed-Releases check pattern-matches release-asset filenames against a fixed allowlist:

  • .sig, .asc, .minisig, .sigstore, .sigstore.json, .intoto.jsonl

The .bundle extension that cosign sign-blob --bundle writes by default is not on that list, so cosign-signed releases that use .bundle score 0/10 on Signed-Releases even though they ARE signed. The bytes inside the file are identical to the Sigstore bundle JSON format — the rename is purely cosmetic for tooling detection, and cosign verify-blob --bundle file.sigstore.json works identically.

Concrete fix:

# Wrong — Scorecard sees this as unsigned
cosign sign-blob --yes \"\$file\" --bundle \"\${file}.bundle\"

# Right — Scorecard recognizes this as signed
cosign sign-blob --yes \"\$file\" --bundle \"\${file}.sigstore.json\"

Past releases cannot be retroactively fixed (GitHub releases are immutable once assets are attached). Only future releases benefit. Scorecard averages over the last 4 releases, so the score climbs gradually.

Reference upstream change for the netresearch shared workflows (already merged): netresearch/typo3-ci-workflows#84 — applied to both `release.yml` and `release-typo3-extension.yml`.

Lesson 2 — `release: vX.Y.Z` PR pattern + tag the merge commit

The release-prep PR pattern was already documented across SKILL.md, `commands/release-prepare.md`, and `references/recovery-procedures.md` ("Branch Protection Blocks the [RELEASE] Commit" section). What was missing:

  1. Affirmative reasoning for why a PR is preferred even though many tutorials online push version bumps directly to `main`:
    • Branch protection on `main` may block direct pushes anyway
    • Gives CI one more chance to verify the version bump didn't break anything
    • Auto-approve / Copilot review still runs cleanly
  2. Tag the merge commit, not the branch tip — the load-bearing detail. After merge, `git checkout main && git pull`, then `git tag -s vX.Y.Z`. Tagging from inside the `release/vX.Y.Z` branch worktree skips the merge commit on merge-commit-strategy repos and produces a tag that's not cleanly reachable from `main`.

Changes

Commit 1 — `fix(release): use .sigstore.json extension for cosign output`

The skill currently embodies the bug Lesson 1 calls out. Fixed:

  • `templates/release-generic.yml`: emit `${file}.sigstore.json` instead of `${file}.bundle`, with an inline comment explaining why
  • `checkpoints.yaml` GR-10: pattern now accepts `.sigstore.json` (preferred) AND keeps `.bundle` (legacy, for already-published releases). Updated `desc:` to spell out the Scorecard implication. jq regex sanity-checked against `.sigstore.json`-only, `.bundle`-only, and no-signature inputs — all behave correctly.
  • `evals/evals.json` scenario 28: `expected_output` and expectations updated to reflect both extensions and the Scorecard rule

Commit 2 — `docs(release): capture sigstore extension and merge-commit tagging lessons`

  • `references/supply-chain-security.md`: new "Output extension matters for OSSF Scorecard" subsection under Sigstore signing — full allowlist, the bytes-are-identical point, the concrete fix snippet, the immutability caveat, and the upstream PR reference. Verification snippet now uses `--bundle artifact.tar.gz.sigstore.json` to keep the example consistent.
  • `references/release-process.md` Phase 3: explicit "checkout main && pull, then tag" reasoning + a paragraph on why the merge commit (not the `release/vX.Y.Z` branch tip) is the right target.
  • `SKILL.md` step 5/6: brief affirmative note that a release PR is preferred over direct `main` pushes (with the "many tutorials show direct pushes" reasoning), and step 6 now points readers at Phase 3 for the merge-commit detail.

Test plan

  • `checkpoints.yaml` parses as YAML
  • `evals.json` parses as JSON, scenario 28 keeps the same shape (`id`, `prompt`, `expected_output`, `expectations`, `assertions`)
  • `templates/release-generic.yml` parses as YAML
  • GR-10 jq pattern returns true for `.sigstore.json`, true for `.bundle`, exit 1 for neither
  • Both commits signed (ED25519, `info@sebastianmendel.de`) and DCO-signed-off
  • Upstream PR netresearch/typo3-ci-workflows#84 verified merged before referencing
  • CI on this PR passes the existing checkpoint suite
  • No prose-in-docs claims exceed what's verified above

CybotTM added 2 commits May 5, 2026 20:21
OSSF Scorecard's Signed-Releases check pattern-matches against a fixed
allowlist of signature extensions: .sig, .asc, .minisig, .sigstore,
.sigstore.json, .intoto.jsonl. The .bundle extension that cosign writes
by default is NOT on that list, so cosign-signed releases using .bundle
score 0/10 on Signed-Releases.

The bytes inside the file are identical to the Sigstore bundle JSON
format — only the filename matters for tooling detection. cosign
verify-blob --bundle works identically with either extension.

Changes:
- templates/release-generic.yml: emit ${file}.sigstore.json instead of
  ${file}.bundle, with an inline comment explaining why
- checkpoints.yaml GR-10: accept .sigstore.json (preferred) and keep
  .bundle (legacy) so existing releases don't fail; describe the
  Scorecard implication in the desc
- evals/evals.json scenario 28: update expected_output and expectations
  to reflect both extensions and the Scorecard rule

Reference upstream change to the netresearch shared workflows:
netresearch/typo3-ci-workflows#84

Signed-off-by: Sebastian Mendel <info@sebastianmendel.de>
…ssons

Two lessons surfaced during the netresearch/t3x-nr-passkeys-be v0.9.0
release that the skill was missing:

1. .sigstore.json vs .bundle for cosign output

   OSSF Scorecard's Signed-Releases check only recognizes a fixed
   allowlist of signature extensions; .bundle (cosign's default) is not
   on it. Add a dedicated subsection to references/supply-chain-security.md
   explaining the allowlist, why the rename is purely cosmetic (bytes are
   the Sigstore bundle JSON regardless of filename), the concrete
   workflow snippet, and the "past releases can't be retroactively fixed"
   caveat (Scorecard averages over the last 4 releases, so the score
   climbs gradually). References upstream PR
   netresearch/typo3-ci-workflows#84.

2. Tag the merge commit, not the release branch tip

   The release-prep PR pattern was already documented across SKILL.md,
   release-prepare.md, and recovery-procedures.md, but none of them
   spelled out *which commit* to tag after the PR merges. Add the
   "checkout main && pull, then tag" reasoning to release-process.md
   Phase 3, and a brief affirmative note to SKILL.md step 5 stating that
   a release/vX.Y.Z PR is preferred over direct main pushes (even though
   many tutorials show direct pushes — branch protection often blocks
   them anyway, and the PR gives CI one more chance to verify the
   version bump).

The companion commit fixes the template, checkpoint, and eval that
embodied the .bundle pattern — these docs explain the *why*.

Signed-off-by: Sebastian Mendel <info@sebastianmendel.de>
Copilot AI review requested due to automatic review settings May 5, 2026 18:22
@github-advanced-security
Copy link
Copy Markdown

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the GitHub release skill’s templates, checkpoints, eval scenario text, and documentation to reflect two release learnings: (1) cosign bundle assets should use a Scorecard-recognized filename extension (.sigstore.json), and (2) version bumps should go through a release-prep PR and the tag should be created from main after merge.

Changes:

  • Update the shared release workflow template to emit cosign bundle outputs as ${file}.sigstore.json instead of ${file}.bundle.
  • Update GR-10 checkpoint + eval scenario 28 guidance to recognize .sigstore.json (preferred) while keeping .bundle as legacy.
  • Expand documentation on why the extension matters for OSSF Scorecard and clarify the “release PR + tag after merge” process.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
skills/github-release/templates/release-generic.yml Switch cosign bundle output extension to .sigstore.json and document rationale inline.
skills/github-release/checkpoints.yaml Update GR-10 asset-detection pattern and description to include .sigstore.json and legacy .bundle.
skills/github-release/evals/evals.json Update scenario 28 expected behavior/expectations to prefer .sigstore.json and note Scorecard implications.
skills/github-release/references/supply-chain-security.md Document Scorecard allowlist and why .sigstore.json is required for tooling detection.
skills/github-release/references/release-process.md Clarify tagging steps post-merge and rationale for tagging from main after PR merge.
skills/github-release/SKILL.md Reinforce PR-based release-prep flow and point to the tagging guidance in release-process reference.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread skills/github-release/references/release-process.md Outdated
Comment thread skills/github-release/references/release-process.md Outdated
Comment thread skills/github-release/checkpoints.yaml Outdated
Comment thread skills/github-release/checkpoints.yaml Outdated
Comment thread skills/github-release/SKILL.md Outdated
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request updates the GitHub release process documentation and templates to prioritize the .sigstore.json extension for cosign signature bundles, ensuring compliance with OSSF Scorecard's Signed-Releases check. It also clarifies the requirement to tag the merge commit on the main branch rather than the release branch tip. I have no further feedback to provide as no review comments were present.

CybotTM added 2 commits May 5, 2026 23:08
… .sigstore to checkpoint

- SKILL.md: trim to 490 words (was 547, max 500); make step 6 strategy-agnostic
  by tagging main's HEAD rather than asserting "merge commit"
- references/release-process.md: clarify that main's post-merge HEAD differs by
  merge strategy (fast-forward / squash / merge-commit); fix incorrect claim
  that release branch tip is "not reachable from main cleanly"
- checkpoints.yaml: extend GR-10 to accept bare .sigstore extension (also on
  the OSSF Scorecard Signed-Releases allowlist), alongside .sigstore.json,
  .bundle, and .sig+.pem

Signed-off-by: Sebastian Mendel <info@sebastianmendel.de>
The reusable validate workflow's inline yamllint default sets
line-length.max to 200, which rejects the GR-10 checkpoint pattern
(now 280 chars after adding the .sigstore branch). Add a repo-local
.yamllint.yml so the workflow uses the project's config instead of
the inline default — long single-line jq patterns in checkpoints.yaml
are intentional and shouldn't be split.

Signed-off-by: Sebastian Mendel <info@sebastianmendel.de>
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented May 5, 2026

@CybotTM CybotTM merged commit b8e6ce6 into main May 5, 2026
9 checks passed
@CybotTM CybotTM deleted the feat/sigstore-and-release-prep-pattern branch May 5, 2026 21:13
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.

3 participants