Skip to content

Commit ec14c5e

Browse files
boehlerlukasclaude
andcommitted
ci: test pull requests and publish to npm on version tags
Pushing a tag X.Y.Z checks it against package.json, runs the tests and publishes gleap with npm trusted publishing (OIDC, no stored token), then creates the GitHub release from the CHANGELOG. CI runs tests, build and pack on pull requests. repository.url uses the form trusted publishing matches. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 6a33ec9 commit ec14c5e

4 files changed

Lines changed: 138 additions & 1 deletion

File tree

‎.github/workflows/ci.yml‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: CI
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches: [master]
7+
8+
permissions:
9+
contents: read
10+
11+
concurrency:
12+
group: ci-${{ github.ref }}
13+
cancel-in-progress: true
14+
15+
jobs:
16+
test:
17+
name: Test, build and pack
18+
runs-on: ubuntu-latest
19+
steps:
20+
- uses: actions/checkout@v6
21+
- uses: actions/setup-node@v6
22+
with:
23+
node-version: 24
24+
cache: npm
25+
# `npm ci` runs `prepare` (webpack build).
26+
- run: npm ci
27+
- run: npm test -- --ci
28+
- run: npm pack --dry-run

‎.github/workflows/release.yml‎

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# Publishes gleap to npm when a version tag (e.g. 19.0.0) is pushed. The CDN (sdk.gleap.io) is
2+
# deployed separately by Cloudflare Workers Builds on every push to master.
3+
#
4+
# Authentication uses npm trusted publishing (GitHub OIDC): no stored token,
5+
# provenance is attached automatically. One-time setup on npmjs.com →
6+
# gleap → Settings → Trusted publishing: GitHub Actions,
7+
# organization GleapSDK, repository JavaScript-SDK, workflow release.yml.
8+
# See README.md → Releasing.
9+
name: Release
10+
11+
on:
12+
push:
13+
tags:
14+
- '[0-9]+.[0-9]+.[0-9]+'
15+
- '[0-9]+.[0-9]+.[0-9]+-*'
16+
17+
permissions: {}
18+
19+
concurrency:
20+
group: release-${{ github.ref }}
21+
cancel-in-progress: false
22+
23+
jobs:
24+
publish:
25+
name: Publish to npm
26+
runs-on: ubuntu-latest
27+
permissions:
28+
contents: read
29+
id-token: write # npm trusted publishing (OIDC)
30+
steps:
31+
- uses: actions/checkout@v6
32+
33+
- uses: actions/setup-node@v6
34+
with:
35+
node-version: 24
36+
registry-url: https://registry.npmjs.org
37+
package-manager-cache: false
38+
39+
- name: Ensure npm >= 11.5.1 (trusted publishing)
40+
run: |
41+
if ! node -e 'const [a,b,c]=process.argv[1].split(".").map(Number);process.exit(a>11||(a===11&&(b>5||(b===5&&c>=1)))?0:1)' "$(npm --version)"; then
42+
npm install -g npm@latest
43+
fi
44+
npm --version
45+
46+
- name: Verify tag matches package.json version
47+
run: |
48+
PKG_VERSION="$(node -p "require('./package.json').version")"
49+
echo "tag=${GITHUB_REF_NAME} package.json=${PKG_VERSION}"
50+
if [ "${GITHUB_REF_NAME}" != "${PKG_VERSION}" ]; then
51+
echo "::error::Tag ${GITHUB_REF_NAME} does not match package.json version ${PKG_VERSION}"
52+
exit 1
53+
fi
54+
55+
# `npm ci` runs `prepare` (webpack build).
56+
- name: Install dependencies
57+
run: npm ci
58+
59+
- name: Test
60+
run: npm test -- --ci
61+
62+
- name: Pack (dry run)
63+
run: npm pack --dry-run
64+
65+
# Prerelease versions (X.Y.Z-…) go to the `next` dist-tag.
66+
- name: Publish to npm
67+
run: |
68+
case "${GITHUB_REF_NAME}" in
69+
*-*) npm publish --tag next ;;
70+
*) npm publish ;;
71+
esac
72+
73+
github-release:
74+
name: GitHub Release
75+
needs: publish
76+
runs-on: ubuntu-latest
77+
permissions:
78+
contents: write
79+
steps:
80+
- uses: actions/checkout@v6
81+
82+
- name: Create GitHub Release from CHANGELOG.md
83+
env:
84+
GH_TOKEN: ${{ github.token }}
85+
TAG: ${{ github.ref_name }}
86+
run: |
87+
if gh release view "$TAG" >/dev/null 2>&1; then
88+
echo "Release $TAG already exists, skipping."
89+
exit 0
90+
fi
91+
# Section "## <version>" up to the next "## " heading.
92+
awk -v v="$TAG" '/^## / { if (found) exit; if ($2 == v) { found = 1; next } } found' CHANGELOG.md > release-notes.md
93+
args=(--title "$TAG" --verify-tag)
94+
if [ -s release-notes.md ]; then
95+
args+=(--notes-file release-notes.md)
96+
else
97+
echo "::warning::No CHANGELOG.md section for $TAG, using generated notes."
98+
args+=(--generate-notes)
99+
fi
100+
case "$TAG" in *-*) args+=(--prerelease) ;; esac
101+
gh release create "$TAG" "${args[@]}"

‎README.md‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,11 @@ Congrats, you are now all set! Report your first bug by using the feedback butto
6060
## 🤝 Need help?
6161

6262
We are here to help! hello@gleap.io
63+
64+
## Releasing
65+
66+
1. Set `version` in `package.json` and add a `## X.Y.Z` section to `CHANGELOG.md`.
67+
2. Merge to `master`. Cloudflare Workers Builds deploys the CDN build (`sdk.gleap.io`) on every push to `master`.
68+
3. `git tag X.Y.Z && git push origin X.Y.Z` (plain version, no `v`).
69+
70+
The `Release` workflow checks that the tag matches `package.json`, runs the tests, publishes `gleap` to npm with trusted publishing (GitHub OIDC, no token; prerelease tags go to the `next` dist-tag) and creates the GitHub release from the CHANGELOG section. One-time setup: `npm trust github gleap --repo GleapSDK/JavaScript-SDK --file release.yml --allow-publish`.

‎package.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
},
2727
"repository": {
2828
"type": "git",
29-
"url": "https://github.com/GleapSDK/JavaScript-SDK"
29+
"url": "git+https://github.com/GleapSDK/JavaScript-SDK.git"
3030
},
3131
"author": "Gleap <hello@gleap.io>",
3232
"homepage": "https://www.gleap.ai",

0 commit comments

Comments
 (0)