Skip to content

Commit 79685bd

Browse files
khaliqgantclaude
andauthored
docs: add release runbook covering the next dist-tag two-step (#355)
Promoting an RC to stable strands `next` on the superseded RC, so `@next` resolves older than `@latest`. `npm dist-tag add` would fix it, but publish.yml authenticates via OIDC trusted publishing and npm's OIDC covers only `npm publish` — dist-tag needs a traditional token this repo deliberately does not hold (npm/cli#8547). Documents the workaround (a second dispatch publishing a version forward onto `next`), its cost, and the GitHub "Latest" release realignment that run leaves behind. Also flags ci-cd-design.md as design intent: it names publish-npm.yml and an npm token setup, neither of which matches what ships. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 914aba6 commit 79685bd

2 files changed

Lines changed: 95 additions & 0 deletions

File tree

docs/ci-cd-design.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# RelayFile CI/CD Pipeline Design
22

3+
> **Design intent, not current state.** Some of this has drifted from what ships
4+
> — publishing lives in `publish.yml` (not `publish-npm.yml`) and authenticates
5+
> with OIDC trusted publishing rather than the npm token described below. For
6+
> the steps to actually cut a release, see [`releasing.md`](./releasing.md).
7+
38
## Overview
49

510
Four GitHub Actions workflows covering continuous integration, SDK publishing, binary releases, and Cloudflare Workers deployment. Designed to match the proven patterns from the relaycast project.

docs/releasing.md

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# Releasing relayfile
2+
3+
Operational runbook for cutting a release. For the pipeline's design intent, see
4+
[`ci-cd-design.md`](./ci-cd-design.md).
5+
6+
## Cutting a release
7+
8+
`publish.yml` (`workflow_dispatch`) is the only supported way to publish. One run
9+
version-bumps every package, publishes them, commits `chore(release): vX.Y.Z`,
10+
and creates the GitHub release.
11+
12+
```bash
13+
gh workflow run publish.yml --ref main \
14+
-f package=all -f version=patch -f tag=latest -f dry_run=false
15+
```
16+
17+
| Input | Notes |
18+
| --- | --- |
19+
| `package` | Must be `all` for a real publish. The workflow hard-fails otherwise: it rewrites every manifest, and lockfile regeneration needs every `@relayfile/mount-*` package already published at the new version so npm can resolve tarball integrity metadata. |
20+
| `version` | `patch` / `minor` / `major`, or `prerelease` with `preid=rc` for a release candidate. |
21+
| `tag` | `latest` for stable, `next` for prereleases. |
22+
23+
The bump is computed from the root `package.json` **on the ref you dispatch
24+
from**, so check it before dispatching. Note `patch` on a prerelease drops the
25+
prerelease rather than bumping the patch digit: `0.10.27-rc.0``0.10.27`.
26+
27+
## Promoting an RC, and the `next` tag
28+
29+
**Promoting an RC to stable strands the `next` tag.** `next` keeps pointing at
30+
the RC you just superseded, so `@next` resolves *older* than `@latest`:
31+
32+
```
33+
latest: 0.10.27
34+
next: 0.10.27-rc.0 # older than latest — anyone on @next is behind
35+
```
36+
37+
`npm dist-tag add relayfile@0.10.27 next` would fix this in one command, but it
38+
**cannot run in this repo's CI**. `publish.yml` authenticates with npm OIDC
39+
trusted publishing, and npm's OIDC covers only `npm publish` / `npm stage
40+
publish` — every other command, `dist-tag` included, still needs a traditional
41+
token ([npm/cli#8547](https://github.com/npm/cli/issues/8547)). This repo holds
42+
no npm token secret by design, so there is nothing for `dist-tag` to
43+
authenticate with.
44+
45+
The fix is a second dispatch that publishes a new version *forward* onto `next`
46+
`npm publish` is the one command OIDC does cover:
47+
48+
```bash
49+
gh workflow run publish.yml --ref main \
50+
-f package=all -f version=patch -f tag=next -f dry_run=false
51+
```
52+
53+
```
54+
latest: 0.10.27 # stable, unchanged
55+
next: 0.10.28 # newer than latest
56+
```
57+
58+
Run this after **every** RC → stable promotion, or `next` stays stranded until
59+
the next RC.
60+
61+
The trade-off: this publishes a version whose content is identical to the stable
62+
release, so version numbers advance faster than shipped changes. That is the
63+
cost of not holding a long-lived npm token. The alternative is a granular npm
64+
token scoped to `relayfile` + `@relayfile/*`, which would allow a single
65+
`dist-tag` step instead — a deliberate security trade, not an oversight.
66+
67+
## After the release
68+
69+
Verify against the registry rather than the workflow log — a green run does not
70+
prove the tags are right:
71+
72+
```bash
73+
npm view relayfile dist-tags
74+
npm view @relayfile/client dist-tags
75+
```
76+
77+
The `next` dispatch creates its own GitHub release and GitHub marks the newest
78+
tag "Latest", even though npm's `latest` is the stable version. Realign so the
79+
releases page matches the registry:
80+
81+
```bash
82+
gh release edit v0.10.27 --latest # the stable version, not the next-tag one
83+
```
84+
85+
## Consumers
86+
87+
Downstream `^x.y.z` ranges resolve by semver across **all** published versions —
88+
dist-tags do not gate them. A version published only to `next` will still
89+
satisfy a caret range in a consumer's manifest on any lockfile refresh. Committed
90+
lockfiles pin exact versions, so `npm ci` is unaffected.

0 commit comments

Comments
 (0)