Skip to content

feat(scripts): mechanise the release lifecycle with release-status.sh - #74

Merged
CybotTM merged 4 commits into
mainfrom
feat/release-status-script
Aug 7, 2026
Merged

feat(scripts): mechanise the release lifecycle with release-status.sh#74
CybotTM merged 4 commits into
mainfrom
feat/release-status-script

Conversation

@CybotTM

@CybotTM CybotTM commented Aug 7, 2026

Copy link
Copy Markdown
Member

The gap

All eight existing scripts run before the tag, and the guards only block bad commands. Everything after it — rewriting the body into a narrative, crediting contributors inline, confirming the registries actually serve the version — is prose in release-process.md.

That is the part that gets skipped, and it is skipped for a structural reason rather than carelessness: a release whose body is still the auto-generated PR-title list renders on GitHub exactly like a finished one. There is no red signal anywhere.

Measured on one session that released six packages: the step-9 overhaul was skipped on 4 of 7 releases. It surfaced only because a reader opened one and asked where the contributors were.

Compare the two skills today:

git-workflow github-release
mechanised pr-status.sh → computed NEXT 8 scripts, all pre-tag
after the tag nothing

What this adds

release-status.sh — the release-side counterpart to pr-status.sh. Reports where the repo sits and ends in a computed NEXT:

prepare-release · merge-release-pr · signed-tag · await-release-workflow
· rewrite-release-notes · verify-publication · ok

Exits non-zero until the release is genuinely finished, so it works as a gate.

release-notes-status.sh — the narrower question, usable on its own and with --last N to sweep a backlog. Checks the published body against the rules this skill already states: auto-generated shape, CI stub, harvested contributors never @mentioned, a hand-written ## Contributors section where inline credit belongs, CI-appended blocks clobbered by an overhaul.

/release-status now defers to the script and keeps its manual steps for explaining a verdict.

Validated while writing, not after

  • cleared seven overhauled releases as ok
  • flagged three that were never overhauled — naming @lradloff, a reporter the author of those notes had missed
  • found a repository whose release workflow declares extension-key and TYPO3_TER_ACCESS_TOKEN while TER 404s the key: a publication claim that has never been true. This is exactly what "Verify each publication claim before reporting the release done" asks for, and nothing enforced it.

Two false starts are pinned as behaviour rather than left as lore:

  • the TER assertion is gated on the workflow declaring it, after an early version raised a false alarm on a repo that deliberately does not publish there
  • a stale-worktree guard, after an early version reported ok for a version released two tags ago — the working tree declared the older version and nothing compared it to the latest release

Tests

tests/release-notes-status.test.sh, following the existing harvest-contributors.test.sh pattern — pure helpers, no network, 8 assertions green. It pins the false positive that cost the most time: the harvest script's own header contains @mention each INLINE at their change, so extracting credits without dropping comment lines invents a contributor named @mention and reports every finished release as missing them.

The skill's eight scripts all run before the tag, and the guards only
block bad commands. Everything after the tag — rewriting the body into a
narrative, crediting contributors inline, confirming the registries
actually serve the version — is prose. That is the part that gets
skipped, because a release with an auto-generated body renders exactly
like a finished one.

Measured on one session releasing six packages: the step-9 overhaul was
skipped on 4 of 7 releases, and nobody noticed until a reader did.

release-status.sh is the release-side counterpart to git-workflow's
pr-status.sh: it reports where the repo sits in the lifecycle and ends
in a computed NEXT (prepare-release, merge-release-pr, signed-tag,
await-release-workflow, rewrite-release-notes, verify-publication, ok),
exiting non-zero until the release is genuinely finished.

release-notes-status.sh answers the narrower question and is reusable on
its own: is the published body still CI output, is every harvested
contributor @mentioned, was a Contributors section hand-written where
inline credit belongs, did an overhaul clobber the CI-appended blocks.

Both were validated against real releases while being written:

- correctly cleared seven overhauled releases
- correctly flagged three that were never overhauled, naming a reporter
  the author of those notes had missed
