8.0 KiB
Release Process
This is the maintainer playbook for cutting a repository release. Historical release notes belong in CHANGELOG.md; this file documents the repeatable process.
Preconditions
- The tracked working tree is clean.
- You are on
main. CHANGELOG.mdalready contains the release section you intend to publish.- README counts, badges, and acknowledgements are up to date.
Release Checklist
- Run the scripted preflight:
npm run release:preflight
This preflight now runs the deterministic sync:release-state flow, refreshes the tracked web assets in apps/web-app/public, executes the local test suite, installs the web-app dependencies, runs the web-app build, and performs npm pack --dry-run --json so release tags are validated against the same artifact path used later in CI.
The active CI/release contract also expects:
- Python dependencies to come from
tools/requirements.txt, - the web app coverage job (
npm run app:test:coverage) to stay green, - and
npm run security:docsto pass without relying on non-blocking audit warnings.
- Mandatory documentation hardening (repo-wide SKILL.md security scan):
npm run security:docs
This is required so every release validates repo-wide risky command patterns and inline token-like examples before publishing.
- Optional hardening pass:
npm run validate:strict
Use this as a diagnostic signal. It is useful for spotting legacy quality debt, but it is not yet the release blocker for the whole repository.
- Update release-facing docs:
- Add the release entry to
CHANGELOG.md. - Confirm
README.mdreflects the current version and generated counts. - Confirm Credits & Sources, contributors, and support links are still correct.
- If PR or CI workflow behavior changed during the cycle, confirm maintainer and contributor docs mention the active checks (for example the
skill-reviewworkflow for any change underskills/**orplugins/**/skills/**). - If maintainers changed declared risk labels during the cycle, confirm that each change has semantic review evidence rather than lexical inference.
- Prepare the protected release PR:
npm run release:prepare -- X.Y.Z
This command:
- checks
CHANGELOG.mdforX.Y.Z - aligns
package.json/package-lock.json - runs the full release suite
- explicitly proves
plugin-compat:checkandbundles:checkafter regeneration - refreshes release metadata in
README.md - regenerates canonical registries, tracked web assets, both plugin marketplaces, every Codex/Claude mirror and editorial bundle, and every release-owned plugin manifest
- stages canonical release files
- creates and pushes
release/vX.Y.Z - opens a release PR containing the scripted canonical release state
Prerelease versions use the same protected flow, for example 15.0.0-rc.1. They must have their own exact changelog section.
- Merge the release PR through required checks, update local
main, then publish the GitHub release:
npm run release:publish -- X.Y.Z
This command requires exactly one merged release PR from the same repository, authored by the repository owner, with base main, exact title chore: release vX.Y.Z, and head branch release/vX.Y.Z. Zero or multiple candidates fail closed; the command never chooses the newest approximate match. It then proves local main equals protected origin/main and that PR's exact squash commit, checks that no canonical-sync PR or release-state drift remains, creates or reuses the matching local/remote tag safely, and creates the GitHub release object from the matching CHANGELOG.md section. SemVer prereleases are marked as GitHub prereleases. It never pushes main directly and can be retried after a partial tag/release failure.
- Publish to npm if needed:
npm publish --tag latest
Normally this still happens via the existing GitHub release workflow after the GitHub release is published. The workflow publishes stable versions explicitly to npm's latest dist-tag and prerelease versions explicitly to next; it fails closed on an invalid version. Verify both tags after a prerelease so latest remains on the last stable release.
npm view agentic-awesome-skills dist-tags --json
The workflow reruns sync:release-state, installs Python dependencies from tools/requirements.txt, refreshes tracked web assets, fails on canonical drift via git diff --exit-code, executes tests and docs security checks, runs the web-app coverage gate, enforces npm audit --audit-level=high, builds the web app, and dry-runs the npm package before publishing.
- Complete the mandatory full-release-alignment gate.
A stable or prerelease version is not complete when only its tag, GitHub Release, or npm package exists. After publication:
- rerun
npm run sync:release-state,npm run plugin-compat:check, andnpm run bundles:check, then require an idempotent second pass and a clean tree; - verify every release-owned Codex/Claude plugin manifest and Claude marketplace entry equals
X.Y.Z, without treating nested third-party skill manifests as AAS release manifests; - bind local and remote
main, the tag, GitHub Release, npm version and intended dist-tag, required CI, CodeQL, and the explicitly dispatched release-only Pages deployment to the exact released commit; - dispatch Pages only from the exact immutable
vX.Y.Zrelease tag, never frommainor another branch, and require the tag, package version, and published GitHub Release to identify the same commit before build work begins; - read back live
llms.txt,skills.json, catalog/plugin routes, and the legacy redirect bridge; - discover every already-configured local AAS MCP host from real configuration, update each existing entry with the digest-bound two-pass
aas mcp configureflow, pinagentic-awesome-skills@X.Y.Zand--version X.Y.Z, preserve a backup, restart or reconnect the host, and prove a realinitializeplustools/listhandshake reportsX.Y.Z; - fetch and fast-forward
mainagain after automation settles, requiregit rev-list --left-right --count main...origin/mainto return0 0, and repeat the no-drift, public-surface, and MCP parity checks.
A release request covers updates to existing AAS MCP host entries only. Creating a previously absent host configuration still needs separate authorization. Any mismatch, inaccessible configured host, or stale public surface keeps the release incomplete.
Canonical Sync Bot
main still uses the repository's auto-sync model for canonical generated artifacts, but through a protected pull-request contract:
- PRs stay source-only.
- After merge, the
mainworkflow may open or updateautomation/canonical-repo-state; it never pushes generated files directly tomain. - The bot PR is only allowed to stage files resolved from
tools/scripts/generated_files.js --include-mixed. - Its explicitly dispatched required checks require both managed-only paths and an exact converged Git tree before an immediate protected merge.
- If repo-state sync leaves any unmanaged tracked or untracked drift, the workflow fails instead of pushing a partial fix.
- The scheduled hygiene workflow follows the same contract and shares the same concurrency group so only one canonical sync writer runs at a time.
- Between the protected release merge and its tag, the only canonical-sync successor subjects accepted by the release contract are exactly
chore: synchronize canonical repository stateand[skip pages] chore: synchronize canonical repository state. The latter is the durable audit marker that the successor must not trigger the release-only Pages lane; both remain subject to the managed-only range validation.
Rollback Notes
- If the release tag is wrong, delete the tag locally and remotely before republishing.
- If generated files drift after tagging, cut a follow-up patch release instead of mutating a published tag.
- If npm publish fails after tagging, fix the issue, bump the version, and publish a new release instead of reusing the same version.