From 0a03db1db324b5f480694bf542c19207f3e1b8aa Mon Sep 17 00:00:00 2001 From: Alex MKX Date: Fri, 23 Oct 2026 10:34:53 +0300 Subject: [PATCH] ci: release on merge to master when package.json version is unreleased Creates the vX.Y.Z GitHub release (marked latest, generated notes) after tests, lint and knip pass. Reuses an existing tag; pushes that keep the version are no-ops. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/release.yml | 63 +++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..03ef47a --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,63 @@ +# Release on every push to master (i.e. a merged PR) whose package.json version +# has no GitHub release yet. Bump "version" in the PR to cut a release; pushes +# that keep the version (benchmark refreshes, docs) are no-ops. An existing +# vX.Y.Z tag is reused as-is, otherwise the tag is created on the pushed commit. +name: release + +on: + push: + branches: [master] + workflow_dispatch: + +permissions: + contents: write + +concurrency: + group: release + cancel-in-progress: false + +jobs: + release: + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Resolve version + id: version + env: + GH_TOKEN: ${{ github.token }} + run: | + version=$(node -p 'require("./package.json").version') + tag="v${version}" + echo "tag=${tag}" >> "$GITHUB_OUTPUT" + if gh release view "$tag" >/dev/null 2>&1; then + echo "Release $tag already exists; nothing to do." + echo "skip=true" >> "$GITHUB_OUTPUT" + else + echo "skip=false" >> "$GITHUB_OUTPUT" + fi + + - uses: actions/setup-node@v4 + if: steps.version.outputs.skip == 'false' + with: + node-version: 24 + cache: npm + + - name: Test + if: steps.version.outputs.skip == 'false' + run: | + npm ci + npm test + npm run lint + npm run knip + + - name: Create release + if: steps.version.outputs.skip == 'false' + env: + GH_TOKEN: ${{ github.token }} + TAG: ${{ steps.version.outputs.tag }} + run: | + gh release create "$TAG" --target "$GITHUB_SHA" --title "$TAG" --generate-notes --latest