Skip to content

ci: arm publishing for @cipherstash/auth and the stack-* crates - #1009

Draft
auxesis wants to merge 4 commits into
ci/stack-crates-release-pipelinesfrom
ci/arm-stack-crates-publishing
Draft

auxesis wants to merge 4 commits into
ci/stack-crates-release-pipelinesfrom
ci/arm-stack-crates-publishing

Conversation

@auxesis

@auxesis auxesis commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

This PR switches publishing on for @cipherstash/auth and its six platform packages on npm, and for the stack-auth and stack-profile crates on crates.io. The title calls this "arming". Each platform package holds the native binary for one platform, such as darwin-arm64.

Until now, the release gate has blocked any new version of the seven auth packages. The release gate, scripts/release-gate.mjs, runs on every push to main before anything publishes to npm. This PR removes the block, which also switches on the crates release job that PR D added.

This is PR E of 6 in the stack crates import. The import moves six Rust crates, their bindings and the Go module here from the private cipherstash/cipherstash-suite repository, with their history. The stack crates import plan in Linear lists every step, and Linear issue CIP-4274 tracks the work.

This PR is stacked on PR D, #1002. Its base branch is PR D's branch, so the diff shows only this PR's own changes. It stays a draft until the freeze on Friday 2 October 2026, Pacific time. The freeze is the window in which the six PRs merge in order: #1000, #1001, #1003, #1002, #1009, then #1010. The steps for that day are in §9.1 of the plan.

Read the four commits in order, and skim the copied changesets

Read commits 1, 2 and 4 in full. Commit 3 copies six files from the suite byte for byte, so you can skim it. In commit 4, the pnpm-lock.yaml changes touch only the @cipherstash/auth entries.

Each commit makes one change

  1. 66437857 removes the seven @cipherstash/auth entries from the release gate's two freeze lists, FROZEN_PUBLISHERS and FROZEN_ARTEFACT_DIGESTS. The gate fails if a package on those lists would publish a new version. Both lists end empty, as they are on main. The commit also removes the temporary lint-no-auth-changeset check that PR B added.
  2. 0efb59e3 ports the suite's check that a change to what @cipherstash/auth ships comes with a changeset. A changeset is a file in .changeset/ that says which packages a change releases, and how far each version moves. The check, require-auth-npm-changeset.yml, runs on pull requests only.
  3. e766c9a8 copies the suite's six pending @cipherstash/auth changesets, byte for byte. The suite history that PR B imports leaves .changeset/ out, so without this commit they would be lost. Each one is a patch, so the first auth release from this repository takes the seven packages to 0.44.1.
  4. 931f359d makes @cipherstash/stack, stash, @cipherstash/wizard and the protect-ffi integration tests take @cipherstash/auth from this repository instead of npm. The copy in this repository has no built binary. So a new action, build-auth-binding, builds the native binding in every CI job that loads it. Without that build, 26, 16 and 2 test files fail in @cipherstash/stack, stash and @cipherstash/wizard. A guard test keeps every build-ffi-binding call paired with a build-auth-binding call.

Merge only after PR D is on main and auth-preflight has passed

This PR must not merge before the freeze steps that come before it:

  1. PR D, ci: add the release pipelines for the stack-* crates and @cipherstash/auth, inert #1002, is on main.
  2. Someone has started auth-preflight.yml by hand, and it passed. That dry run builds all seven auth packages without publishing them. GitHub can start a workflow by hand only once it is on main, so this step waits for PR D.

Trusted publishing is already in place. It lets a registry accept a publish from a named GitHub workflow, with no stored token. On npm, all seven auth packages trust cipherstash/stack. On crates.io, stack-auth and stack-profile trust it too.

Merge this PR with a merge commit, which keeps every commit, and never with a squash or a rebase. The crates release, #1010, is built on these exact commits.

Watch the release-plz run that this merge starts

Merging runs release-plz.yml, because this PR edits that file. release-plz is the tool that publishes the Rust crates to crates.io. Its release-crates job should find version 0.42.3 already published, and publish nothing. Watch that run.

The checks pass locally and in CI

  • pnpm test:scripts passes 1,142 tests.
  • A mutation is a deliberate break in the new code, made to prove that a test notices. All 20 of 20 mutations make a test fail.
  • A test version bump of @cipherstash/auth now passes the release gate, which reports auth=true. On PR D, the same bump makes the gate fail.
  • CI: 27 checks pass and 11 are skipped.

🤖 Generated with Claude Code

https://claude.ai/code/session_01PaY5xYydZUWhv8Nex9Sw8a

@changeset-bot

