Skip to content

Release from the registry's count, so nothing has to be pushed to main - #18

Merged
pablo-tech merged 1 commit into
devfrom
fix/release-without-pushing-main
Oct 24, 2026
Merged

pablo-tech merged 1 commit into
devfrom
fix/release-without-pushing-main

Conversation

@pablo-tech

Copy link
Copy Markdown
Contributor

What was wrong

The release job bumped packages/frame/package.json and pushed that commit straight to main. Since lexi went public on 2026-10-18, protect-main (ruleset 25357904) refuses it — every landing is a pull request and bypass_actors is empty. The first promote after that date was pull request #17, merged today, and its release job died at step 4:

remote: error: GH013: Repository rule violations found for refs/heads/main.
remote: - Changes must be made through a pull request.
 ! [remote rejected] HEAD -> main (push declined due to repository rule violations)

Publish to npm and Create GitHub release were skipped. @tinytars/frame is still 0.1.53. Nothing about rescheduling or re-running helps: the branch is the obstacle, and it would refuse every future promote the same way.

Production was unaffected — package-lock.json resolves @tinytars/frame to packages/frame with link: true, so LexiTar builds against the workspace copy and the registry version has no consumer in this repository.

What changes

The registry is the counter. The next version is the patch above the highest of the committed floor and everything npm already holds. npm cannot take a version back, which makes it the one record that cannot drift — and asking it means nothing has to be written to the branch at all.

The committed number stays put, as a floor rather than a counter. apps/lexitar asks for ^0.1.5 and the lockfile resolves that to packages/frame itself, so the number only has to keep satisfying that range for the workspace link to hold. One consequence is deliberate: a tag names the commit a version shipped from while that commit's tree still declares the previous number. The alternative is a person merging a pull request for every patch release, and provenance already binds each tarball to its exact commit and run.

Publishing now precedes tagging. The old order left frame-v0.1.54 through v0.1.57, cut 6–8 October, naming versions npm never received. The surviving log from the archived repository (run 37541771501) says why:

npm error code E422
npm error 422 Unprocessable Entity - PUT https://registry.npmjs.org/@tinytars%2fframe -
  Error verifying sigstore provenance bundle: Unsupported GitHub Actions source repository
  visibility: "private". Only public source repositories are supported when publishing with provenance.

lexi was private for the re-key, so the tag pushed and the publish then failed. That fault is gone — the repository has been public since 2026-10-18 — but the ordering is what stops a repeat leaving tags for packages that do not exist.

Rejected alternative

Adding github-actions to protect-main's bypass_actors. One API call, and it reopens unreviewed direct pushes to the branch whose protection was only made real six days ago, to buy back a mechanical commit nobody reads.

secrets.RELEASE_PAT is kept on the checkout deliberately. The job now only needs to push a tag, which the job token's contents: write would cover, but this job can only be exercised by a merge to main — so swapping the credential in the same change would put an untestable variable into the one thing being fixed. Worth doing next, on its own.

Verified

  • The workflow parses, and release is the only one of the nine jobs whose definition differs.
  • The release job contains no git commit, no git add and no push to a branch; its single git push carries the tag.
  • Neither ruleset targets a tag — protect-main and protect-dev are both branch rulesets, on ~DEFAULT_BRANCH and dev.
  • node --check passes on the embedded version script.
  • Run against the live registry, the step computes 0.1.58 from a 0.1.57 floor and a 0.1.53 registry, and 0.1.59 once 0.1.58 lands — monotonic, with the committed file never moving.

The job's if: gates on refs/heads/main, so it cannot run on this pull request or on dev. The first real exercise is the next promote.

🤖 Generated with Claude Code

The release job bumped packages/frame/package.json and pushed that commit
straight to `main`. Since 18 October `protect-main` refuses it - every landing
is a pull request and the bypass list is empty - so the first promote after
that, pull request #17 today, died at the push with GH013 and published
nothing. Rescheduling or re-running cannot help: the branch is the obstacle.

So stop writing to the branch. The next version is now the patch above the
highest of the committed floor and everything npm already holds, which makes
the registry the counter - and npm cannot take a version back, so it is the one
record that cannot drift. The committed number stays put as a floor: apps/lexitar
asks for ^0.1.5 and package-lock.json resolves that to packages/frame itself, so
it only has to keep satisfying that range for the workspace link to hold. A tag
therefore names the commit a version shipped from while that commit's tree still
declares the previous number; the alternative is a person merging a pull request
for every patch, and provenance already binds each tarball to its exact commit
and run.

Publishing now precedes tagging. The old order left frame-v0.1.54 through
v0.1.57, cut 6-8 October, naming versions npm never received: `--provenance`
refuses a private source repository and lexi was private for the re-key, so the
tag was pushed and the publish then failed with E422. Those tags went with the
republish, and the ordering is what stops the next set.

Verified: the workflow parses and `release` is the only job that differs; the
job contains no `git commit`, no `git add` and no push to a branch, and its one
`git push` carries the tag; neither ruleset targets a tag, both being branch
rulesets on main and dev. Run against the live registry, the step computes
0.1.58 from a 0.1.57 floor and a 0.1.53 registry, and 0.1.59 once 0.1.58 lands.

Signed-off-by: Pablo Rodriguez <contact@promontory.studio>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@pablo-tech
pablo-tech enabled auto-merge October 24, 2026 10:03
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying health-dash-main with  Cloudflare Pages  Cloudflare Pages

Latest commit: e1dd4b6
Status: ✅  Deploy successful!
Preview URL: https://f141488a.health-dash-prod.pages.dev
Branch Preview URL: https://fix-release-without-pushing.health-dash-prod.pages.dev

View logs

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying health-dash-dev with  Cloudflare Pages  Cloudflare Pages

Latest commit: e1dd4b6
Status: ✅  Deploy successful!
Preview URL: https://e5748da2.health-dash-aex.pages.dev
Branch Preview URL: https://fix-release-without-pushing.health-dash-aex.pages.dev

View logs

@pablo-tech
pablo-tech merged commit 47cbb4d into dev Oct 24, 2026
17 checks passed
@pablo-tech
pablo-tech deleted the fix/release-without-pushing-main branch October 24, 2026 10:18
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.

1 participant