Skip to content

Commit 08a26cb

Browse files
author
Sergiu Oala
committed
fix: npm publish workflow
1 parent fca987f commit 08a26cb

3 files changed

Lines changed: 102 additions & 13 deletions

File tree

.github/workflows/npm-publish.yml

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
name: npm-publish
2+
3+
on:
4+
release:
5+
types: [published]
6+
workflow_dispatch:
7+
8+
permissions:
9+
contents: read
10+
11+
concurrency:
12+
group: npm-publish-${{ github.event.release.tag_name || github.run_id }}
13+
cancel-in-progress: false
14+
15+
jobs:
16+
validate:
17+
name: Validate
18+
runs-on: ubuntu-latest
19+
steps:
20+
- uses: actions/checkout@v7
21+
with:
22+
ref: ${{ github.event.release.tag_name || github.ref }}
23+
persist-credentials: false
24+
25+
- uses: actions/setup-node@v6
26+
with:
27+
node-version: 26.x
28+
cache: npm
29+
30+
- name: verify release version
31+
if: github.event_name == 'release'
32+
run: |
33+
pkg_name=$(jq -r .name package.json)
34+
pkg_version=$(jq -r .version package.json)
35+
tag_version="${GITHUB_EVENT_RELEASE_TAG_NAME#v}"
36+
if [ "$pkg_version" != "$tag_version" ]; then
37+
echo "package.json version ($pkg_version) does not match release tag ($tag_version)"
38+
exit 1
39+
fi
40+
if npm view "${pkg_name}@${pkg_version}" version >/dev/null 2>&1; then
41+
echo "${pkg_name}@${pkg_version} is already published"
42+
exit 1
43+
fi
44+
env:
45+
GITHUB_EVENT_RELEASE_TAG_NAME: ${{ github.event.release.tag_name }}
46+
47+
- name: install dependencies
48+
run: npm ci
49+
50+
- name: run tests
51+
run: make test
52+
env:
53+
TEST_SKIP_IP_V6: true
54+
55+
- name: validate publish package contents
56+
run: |
57+
npm pack --dry-run 2>&1 | tee pack.log
58+
grep -q 'lib/index.js' pack.log
59+
grep -q 'bin/report-latency' pack.log
60+
! grep -qE '[[:space:]]test/' pack.log
61+
! grep -qE '[[:space:]]tools/' pack.log
62+
63+
publish:
64+
name: publish
65+
needs: validate
66+
if: github.event_name == 'release'
67+
runs-on: ubuntu-latest
68+
environment: Publish
69+
permissions:
70+
contents: read
71+
id-token: write
72+
steps:
73+
- uses: actions/checkout@v7
74+
with:
75+
ref: ${{ github.event.release.tag_name }}
76+
persist-credentials: false
77+
78+
- uses: actions/setup-node@v6
79+
with:
80+
node-version: 26.x
81+
registry-url: https://registry.npmjs.org
82+
83+
- name: publish to npm
84+
run: npm publish --provenance

CONTRIBUTING.md

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -50,16 +50,21 @@ make benchmark
5050

5151
## Cutting a release
5252

53-
Cutting a release is currently a manual process. We use a [Conventional Changelog](http://conventionalcommits.org/) to simplify the process of managing semver on this project. Generally, the following series of commands will cut a release from the `master` branch:
53+
Releases are automated with [release-please](https://github.com/googleapis/release-please) and published to npm via GitHub Actions. We use [Conventional Commits](http://conventionalcommits.org/) to simplify the process of managing semver on this project — release-please parses commit types (`fix`, `feat`, etc.) to determine the version bump.
5454

55-
```
56-
$ git fetch
57-
$ git pull origin master # ensure you have the latest changes
58-
$ npx unleash [-p for patch, -m for minor, -M for major] --no-publish -d # do a dry run to verify
59-
$ npx unleash [-p for patch, -m for minor, -M for major] --no-publish
60-
# Unleash doesnt support 2FA, hence we use --no-publish flag here.
61-
# This ensures we have the package.json updated, changelog generated, tag created
62-
# and all the changes into origin
63-
# Next, publish to npm manually and do not forget to provide the 2FA code.
64-
$ npm publish
65-
```
55+
### Release flow
56+
57+
1. Merge pull requests to `master` using [Conventional Commits](http://conventionalcommits.org/).
58+
2. `release-please` opens or updates a **Release PR** with the version bump and changelog.
59+
3. Review and merge the Release PR when ready to ship.
60+
4. `release-please` creates a GitHub Release and version tag (for example `v11.3.0`).
61+
5. The `npm-publish` workflow runs automatically, re-runs tests, validates the package contents (`npm pack --dry-run`), then pauses at the `Publish` environment for reviewer approval.
62+
6. After approval, the package is published to npm via [Trusted Publishing](https://docs.npmjs.com/trusted-publishers) (OIDC). Do not run `npm publish` manually.
63+
64+
### Dry run
65+
66+
To validate the publish workflow without publishing, run **Actions → npm-publish → Run workflow**. This runs tests and `npm pack --dry-run`.
67+
68+
### Retrying a failed run
69+
70+
If `npm-publish` fails, use **Re-run jobs** on the failed run itself (Actions tab) — it replays the same release/tag, so there's no need to cut a new one. This is safe even if `publish` partially ran, since `validate` checks whether the version is already on npm before continuing.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@
7777
"version": "11.2.0",
7878
"repository": {
7979
"type": "git",
80-
"url": "git://github.com/restify/node-restify.git"
80+
"url": "git+https://github.com/restify/node-restify.git"
8181
},
8282
"bugs": {
8383
"url": "https://github.com/restify/node-restify/issues"

0 commit comments

Comments
 (0)