Skip to content

ops: immutable client releases, main-only release builds, SHA-pinned actions - #196

Merged
scrimshawlife-ctrl merged 1 commit into
mainfrom
ops/workflow-hardening
Oct 25, 2026
Merged

scrimshawlife-ctrl merged 1 commit into
mainfrom
ops/workflow-hardening

Conversation

@scrimshawlife-ctrl

Copy link
Copy Markdown
Contributor

Fixes three findings from the independent review of PRs #182 to #194. Workflows, MCP packaging in the release job, the MCP README, and docs/RUNBOOK.md only. No spec version bump.

A. Release files can be replaced; the MCP tarball's client dependency was unchecked

  • gh release upload --clobber is gone. If the release for the tag already has files, the release job fails with "Releases are immutable ... bump the client version and push a new clients-v tag". A release opened by hand with no files still gets them attached (without --clobber).
  • The Python wheel and sdist are built with SOURCE_DATE_EPOCH set to the tagged commit's time. npm pack already writes a fixed mtime on every entry, so it needs none. The TypeScript and Python jobs now build twice and cmp the results, so reproducibility is checked on every run.
  • The release MCP tarball bundles @zero-state/jchain (bundleDependencies, with the dependency pinned to the exact version). Only the runner's copy of clients/mcp/package.json and node_modules changes; the repo's dev setup (link to ../typescript) is untouched, so npm ci and clients-ts are unaffected. The job checks the tarball contains the client, installs it alone in a scratch dir, checks the lockfile has no releases/download URL and marks the client inBundle, and imports the server. A new assets job checks the bundled copy is byte for byte the released client tarball, writes SHA256SUMS and the notes, and emits a Release asset notice per file (name, size, SHA-256). It runs on manual dispatch too.
  • MCP README and the release notes now install the one MCP file.

B. A release could be built from any commit

  • The versions job checks out with fetch-depth: 0, fetches main, and fails a tag push unless git merge-base --is-ancestor "$GITHUB_SHA" origin/main. A manual run on a branch only gets a notice, since it publishes nothing.
  • RUNBOOK gains a Client releases section that recommends a clients-v* tag ruleset (Danny's to set).

C. Actions were pinned to major tags

Every uses: across the ten workflows is pinned to a full commit SHA with a # vX.Y.Z comment, the latest release within the major already in use (majors unchanged). The SHAs come from GitHub's tag refs (git ls-remote --tags; annotated tags taken from their peeled ^{} commit). Each one matches the moving major tag.

Action Version SHA
actions/checkout v7.0.1 3d3c42e5aac5ba805825da76410c181273ba90b1
actions/checkout v4.4.0 11d5960a326750d5838078e36cf38b85af677262
actions/setup-node v4.4.0 49933ea5288caeca8642d1e84afbd3f7d6820020
actions/upload-artifact v4.6.2 ea165f8d65b6e75b540449e92b4886f43607fa02
actions/download-artifact v4.3.0 d3f86a106a0bac45b974a628896c90dbdf5c8093
actions/setup-python v5.6.0 a26af69be951a213d495a4c3e4e4022e16d87065
DavidAnson/markdownlint-cli2-action v24.2.0 21c1be1b93ad9ed58fa840aacc3f279cde2a72ff
lycheeverse/lychee-action v2.9.0 e7477775783ea5526144ba13e8db5eec57747ce8

.github/dependabot.yml adds the github-actions ecosystem, weekly, grouped into one PR.

For Danny

  • Add a repository tag ruleset on clients-v* (restrict create, update, delete).

Generated by Claude Code

…actions

- release-clients: no --clobber; a release that already has files fails
  with a clear message. Python builds stamped with SOURCE_DATE_EPOCH from
  the tagged commit; TypeScript and Python jobs build twice and compare.
- The release MCP tarball bundles @zero-state/jchain (bundleDependencies)
  in the runner's copy only; the job checks it installs alone and the
  bundled copy matches the released client tarball. MCP README and the
  release notes now install the one file.
- versions job fails a clients-v tag whose commit is not on main.
- Every third-party action pinned to a commit SHA with a version comment;
  dependabot keeps them current weekly.
- RUNBOOK: client release rules and a recommended clients-v* tag ruleset.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L8SjVSu8au2USqFDpkD1Li
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ⚠️ Failed 2026-10-25T03:44:02.613416Z
We couldn’t complete this review. Comment @codex review to try again.
31c03c5 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@scrimshawlife-ctrl
scrimshawlife-ctrl merged commit 88c2050 into main Oct 25, 2026
12 checks passed
@scrimshawlife-ctrl
scrimshawlife-ctrl deleted the ops/workflow-hardening branch October 25, 2026 03:47
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.

2 participants