Skip to content

Release process

This page is the development-facing release checklist. User-facing release notes remain in CHANGELOG.md and docs/release.md.

Release model

  • Versioning follows Semantic Versioning for the Python server and matching wrappers.
  • Release PRs are generated by release-please.
  • Publishing runs from GitHub Actions, not from a maintainer workstation.
  • Artifact-specific workflows attach checksums, SBOMs, provenance, and attestations where supported.

Preparing versus publishing

Release Please no longer runs after every merge to main. Its scheduled run once per day (03:37 UTC) prepares or updates the release PR and synchronizes its generated version-derived files. For an immediate refresh, use Actions → Release Please → Run workflow, selecting main. Neither scheduled nor manually requested preparation creates tags or publishes GitHub Releases.

When a release is ready, review and merge the protected release PR after its required checks pass. The merge updates the version metadata in main. The normal CI workflow validates that exact main commit. After its Required PR Gate and SonarCloud Scan jobs have succeeded, CI calls the reusable Publish Release workflow only for that trusted main push. The called workflow confirms via the GitHub API that the exact commit is the merge commit of a reviewed release-please--branches--main PR; ordinary main merges return successfully without publishing. Normal PR merges, failed CI runs, cancelled/skipped aggregate gates, fork-originated CI and daily release preparation cannot start publication. The publish-capable GitHub App token is minted only after this verification.

The existing tag/release-triggered workflows then publish the respective packages and verify the usual checksums, SBOMs, provenance, and attestations. This keeps protected PR review and CI as the publication approval boundary; merging a release PR is an intentional authorization to publish once those checks succeed.

For recovery only, an authorized maintainer can still use Actions → Publish Release → Run workflow, selecting main. The automatic and manual paths share a serialized concurrency group; Release Please's released-version tracking prevents publication of the same candidate as a new version. Do not use the manual workflow unless publication failed or did not start.

Avoid bypassing this release decision by manually running individual publish-* backfill workflows or creating release tags by hand. Such workflows remain available only for authorized recovery and retain their existing source/tag, environment and integrity guards.

Pre-release checks

Before approving a release PR:

corepack pnpm run check:meta
corepack pnpm run check:lint
corepack pnpm run check:type
corepack pnpm run check:test
corepack pnpm run check:security
corepack pnpm run check:workflows
corepack pnpm run check:build

If the full suite exceeds local time limits, run the same underlying pytest suites in documented chunks and record the evidence in the PR.

Release-note completeness before release PR approval

Release Please may prepare its draft before later feature/fix merges. Resolve the last actually published GitHub Release and matching component tag separately for server, npm and GUI; tag existence alone is not proof of publication. Compare against the exact release PR head SHA, not floating main.

For the already-published v4.2.0-to-v4.3.0 regression case:

python3 scripts/audit_release_notes.py \
  --version 4.3.0 --previous-version 4.2.0 \
  --candidate 282c7499f67457bb247d2390379410f05e96a3e8 \
  --json-out release-audit.json --markdown-out release-audit.md

The read-only tool checks exact tag ancestry, candidate source/config/changelog versions and immutable commit links. missing requires material-impact review; needs_review and cross_component_review are open questions, not exclusions. excluded records the conservative convention-based reason. Inspect actual diffs before deciding what affects users. Native compatibility, release asset integrity and manufactured-board acceptance cannot be inferred from a note.

Before merging any release PR, reconcile every material uncovered change or justify its exclusion, update the PR's generated notes through its normal review process, and rerun against the new exact head. Missing tags, history or version sections fail closed. Never use this audit to bypass existing required checks, approval, tag restrictions or trusted publishing controls. The historical example is recorded under docs/evidence/release-notes/ and flags one missing feat(evals) #1225 server entry without asserting product failure.

Release validation

.github/workflows/release.yml is a low-risk validation workflow. It checks release metadata and package build behavior without publishing artifacts or requiring secrets.

Live-model release readiness

Live Model Release Gate is scope-aware rather than a universal provider-availability gate. The release policy resolves the previous reachable mcp-server-v* tag and compares the versioned agent_contract_paths at that release with the release candidate.

  • If the contract is unchanged, live-model readiness succeeds with no_agent_contract_change_since_release; an old or temporarily unapproved live baseline does not block an unrelated release.
  • One narrow, audited nonfunctional exception is verified by exact Python AST: removing the unused EvidenceSanitizationError name from the existing kicad_mcp.evals.live_runner import in scripts/run_live_model_eval.py. The original module must still be imported, no reflection or reference to that name may be present, and every other tracked agent-contract file must match the preceding server release. Source content digests are not rewritten and approved baseline evidence is not modified. Any other change to a tracked contract path still requires the protected full gate.
  • If the contract changed, the existing fail-closed baseline rules apply. Unapproved, stale, future-dated, or digest-mismatched evidence requires the protected full gate and reviewed baseline promotion before publishing.
  • If the previous server release tag/history cannot be resolved, readiness fails closed. Release and publish workflows therefore check out full Git history (fetch-depth: 0).

  • Protected live evidence is intentionally asymmetric for reliability and runtime cost: NVIDIA Nemotron Lightning is the single blocking live smoke provider and also runs the full 65-case baseline benchmark. The standard full evidence floor is two repetitions. Cross-provider OpenCode/OpenAI runs remain available as manual diagnostics, but external provider authentication, quota, or trial-service outages do not block an otherwise healthy release unless they affect the blocking NVIDIA evidence path.

Release Readiness and Release Validation each print an actionable Live-model release readiness GitHub Actions step summary, including the changed tracked paths, baseline age, digests, release tag and whether protected full evidence or baseline promotion is required. A successful verified no-op classification is not permission to bypass normal CI, security, packaging, review, or manual publication decisions. No preflight automatically promotes model evidence or publishes a release.

This rule is based on the actual model-facing contract diff, not on whether the version is a patch, minor, or major release. Deterministic CI, security, packaging, metadata, and required-status checks remain mandatory in every case.

Post-release checks

After a release is published:

  1. Verify GitHub Release notes are human-readable.
  2. Verify package versions match pyproject.toml, package.json, server.json, and registry metadata.
  3. Verify checksums and release evidence artifacts are attached where expected.
  4. Verify package installation smoke tests.
  5. Verify PyPI Integrity API provenance identifies oaslananka/kicad-mcp-pro, publish-python.yml, and the pypi environment.
  6. Update OpenSSF evidence if release process or artifact classes changed.

Do not do

  • Do not publish from a local workstation.
  • Do not bypass protected environments for production package registries.
  • Do not manually edit generated metadata without running metadata sync checks.
  • Do not claim SLSA level without explicit per-artifact evidence.