Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions .github/workflows/publish-cli.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# One-shot bootstrap: the first `termlens-cli` publish (#255).
#
# Every other publish in this repository is crates.io Trusted Publishing —
# release.yml exchanges a job's OIDC token for a short-lived one and no
# secret is stored. That cannot be used here: 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 therefore
# publishes termlens-cli only when crates.io already knows it, and warns
# otherwise.
#
# This workflow closes that gap exactly once, with a token, from a tag. Once
# it has run: link Trusted Publishing for termlens-cli (crates.io →
# termlens-cli → Settings → Trusted Publishing → GitHub, repository
# vyncint/termlens, workflow release.yml, environment release), then revoke
# the token, delete the CARGO_REGISTRY_TOKEN secret and delete this file.
# Every release after that goes through release.yml with no secret at all.
#
# 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.
name: publish-cli (bootstrap)

on:
workflow_dispatch:
inputs:
ref:
description: The tag to publish from. Its version must match the manifest.
required: true
default: v0.10.0
confirm:
description: Type the crate name to confirm this irreversible publish.
required: true
default: ""

permissions:
contents: read

concurrency:
group: publish-cli
cancel-in-progress: false

jobs:
publish:
name: publish termlens-cli
runs-on: ubuntu-latest
steps:
- name: Refuse an unconfirmed dispatch
env:
CONFIRM: ${{ inputs.confirm }}
run: |
if [ "$CONFIRM" != "termlens-cli" ]; then
echo "::error::type 'termlens-cli' in the confirm box; a publish cannot be undone"
exit 1
fi
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
ref: ${{ inputs.ref }}
persist-credentials: false
- uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 # v1
with:
toolchain: stable
# The same guard release.yml puts in front of every publish: the crate
# that goes out must be the version the tag names, or the registry gets
# a number that means nothing.
- name: Compare the ref against the crate version
env:
REF: ${{ inputs.ref }}
run: |
tag="${REF#v}"
version="$(cargo metadata --no-deps --format-version 1 \
| jq -r '.packages[] | select(.name == "termlens-cli") | .version')"
echo "ref=${tag} crate=${version}"
if [ "$tag" != "$version" ]; then
echo "::error::${REF} does not match termlens-cli ${version}"
exit 1
fi
# --locked so the published crate is the tested tree, not whatever the
# index offers today. The verify build resolves `termlens` from
# crates.io rather than the path, which is what a consumer will do.
- run: cargo publish -p termlens-cli --locked
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
11 changes: 11 additions & 0 deletions .github/zizmor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,14 @@ rules:
- release.yml
- install.yml
- windows.yml
- publish-cli.yml

# Correct advice that this one workflow cannot take, which is the whole
# reason it exists. 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 and must use a token. Every other publish here is
# Trusted Publishing (release.yml), and this file is deleted along with the
# secret once crates.io knows termlens-cli.
use-trusted-publishing:
ignore:
- publish-cli.yml