changeset-bot Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: dfa43c2

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 19 packages
Name Type
@cipherstash/auth Patch
stash Patch
@cipherstash/stack Patch
@cipherstash/wizard Patch
@cipherstash/ffi-integration-tests Patch
@cipherstash/basic-example Patch
@cipherstash/e2e Patch
@cipherstash/bench Patch
@cipherstash/stack-drizzle Patch
@cipherstash/stack-prisma Patch
@cipherstash/stack-supabase Patch
@cipherstash/test-kit Patch
@cipherstash/prisma-example Patch
@cipherstash/auth-darwin-arm64 Patch
@cipherstash/auth-darwin-x64 Patch
@cipherstash/auth-linux-arm64-gnu Patch
@cipherstash/auth-linux-x64-gnu Patch
@cipherstash/auth-linux-x64-musl Patch
@cipherstash/auth-win32-x64-msvc Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@auxesis
auxesis force-pushed the ci/stack-crates-release-pipelines branch from d669946 to db6b3b9 Compare October 2, 2026 08:07
@auxesis
auxesis force-pushed the ci/arm-stack-crates-publishing branch from e78e71d to dfa43c2 Compare October 2, 2026 08:07
auxesis and others added 4 commits October 2, 2026 18:16
Delete the seven @cipherstash/auth entries from FROZEN_PUBLISHERS and
FROZEN_ARTEFACT_DIGESTS. This arms release.yml's auth-artifacts and
publish-auth jobs, which run when the gate reports auth=true, and
release-plz.yml's release-crates job, whose switch keys on the
@cipherstash/auth entry. It assumes npm and crates.io trusted publishing
for the seven packages and the two crates now name cipherstash/stack.

Remove the temporary lint-no-auth-changeset guard, its test, its
lint:auth-changeset script and its tests.yml step, as its header asked.
Its check that the changesets fixed group is exactly the seven auth
workspace packages moves to auth-build-artifacts.test.mjs, so the
lockstep stays covered.

The gate keeps its `files` and `noTreeBytes` entry shapes. Their tests
use the entries the auth packages carried as fixtures. New tests assert
that no auth package is frozen, that an unpublished auth version passes
the gate with auth=true, and that the crates line is armed.
frozen-publisher-docs.test.mjs keeps its auth rows, with the wording
each instruction was written for, so an assertion of absence can still
fail. AGENTS.md, SECURITY.md, CONTRIBUTING.md and the workflow comments
no longer describe the freeze, and docs/npm-releases.md is marked as
the suite's history.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PaY5xYydZUWhv8Nex9Sw8a
Port require-auth-npm-changeset.yml from cipherstash-suite, with its
paths renamed: packages/stack-auth's manifest and src/, and the auth and
stack-auth-wasm binding folders. The job diffs the pull request against
its base and passes the added or modified changesets to
scripts/check-auth-npm-changeset.mjs, which fails unless one releases
@cipherstash/auth with a patch, minor or major bump.

The script imports @changesets/parse, which pnpm does not expose to the
root as a dependency of @changesets/cli, so the root declares it at the
0.4.3 already in the lock and the job installs only the root. The script
now skips .changeset/README.md, which the job's pathspec matches, and
names `pnpm changeset`. The suite's release-plz exemption is dropped:
nothing here opens a release-plz pull request.

check-auth-npm-changeset.test.mjs drives the script and holds the job's
pathspec and its paths filter to the same set. The workflow has only a
pull_request trigger, which workflow-paths-filter-parity now records.
AGENTS.md and CONTRIBUTING.md describe the rule, and note that a crates
release trips it: stack-auth sends its own version in its user-agent.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PaY5xYydZUWhv8Nex9Sw8a
Copy the six changesets pending on cipherstash-suite main (f161a447f,
the commit the import exported) into .changeset/, byte for byte. Each is
a patch for @cipherstash/auth; the fixed group takes the six platform
packages with it, to 0.44.1. The suite's last release PR closed without
merging and the export left .changeset/ out, so the first auth release
from this repository carries them.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PaY5xYydZUWhv8Nex9Sw8a
stack, stash, @cipherstash/wizard and the protect-ffi integration suite
move the wrapper and the six platform packages from `catalog:repo` to
`workspace:*`. The seven catalog entries, the two
minimumReleaseAgeExclude entries and the two npm Dependabot ignores are
dead config and go. The lock changes only the auth importers and
entries, and `pnpm pack` still writes each range as the exact version.

A workspace @cipherstash/auth ships source only, and its index.js loads
the napi module on import, so every CI job that imports the SDK or runs
the CLI now builds it: without a build, the stack, stash and wizard
suites fail 26, 16 and 2 files with `Failed to load native binding`.
.github/actions/build-auth-binding runs build:debug, and build:wasm with
`wasm: 'true'`, then checks both load. It runs after each of the ten
build-ffi-binding calls, with wasm where that call has it, and in
tests-bench.yml, whose unit checks import the SDK and whose globalSetup
runs `stash`. In tests.yml's run-tests it replaces the auth half of the
binding build step. auth-binding-step-order.test.mjs holds the pairing
and the filters.

Every workflow that uses the action filters on it. The three
integration workflows that saw auth bumps through pnpm-workspace.yaml
now filter on the paths require-auth-npm-changeset.yml treats as what
@cipherstash/auth ships.

supply-chain.e2e.test.ts keeps the lockstep invariant in its new shape:
no auth catalog entry, and `workspace:*` in every consumer.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PaY5xYydZUWhv8Nex9Sw8a

@yujiyokoo yujiyokoo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM

Reviewed with GPT-6-Luna medium

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants