From ec14c5e5953ebc4b0ec6599c98e3849d8d7a9056 Mon Sep 17 00:00:00 2001 From: Lukas Boehler Date: Wed, 30 Sep 2026 11:53:37 -0400 Subject: [PATCH] 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 --- .github/workflows/ci.yml | 28 ++++++++++ .github/workflows/release.yml | 101 ++++++++++++++++++++++++++++++++++ README.md | 8 +++ package.json | 2 +- 4 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..c5d671f --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,28 @@ +name: CI + +on: + pull_request: + push: + branches: [master] + +permissions: + contents: read + +concurrency: + group: ci-${{ github.ref }} + cancel-in-progress: true + +jobs: + test: + name: Test, build and pack + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - uses: actions/setup-node@v6 + with: + node-version: 24 + cache: npm + # `npm ci` runs `prepare` (webpack build). + - run: npm ci + - run: npm test -- --ci + - run: npm pack --dry-run diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..c47609c --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,101 @@ +# Publishes gleap to npm when a version tag (e.g. 19.0.0) is pushed. The CDN (sdk.gleap.io) is +# deployed separately by Cloudflare Workers Builds on every push to master. +# +# Authentication uses npm trusted publishing (GitHub OIDC): no stored token, +# provenance is attached automatically. One-time setup on npmjs.com → +# gleap → Settings → Trusted publishing: GitHub Actions, +# organization GleapSDK, repository JavaScript-SDK, workflow release.yml. +# See README.md → Releasing. +name: Release + +on: + push: + tags: + - '[0-9]+.[0-9]+.[0-9]+' + - '[0-9]+.[0-9]+.[0-9]+-*' + +permissions: {} + +concurrency: + group: release-${{ github.ref }} + cancel-in-progress: false + +jobs: + publish: + name: Publish to npm + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write # npm trusted publishing (OIDC) + steps: + - uses: actions/checkout@v6 + + - uses: actions/setup-node@v6 + with: + node-version: 24 + registry-url: https://registry.npmjs.org + package-manager-cache: false + + - name: Ensure npm >= 11.5.1 (trusted publishing) + run: | + 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 + npm install -g npm@latest + fi + npm --version + + - name: Verify tag matches package.json version + run: | + PKG_VERSION="$(node -p "require('./package.json').version")" + echo "tag=${GITHUB_REF_NAME} package.json=${PKG_VERSION}" + if [ "${GITHUB_REF_NAME}" != "${PKG_VERSION}" ]; then + echo "::error::Tag ${GITHUB_REF_NAME} does not match package.json version ${PKG_VERSION}" + exit 1 + fi + + # `npm ci` runs `prepare` (webpack build). + - name: Install dependencies + run: npm ci + + - name: Test + run: npm test -- --ci + + - name: Pack (dry run) + run: npm pack --dry-run + + # Prerelease versions (X.Y.Z-…) go to the `next` dist-tag. + - name: Publish to npm + run: | + case "${GITHUB_REF_NAME}" in + *-*) npm publish --tag next ;; + *) npm publish ;; + esac + + github-release: + name: GitHub Release + needs: publish + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - uses: actions/checkout@v6 + + - name: Create GitHub Release from CHANGELOG.md + env: + GH_TOKEN: ${{ github.token }} + TAG: ${{ github.ref_name }} + run: | + if gh release view "$TAG" >/dev/null 2>&1; then + echo "Release $TAG already exists, skipping." + exit 0 + fi + # Section "## " up to the next "## " heading. + awk -v v="$TAG" '/^## / { if (found) exit; if ($2 == v) { found = 1; next } } found' CHANGELOG.md > release-notes.md + args=(--title "$TAG" --verify-tag) + if [ -s release-notes.md ]; then + args+=(--notes-file release-notes.md) + else + echo "::warning::No CHANGELOG.md section for $TAG, using generated notes." + args+=(--generate-notes) + fi + case "$TAG" in *-*) args+=(--prerelease) ;; esac + gh release create "$TAG" "${args[@]}" diff --git a/README.md b/README.md index 0dedef7..8da8276 100644 --- a/README.md +++ b/README.md @@ -60,3 +60,11 @@ Congrats, you are now all set! Report your first bug by using the feedback butto ## 🤝 Need help? We are here to help! hello@gleap.io + +## Releasing + +1. Set `version` in `package.json` and add a `## X.Y.Z` section to `CHANGELOG.md`. +2. Merge to `master`. Cloudflare Workers Builds deploys the CDN build (`sdk.gleap.io`) on every push to `master`. +3. `git tag X.Y.Z && git push origin X.Y.Z` (plain version, no `v`). + +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`. diff --git a/package.json b/package.json index 825eedd..dca337e 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/GleapSDK/JavaScript-SDK" + "url": "git+https://github.com/GleapSDK/JavaScript-SDK.git" }, "author": "Gleap ", "homepage": "https://www.gleap.ai",