Skip to content

ci(release): add MCP release-candidate dry-run workflow and checks#379

Merged
JSONbored merged 3 commits into
JSONbored:mainfrom
JPette1783:feat/mcp-release-candidate-dry-run
Jun 4, 2026
Merged

ci(release): add MCP release-candidate dry-run workflow and checks#379
JSONbored merged 3 commits into
JSONbored:mainfrom
JPette1783:feat/mcp-release-candidate-dry-run

Conversation

@JPette1783
Copy link
Copy Markdown
Contributor

@JPette1783 JPette1783 commented Jun 4, 2026

Summary

Closes: #85

  • Adds a single, non-publishing MCP release-candidate dry-run maintainers can run before pushing a release tag, so mistakes are caught before the public package is touched (ci(release): add MCP release candidate dry-run workflow #85).
  • New npm run mcp:release-candidate (and a manual MCP Release Candidate Dry-Run workflow) validate package version + tag format, the changelog target-version section, the tarball allowlist + secret scan, a packed-tarball CLI smoke, and that the publish workflow stays tokenless — all without publishing.
  • Pure check logic lives in a testable core module with unit tests covering success and failure fixtures; dry-run output is redacted of tokens, npm credentials, GitHub auth, and absolute local paths.

What was added

  • scripts/mcp-release-candidate-core.mjs (+ .d.mts): pure, deterministic checks — checkTag (mcp-v format + match to package.json), checkChangelog (real dated ## mcp-v<version> section), checkTarball (publish allowlist + secret-content scan), checkTokenlessPublish (id-token: write + --provenance, no npm token), buildReleaseCandidateReport (pass/fail + non-publishing next steps), and redactSensitive (scrubs tokens/credentials/paths).
  • scripts/check-mcp-release-candidate.mjs (npm run mcp:release-candidate): reads the package version, derives or accepts --tag, runs npm pack to gate tarball contents, performs a packed-tarball CLI smoke (install into a temp project + gittensory-mcp --help), verifies npm-publish.yml is tokenless, prints redacted PASS/FAIL with next steps, and exits non-zero on any failure. Never publishes.
  • .github/workflows/mcp-release-candidate.yml: manual workflow_dispatch dry-run with an optional tag input; contents: read only.
  • test/unit/mcp-release-candidate.test.ts: success fixture plus failure fixtures (missing changelog section, unexpected tarball file, secret-bearing file, tag/package mismatch), tokenless-config checks, and log-redaction / forbidden-public-language invariants.

Scope

  • This PR is focused and does not mix unrelated backend, UI, MCP, docs, dependency, and deploy changes.
  • This follows CONTRIBUTING.md and does not reintroduce GitHub Pages, VitePress, site/, or CNAME.
  • I linked an issue, or this is small enough that the summary explains why an issue is not needed. (ci(release): add MCP release candidate dry-run workflow #85)

Validation

  • git diff --check
  • npm run actionlint — clean (ran github-actionlint .github/workflows/mcp-release-candidate.yml directly; the npm script's glob is a Windows-only shell limitation)
  • npm run typecheck — clean
  • npm run test:coverage locally — 976 pass (1 skipped); branch 97.02%, lines 99.65%, statements 99.07%, functions 98.40% (no src/ behavior changed, so global coverage is unchanged and above the gate; the 3 pre-existing Windows-only spawn failures mcp-cli, github-type-label, mcp-release were excluded locally and are unaffected)
  • node scripts/check-mcp-release-candidate.mjs — all five checks PASS on the current tree (exit 0); a mismatched --tag fails with clear remediation (exit 1)
  • npm run test:workers
  • npm run build:mcp
  • npm run test:mcp-pack
  • npm run ui:openapi:check
  • npm run ui:lint
  • npm run ui:typecheck
  • npm run ui:build
  • npm audit --audit-level=moderate
  • New or changed behavior has unit/integration tests for new branches, fallback paths, and sanitizer boundaries

If any required check was skipped, explain why:

  • Worker/MCP/UI/audit steps run in CI on Linux; the local environment has known Windows-only failures in mcp-cli/mcp-release/type-label tooling unrelated to this change.

Safety

  • No secrets, wallet details, hotkeys, coldkeys, user PATs, private keys, raw trust scores, private rankings, or private maintainer evidence are exposed. (redactSensitive scrubs tokens/credentials/paths from all dry-run output; tested.)
  • Public GitHub text stays sanitized, low-noise, and does not imply compensation guarantees or optimization tactics. (Report/messages are asserted free of forbidden public language.)
  • Auth, cookie, CORS, GitHub App, Cloudflare, or session changes include negative-path tests. (n/a)
  • API/OpenAPI/MCP behavior is updated and tested where needed. (n/a — release tooling only; no runtime MCP behavior change)
  • UI changes use live API data or real empty/error/loading states, not production mock/demo fallbacks. (n/a)
  • Visible UI changes include screenshots or a short recording. (n/a)
  • Public docs/changelogs are updated where needed; changelogs are only edited for release-prep PRs. (No changelog/snapshot files modified.)

Notes

  • No-publish guarantee: the dry-run never runs npm publish; the packed CLI smoke installs the tarball into a throwaway temp project and removes both the temp dir and the tarball afterward. The runner uses captured (not streamed) subprocess output and redacts it before printing.
  • Tokenless verification: checkTokenlessPublish requires id-token: write and --provenance and fails if any npm auth token (NODE_AUTH_TOKEN/NPM_TOKEN/_authToken/secrets.NPM*) appears in npm-publish.yml, keeping trusted publishing intact.
  • Failure clarity: every failing check maps to a concrete remediation next step, and the runner exits non-zero so the manual workflow (with set -euo pipefail) fails loudly — without ever attempting a publish.
  • Coverage: the new script/tests live outside src/, so the 97% global gate is unaffected; the suite still passes with branch coverage above the threshold.

Adds a single, non-publishing preflight maintainers can run before tagging an
MCP release, so release mistakes are caught before the public package is touched.

- scripts/mcp-release-candidate-core.mjs: pure, deterministic checks — tag
  format + version match, changelog target-version section, tarball allowlist +
  secret scan, and tokenless trusted-publishing verification (id-token +
  provenance, no npm token). redactSensitive() scrubs tokens, npm credentials,
  GitHub auth, and absolute local paths from any output.
- scripts/check-mcp-release-candidate.mjs (npm run mcp:release-candidate): reads
  the package version, derives or accepts --tag, runs npm pack to gate tarball
  contents, runs a packed-tarball CLI smoke (install + gittensory-mcp --help),
  verifies npm-publish.yml stays tokenless, and prints redacted PASS/FAIL plus
  next steps. Exits non-zero on any failure and never publishes.
- .github/workflows/mcp-release-candidate.yml: manual workflow_dispatch dry-run
  with an optional tag input, contents:read only.
- test/unit/mcp-release-candidate.test.ts: success fixture plus failure fixtures
  for missing changelog section, unexpected/secret-bearing tarball files, and
  tag/package mismatch; tokenless-config and log-redaction/public-language
  invariants.

Global coverage unchanged and above the 97% gate (branches 97.02%, lines
99.65%, statements 99.07%, functions 98.40%); no src behavior changes.
@JPette1783 JPette1783 requested a review from JSONbored as a code owner June 4, 2026 11:00
@dosubot dosubot Bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Jun 4, 2026
@superagent-security superagent-security Bot added the pr:flagged PR flagged for review by security analysis. label Jun 4, 2026
Copy link
Copy Markdown

@superagent-security superagent-security Bot left a comment

Choose a reason for hiding this comment

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

Superagent found 1 security concern(s).

Comment thread scripts/check-mcp-release-candidate.mjs
@superagent-security superagent-security Bot removed the pr:flagged PR flagged for review by security analysis. label Jun 4, 2026
Copy link
Copy Markdown
Owner

@JSONbored JSONbored left a comment

Choose a reason for hiding this comment

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

@web-dev0521 this is mergeable.

A few notes:

  • The workflow is manual and read-oriented, which is the right shape for a release-candidate dry run.
  • The added checks improve release confidence without adding expensive PR-path CI.
  • No code changes requested.

Validation expected:

  • Keep the current green CI run.

@dosubot dosubot Bot added the lgtm This PR has been approved by a maintainer label Jun 4, 2026
@JSONbored JSONbored merged commit 37d2d82 into JSONbored:main Jun 4, 2026
4 checks passed
@github-project-automation github-project-automation Bot moved this from Todo to Done in gittensory - v1 roadmap Jun 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lgtm This PR has been approved by a maintainer size:L This PR changes 100-499 lines, ignoring generated files.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

ci(release): add MCP release candidate dry-run workflow

2 participants