Skip to content

Commit 2340679

Browse files
ejntaylorclaude
andauthored
Fix Release→Publish cascade: dispatch Publish instead of relying on release event (#55)
The Release workflow creates the GitHub release with the built-in GITHUB_TOKEN, and GitHub deliberately does not fire release-triggered workflows for those releases (anti-recursion), so Publish never ran and nothing reached npm. Bridge the two via workflow_dispatch, which is exempt from that rule: Release now dispatches Publish with the computed version, and Publish gains a `version` input that publishes the matching tag (blank input still does a dry-run). The release-event trigger stays for manual, human-created releases. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent f3a220d commit 2340679

3 files changed

Lines changed: 50 additions & 15 deletions

File tree

.github/workflows/publish.yml

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ on:
55
types:
66
- published
77
workflow_dispatch:
8+
inputs:
9+
version:
10+
description: Version to publish (e.g. 0.3.7). Leave blank for a dry-run.
11+
type: string
12+
default: ""
813

914
permissions:
1015
contents: read
@@ -51,21 +56,35 @@ jobs:
5156
run: npm pack --dry-run
5257

5358
- name: Dry-run publish
54-
if: github.event_name == 'workflow_dispatch'
59+
if: github.event_name == 'workflow_dispatch' && inputs.version == ''
5560
run: npm publish --access public --provenance --dry-run
5661

5762
publish:
5863
name: Publish to npm
59-
if: github.event_name == 'release'
64+
if: github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.version != '')
6065
needs: validate
6166
runs-on: ubuntu-latest
6267
environment:
6368
name: npm
6469
url: ${{ steps.version.outputs.url }}
6570

6671
steps:
72+
- name: Resolve version
73+
id: version
74+
run: |
75+
if [ "${{ github.event_name }}" = "release" ]; then
76+
version="${GITHUB_REF_NAME#v}"
77+
else
78+
version="${{ inputs.version }}"
79+
fi
80+
echo "Publishing version $version"
81+
echo "version=$version" >> "$GITHUB_OUTPUT"
82+
echo "url=https://www.npmjs.com/package/@patchstack/connect/v/$version" >> "$GITHUB_OUTPUT"
83+
6784
- name: Checkout
6885
uses: actions/checkout@v4
86+
with:
87+
ref: refs/tags/v${{ steps.version.outputs.version }}
6988

7089
- name: Setup Node
7190
uses: actions/setup-node@v4
@@ -77,13 +96,8 @@ jobs:
7796
- name: Install dependencies
7897
run: npm ci
7998

80-
- name: Set version from release tag
81-
id: version
82-
run: |
83-
version="${GITHUB_REF_NAME#v}"
84-
echo "Publishing version $version (from tag $GITHUB_REF_NAME)"
85-
npm version "$version" --no-git-tag-version --allow-same-version
86-
echo "url=https://www.npmjs.com/package/@patchstack/connect/v/$version" >> "$GITHUB_OUTPUT"
99+
- name: Set package version
100+
run: npm version "${{ steps.version.outputs.version }}" --no-git-tag-version --allow-same-version
87101

88102
- name: Build
89103
run: npm run build

.github/workflows/release.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ on:
1414

1515
permissions:
1616
contents: write
17+
actions: write
1718

1819
concurrency:
1920
group: release
@@ -56,3 +57,9 @@ jobs:
5657
--target "${{ github.sha }}" \
5758
--title "v${{ steps.version.outputs.next }}" \
5859
--generate-notes
60+
61+
- name: Trigger publish
62+
env:
63+
GH_TOKEN: ${{ github.token }}
64+
run: |
65+
gh workflow run publish.yml -f version="${{ steps.version.outputs.next }}"

RELEASING.md

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,10 @@ be bumped before a release.
1313

1414
Run the **`Release`** workflow from the Actions tab (or `gh` below) and pick a
1515
`bump``patch`, `minor`, or `major`. It reads the current `latest` from npm,
16-
computes the next semver version, and cuts the GitHub release + tag on the
17-
current `main`. That release then triggers `Publish`, which validates
18-
(typecheck, test, build, `npm pack`) and publishes to npm with provenance.
16+
computes the next semver version, cuts the GitHub release + tag on the current
17+
`main`, and then dispatches `Publish` for that version. `Publish` validates
18+
(typecheck, test, build, `npm pack`) and publishes to npm with provenance,
19+
recording a deployment to the `npm` environment linked to the published version.
1920

2021
```bash
2122
gh workflow run Release -f bump=patch
@@ -24,21 +25,34 @@ gh workflow run Release -f bump=patch
2425
No version math, no `npm view` lookup, no chance of colliding with an existing
2526
version — the workflow does all of that.
2627

28+
`Release` triggers `Publish` explicitly via `workflow_dispatch` rather than
29+
relying on the release event. This is deliberate: GitHub does **not** fire
30+
`release`-triggered workflows for releases created by the built-in
31+
`GITHUB_TOKEN` (an anti-recursion safeguard), and `workflow_dispatch` is the
32+
one event type that is exempt.
33+
2734
## Manual fallback
2835

29-
You can still cut a release by hand, which triggers `Publish` the same way:
36+
You can still cut a release by hand. Because a human token (not `GITHUB_TOKEN`)
37+
creates it, the release event fires `Publish` on its own:
3038

3139
```bash
3240
gh release create v0.3.3 --generate-notes --title "v0.3.3"
3341
```
3442

3543
or use the GitHub UI (Releases → Draft a new release → new tag `v0.3.3`).
3644

45+
You can also publish an existing tag directly:
46+
47+
```bash
48+
gh workflow run publish.yml -f version=0.3.3
49+
```
50+
3751
## Notes
3852

3953
- Tags must be `vX.Y.Z` (the leading `v` is stripped to get the npm version).
4054
- For a manual release, pick a version higher than the current `latest` on npm
4155
(`npm view @patchstack/connect version`); npm rejects re-publishing an
4256
existing version. The `Release` workflow handles this for you.
43-
- Run the `Publish` workflow via **workflow_dispatch** for a dry-run publish
44-
without cutting a release.
57+
- Run `Publish` via **workflow_dispatch** with a blank `version` for a dry-run
58+
publish without cutting a release.

0 commit comments

Comments
 (0)