1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# Release publishing — the *publishing* half. `release-please.yml` is the *versioning* half.
#
# Publishes all 43 `geiserx_*` workspace crates to crates.io for a `v{version}` tag, using
# crates.io **trusted publishing** (OIDC — no stored token). Driven by `scripts/publish-crates.sh`
# (leaf-first dependency order, `SKIP_PUBLISHED=1` so a re-run resumes past already-published
# crates, and self-healing through crates.io's sliding-window 429 rate limit — which a 43-crate
# release reliably trips).
#
# Triggers:
# - workflow_dispatch: how `release-please.yml` invokes this after it pushes the tag (a tag pushed
# with GITHUB_TOKEN does NOT fire `on: push: tags` — GitHub's recursion guard — so the release
# flow reaches this job only via that explicit dispatch).
# - push: tags 'v*': for a manually/CLI-pushed tag (a human cutting a release outside release-please).
#
# This is intentionally SEPARATE from ci.yml's upstream-only publish job (which is gated
# `owner == 'tailscale'` and `needs:` self-hosted-runner jobs this fork lacks). This workflow runs on
# a GitHub-hosted runner and stands alone, so it has no dependency on the inherited upstream CI.
name: Release
on:
workflow_dispatch:
push:
tags:
- "v*"
# `id-token: write` is required for crates.io OIDC trusted publishing (rust-lang/crates-io-auth-action).
# `contents: read` is all the publish needs (the tag/release already exist).
permissions:
contents: read
id-token: write
concurrency:
# One publish per tag; never two racing the same crates.io version.
group: release-${{ github.ref }}
cancel-in-progress: false
jobs:
publish-crates:
name: publish 43 crates to crates.io (trusted publishing)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Setup rust
uses: ./.github/actions/setup-rust
with:
toolchain-version: "1.95.0"
builder-triple: x86_64-unknown-linux-gnu
# Mint a short-lived crates.io token via OIDC trusted publishing — no long-lived secret.
- uses: rust-lang/crates-io-auth-action@bbd81622f20ce9e2dd9622e3218b975523e45bbe # v1.0.4
id: auth
- name: Publish workspace to crates.io
env:
# The publish script reads CARGO_REGISTRY_TOKEN; feed it the OIDC-minted token.
CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}
# The script gates real publishes behind this explicit opt-in (guards against accidental runs).
TS_RS_EXPERIMENT: this_is_unstable_software
# Tolerate already-published crates so a re-dispatch after a partial/rate-limited run resumes.
SKIP_PUBLISHED: "1"
run: ./scripts/publish-crates.sh