Skip to content

ci: a one-shot bootstrap workflow for termlens-cli's first publish - #293

Merged
vyncint merged 1 commit into
mainfrom
bootstrap-cli-publish
Sep 8, 2026
Merged

ci: a one-shot bootstrap workflow for termlens-cli's first publish#293
vyncint merged 1 commit into
mainfrom
bootstrap-cli-publish

Conversation

@vyncint

@vyncint vyncint commented Sep 8, 2026

Copy link
Copy Markdown
Owner

termlens-cli shipped in 0.10.0 but is not on crates.io: Trusted Publishing is configured per crate, on a crate that already exists, so the first publish of a new name has nothing to configure it against. release.yml already knows this — it publishes termlens-cli only when crates.io answers 200 and warns otherwise — which leaves exactly one publish that must happen another way. This is that publish, and nothing else.

Safety, since a publish cannot be undone:

  • dispatch-only, with a typed confirmation (termlens-cli) so a stray click cannot fire it;
  • checks out a tag, not a branch, and re-runs release.yml's tag-matches-version guard;
  • --locked, so what goes out is the tested tree rather than whatever the index offers today;
  • verified locally first — cargo publish -p termlens-cli --locked --dry-run packaged 9 files and its verify build downloaded termlens v0.10.0 from crates.io, i.e. resolved the dependency the way a consumer will, not through the path.

Not wired to the release environment, deliberately: that environment exists so an OIDC token cannot be minted from a branch, and its policy admits only v* refs. CARGO_REGISTRY_TOKEN is a repository secret, so the environment would add no protection here while blocking the dispatch.

zizmor at pedantic flags use-trusted-publishing on this file. It is right, and this is the one workflow that structurally cannot take the advice — recorded in .github/zizmor.yml with that rationale rather than waved through.

Teardown is in the file's header and I'll do it once the publish lands: link Trusted Publishing for termlens-cli, then revoke the token, delete the secret and delete this workflow. Every release after that goes through release.yml with no stored secret, which is the posture docs/RELEASING.md claims.

Refs #255

Trusted Publishing is configured per crate, on a crate that already
exists, so the first publish of a new name has nothing to configure it
against. release.yml knows this — it publishes termlens-cli only once
crates.io answers 200 for it and warns otherwise — which leaves exactly
one publish that has to happen another way.

This is that publish and nothing else: dispatch-only, a typed confirmation
because the action cannot be undone, checkout of a tag rather than a
branch, the same tag-matches-version guard release.yml puts in front of
every publish, and `--locked` so what goes out is the tested tree. Its
verify build resolves `termlens` from crates.io rather than the path,
which is what a consumer does.

Deliberately not wired to the `release` environment. That environment
exists so an OIDC token cannot be minted from a branch and its policy
admits only `v*` refs; CARGO_REGISTRY_TOKEN is a repository secret, so the
environment would add no protection here while blocking the dispatch.

zizmor says at pedantic that this should use Trusted Publishing. It is
right, and it is the one workflow that cannot — recorded in
.github/zizmor.yml with that rationale rather than waved through.

The header carries the teardown: link Trusted Publishing for termlens-cli,
revoke the token, delete the secret, delete this file. Every release after
that goes through release.yml with no secret at all.

Refs #255

Signed-off-by: Vyncint Ng <115854244+vyncint@users.noreply.github.com>
@vyncint
vyncint merged commit a17807e into main Sep 8, 2026
15 checks passed
@vyncint
vyncint deleted the bootstrap-cli-publish branch September 8, 2026 08:19
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