Skip to content

Commit c956780

Browse files
committed
build: migrate from npm to pnpm — match the rest of the plugin ecosystem
Other ether/* plugins (ep_font_color, ep_align, ep_syntax_highlighting, …) all use pnpm in their CI; this repo was the odd one out on npm ci / npm test. Switching to keep tooling consistent and to share the pnpm-store cache across plugin CI runs. Changes: - test-and-release.yml: pnpm/action-setup + pnpm install --frozen-lockfile + pnpm test, with the standard pnpm-store cache step. - npmpublish.yml: replaced with the canonical ep_font_color version that uses pnpm for install/test and 'npm publish' only for the OIDC-trusted publish step (OIDC requires npm CLI >= 11.5.1; pnpm publish shells out ambiguously). Bumps patch in Node rather than 'npm version patch' to sidestep pnpm/action-setup#225. - Replaced package-lock.json with pnpm-lock.yaml. 88 tests pass with the new toolchain.
1 parent 5da28b7 commit c956780

4 files changed

Lines changed: 3546 additions & 6283 deletions

File tree

.github/workflows/npmpublish.yml

Lines changed: 96 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
# This workflow will run tests using node and then publish a package to the npm registry when a release is created
2+
# For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages
3+
#
4+
# Publishing uses npm Trusted Publishing (OIDC) — no NPM_TOKEN secret is
5+
# required. Each package must have a trusted publisher configured on npmjs.com
6+
# pointing at this workflow file. See:
7+
# https://docs.npmjs.com/trusted-publishers
8+
19
name: Node.js Package
210

311
on:
@@ -7,40 +15,107 @@ jobs:
715
publish-npm:
816
runs-on: ubuntu-latest
917
permissions:
10-
contents: write
11-
id-token: write
18+
contents: write # for the atomic version-bump push (branch + tag)
19+
id-token: write # for npm OIDC trusted publishing
1220
steps:
1321
- uses: actions/setup-node@v6
1422
with:
23+
# OIDC trusted publishing needs npm >= 11.5.1, which requires
24+
# Node >= 20.17.0. setup-node's `20` resolves to the latest
25+
# 20.x, which satisfies that.
1526
node-version: 20
1627
registry-url: https://registry.npmjs.org/
1728
- name: Upgrade npm to >=11.5.1 (required for trusted publishing)
1829
run: npm install -g npm@latest
19-
- uses: actions/checkout@v6
30+
- name: Check out Etherpad core
31+
uses: actions/checkout@v6
32+
with:
33+
repository: ether/etherpad-lite
34+
- uses: pnpm/action-setup@v6
35+
name: Install pnpm
36+
with:
37+
version: 10
38+
run_install: false
39+
- name: Get pnpm store directory
40+
shell: bash
41+
run: |
42+
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
43+
- uses: actions/cache@v5
44+
name: Setup pnpm cache
45+
with:
46+
path: ${{ env.STORE_PATH }}
47+
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
48+
restore-keys: |
49+
${{ runner.os }}-pnpm-store-
50+
-
51+
uses: actions/checkout@v6
2052
with:
2153
fetch-depth: 0
22-
- run: npm ci
23-
- run: npm test
24-
- name: Bump version (patch)
54+
-
55+
name: Bump version (patch)
56+
id: bump
2557
run: |
2658
LATEST_TAG=$(git describe --tags --abbrev=0) || exit 1
2759
NEW_COMMITS=$(git rev-list --count "${LATEST_TAG}"..) || exit 1
28-
[ "${NEW_COMMITS}" -gt 0 ] || exit 0
60+
# No new commits since the last tag → nothing to publish.
61+
# Setting `bumped=false` lets the publish step below skip
62+
# itself instead of trying to republish the existing version
63+
# (which fails with "cannot publish over previously published
64+
# versions"). Only manual `gh workflow run` invocations on a
65+
# tag-current branch hit this path; on:push always sees ≥1
66+
# new commit because the push event is what triggered us.
67+
if [ "${NEW_COMMITS}" -le 0 ]; then
68+
echo "bumped=false" >> "${GITHUB_OUTPUT}"
69+
exit 0
70+
fi
2971
git config user.name 'github-actions[bot]'
3072
git config user.email '41898282+github-actions[bot]@users.noreply.github.com'
31-
npm version patch
32-
NEW_TAG="v$(node -p "require('./package.json').version")"
33-
# Use --atomic so branch + tag succeed or fail together.
34-
# If a concurrent run already pushed this tag, the push fails
35-
# cleanly and the next run will retry.
73+
pnpm i --frozen-lockfile
74+
# `pnpm version patch` bumps package.json, makes a commit, and creates
75+
# a `v<new-version>` tag. Capture the new tag name from package.json
76+
# rather than parsing pnpm's output, which has historically varied.
77+
# Bump the patch component directly with Node. pnpm/action-setup@v6
78+
# sometimes installs pnpm 11 pre-releases even when version: 10.x is
79+
# requested (pnpm/action-setup#225); those pre-releases either skip
80+
# the git commit/tag or reject --no-git-tag-version as unknown.
81+
# Doing the bump in Node sidesteps both failure modes.
82+
NEW_VERSION=$(node -e "const fs=require('fs');const p=require('./package.json');const v=p.version.split('.');v[2]=String(Number(v[2])+1);p.version=v.join('.');fs.writeFileSync('./package.json',JSON.stringify(p,null,2)+'\n');console.log(p.version);")
83+
NEW_TAG="v${NEW_VERSION}"
84+
git add package.json
85+
git commit -m "${NEW_TAG}"
86+
git tag -a "${NEW_TAG}" -m "${NEW_TAG}"
87+
# CRITICAL: use --atomic so the branch update and the tag update
88+
# succeed (or fail) as a single transaction on the server. The old
89+
# `git push --follow-tags` was non-atomic per ref: if a concurrent
90+
# publish run won the race, the branch fast-forward would be rejected
91+
# but the tag push would still land — leaving a dangling tag with no
92+
# matching commit on the branch. Subsequent runs would then forever
93+
# try to bump to the same already-existing tag and fail with
94+
# `tag 'vN+1' already exists`. With --atomic, a rejected branch push
95+
# rejects the tag push too, and the next workflow tick can retry
96+
# cleanly against the up-to-date refs.
3697
git push --atomic origin "${GITHUB_REF_NAME}" "${NEW_TAG}"
98+
echo "bumped=true" >> "${GITHUB_OUTPUT}"
99+
# This is required if the package has a prepare script that uses something
100+
# in dependencies or devDependencies.
101+
-
102+
if: steps.bump.outputs.bumped == 'true'
103+
run: pnpm i
104+
# `npm publish` must come after `git push` otherwise there is a race
105+
# condition: If two PRs are merged back-to-back then master/main will be
106+
# updated with the commits from the second PR before the first PR's
107+
# workflow has a chance to push the commit generated by `npm version
108+
# patch`. This causes the first PR's `git push` step to fail after the
109+
# package has already been published, which in turn will cause all future
110+
# workflow runs to fail because they will all attempt to use the same
111+
# already-used version number. By running `npm publish` after `git push`,
112+
# back-to-back merges will cause the first merge's workflow to fail but
113+
# the second's will succeed.
114+
#
115+
# Use `npm publish` directly (not `pnpm publish`) because OIDC trusted
116+
# publishing requires npm CLI >= 11.5.1 and `pnpm publish` shells out to
117+
# whichever `npm` is on PATH; calling `npm` directly avoids any shim
118+
# ambiguity.
37119
- name: Publish to npm via OIDC
38-
run: |
39-
# Only publish if the version bump succeeded (tag was pushed)
40-
CURRENT_VERSION=$(node -p "require('./package.json').version")
41-
PUBLISHED=$(npm view ep_plugin_helpers version 2>/dev/null || echo "none")
42-
if [ "${CURRENT_VERSION}" = "${PUBLISHED}" ]; then
43-
echo "Version ${CURRENT_VERSION} already published, skipping"
44-
exit 0
45-
fi
46-
npm publish --provenance --access public
120+
if: steps.bump.outputs.bumped == 'true'
121+
run: npm publish --provenance --access public

.github/workflows/test-and-release.yml

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,21 @@ jobs:
1313
- uses: actions/setup-node@v6
1414
with:
1515
node-version: 20
16-
- run: npm ci
17-
- run: npm test
16+
- uses: pnpm/action-setup@v6
17+
with:
18+
version: 10
19+
run_install: false
20+
- name: Get pnpm store directory
21+
shell: bash
22+
run: echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
23+
- uses: actions/cache@v5
24+
with:
25+
path: ${{ env.STORE_PATH }}
26+
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
27+
restore-keys: |
28+
${{ runner.os }}-pnpm-store-
29+
- run: pnpm install --frozen-lockfile
30+
- run: pnpm test
1831
release:
1932
if: ${{ github.ref == 'refs/heads/main' }}
2033
needs: test

0 commit comments

Comments
 (0)