- found a repository whose release workflow declares an extension-key
  and a TER token while TER 404s the key — a publication claim that has
  never been true, which the "verify each publication claim" rule asks
  for and nothing enforced
- the TER assertion is gated on the workflow actually declaring it,
  after an early version raised a false alarm on a repo that
  deliberately does not publish there
- a stale-worktree guard, after an early version reported ok for a
  version released two tags ago

/release-status now defers to the script and keeps its manual steps for
explaining a verdict.

Signed-off-by: Sebastian Mendel <info@sebastianmendel.de>
Copilot AI lite review requested due to automatic review settings August 7, 2026 14:35
@github-actions github-actions Bot added documentation Improvements or additions to documentation skill labels Aug 7, 2026
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown

Dependency Review

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

Scanned Files

None

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

The pointer to the new scripts pushed SKILL.md to 643 words against a
500 limit that it already sat exactly on, so Skill Validation failed.

Trimmed the pointer to two lines and condensed step 9, whose detail —
inline crediting, reporters, the harvest-vs-git-log rule — is already
stated verbatim in references/release-process.md Phase 5, which it now
links instead of repeating.

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

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

… lookup

The declared-version chain covered ext_emconf.php and composer's
extra.typo3/cms.version. A skill repo declares its version only in
.claude-plugin/plugin.json, so every skill repo resolved to an empty
declared version and the verdict came out as prepare-release no matter how
cleanly it was released (checked against concourse-ci-skill at v1.9.3:
declared <none>, NEXT prepare-release; with the fallback: declared 1.9.3,
NEXT verify-publication).

latest_tag was assigned and never read (shellcheck SC2034), costing one API
call per invocation.

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

CybotTM commented Aug 7, 2026

Copy link
Copy Markdown
Member Author

Manual review standing in for copilot_code_review — Copilot returned its quota-limit message instead of a review.

Ran against the PR head: shellcheck on all three scripts, bash -n, the shipped test suite (8/8 pass), and release-status.sh end-to-end against a live repo.

Two findings, both fixed in 642bb7a on this branch:

1. Skill repos always came out as prepare-release. The declared-version chain read ext_emconf.php, then composer's extra.typo3/cms.version. A skill repo declares its version only in .claude-plugin/plugin.json, so declared stayed empty and the verdict was prepare-release regardless of the real state. Controlled check against netresearch/concourse-ci-skill, cleanly released at v1.9.3:

declared NEXT
before <none> prepare-release — no version file found
after 1.9.3 verify-publication — not served yet by: packagist

That is the whole skill fleet — the tool's main audience here — getting a wrong answer. Added .claude-plugin/plugin.json as the third fallback and named it in the not-found message.

2. latest_tag was assigned and never read (shellcheck SC2034), spending one API call per invocation. $latest (the release) is used throughout; $latest_tag (the newest tag) nowhere. Removed.

Two observations, not changed here:

  • release-notes-status.sh has a test suite; release-status.sh has none, and it holds the verdict logic — the part worth pinning.
  • The smoke run reports missing on packagist for a skill repo. Worth confirming that skill repos are expected on Packagist at all before that becomes a standing verify-publication verdict for the fleet.

Running the script against its own repo exposed the gap your plugin.json
fix uncovered from the other side: a skill repo (composer type
ai-agent-skill) is not a Packagist package, so the version assertion
failed it forever.

"Packagist does not know this package" (404 on the package) now means
skip; "package known, version absent" still means the publication has
not landed. Same distinction the TER check already makes.

Verified both directions: the skill repo now reads ok, and t3x-nr-llm
v0.26.0 -- a real Packagist package -- is still asserted.

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

sonarqubecloud Bot commented Aug 7, 2026

Copy link
Copy Markdown

@CybotTM
CybotTM requested a lite review from Copilot August 7, 2026 15:04
@CybotTM
CybotTM merged commit 469aba9 into main Aug 7, 2026
23 of 24 checks passed
@CybotTM
CybotTM deleted the feat/release-status-script branch August 7, 2026 15:05

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

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 skill

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants