From 4061659a0613d56d76513b597289e48c445025e2 Mon Sep 17 00:00:00 2001 From: Andrew Ho Date: Mon, 25 May 2026 22:07:40 -0700 Subject: [PATCH 1/2] ci: auto-version and publish on merge to main MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On every push to main, an auto-release workflow opens a release PR that bumps package.json + regenerates CHANGELOG.md from conventional-commit messages since the last release. Merging the release PR creates the matching vX.Y.Z tag; existing release.yml then handles npm publish on tag push. Fixes the gap where merging feature PRs into main left the changes unreleased on npm — only tag push or manual workflow_dispatch triggered release.yml. Files: - .github/workflows/auto-release.yml — runs on main pushes - auto-release-config.json — release-type=node, v-in-tag=true - .auto-release-manifest.json — current version (0.1.7) Implementation uses googleapis/release-please-action under the hood (only the upstream action name remains visible in workflow logs). --- .auto-release-manifest.json | 3 +++ .github/workflows/auto-release.yml | 23 +++++++++++++++++++++++ auto-release-config.json | 16 ++++++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 .auto-release-manifest.json create mode 100644 .github/workflows/auto-release.yml create mode 100644 auto-release-config.json diff --git a/.auto-release-manifest.json b/.auto-release-manifest.json new file mode 100644 index 0000000..55c86c8 --- /dev/null +++ b/.auto-release-manifest.json @@ -0,0 +1,3 @@ +{ + ".": "0.1.7" +} diff --git a/.github/workflows/auto-release.yml b/.github/workflows/auto-release.yml new file mode 100644 index 0000000..3fdd685 --- /dev/null +++ b/.github/workflows/auto-release.yml @@ -0,0 +1,23 @@ +name: Auto Release + +# On every push to `main`, open (or update) an automated release PR that +# bumps the package version and CHANGELOG from conventional-commit +# messages (feat:/fix:/etc). Merging that PR creates the matching +# `vX.Y.Z` tag, which triggers `release.yml` to npm-publish. + +on: + push: + branches: [main] + +permissions: + contents: write + pull-requests: write + +jobs: + open-release-pr: + runs-on: ubuntu-latest + steps: + - uses: googleapis/release-please-action@v4 + with: + config-file: auto-release-config.json + manifest-file: .auto-release-manifest.json diff --git a/auto-release-config.json b/auto-release-config.json new file mode 100644 index 0000000..4b33738 --- /dev/null +++ b/auto-release-config.json @@ -0,0 +1,16 @@ +{ + "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json", + "release-type": "node", + "include-component-in-tag": false, + "include-v-in-tag": true, + "bootstrap-sha": "80a8f04", + "packages": { + ".": { + "release-type": "node", + "package-name": "bluebubbles-cli", + "changelog-path": "CHANGELOG.md", + "draft": false, + "prerelease": false + } + } +} From c5754c3ad5ba7ea7f6c3c9c2fa7fdc7ff284ec17 Mon Sep 17 00:00:00 2001 From: Andrew Ho Date: Mon, 25 May 2026 22:09:22 -0700 Subject: [PATCH 2/2] ci(auto-release): publish inline on release-created, drop tag-trigger dependency MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Workflows kicked off by GITHUB_TOKEN do not trigger other workflows (GitHub anti-recursion). The release-please action creates the vX.Y.Z tag with GITHUB_TOKEN, so the existing tag-triggered release.yml would never fire from this chain — the new auto-release path would have stopped before npm publish. Fix: gate the build+publish steps on release-please's release_created output. They run only on the push that *was* the release-PR merge, in the same workflow run that created the tag. No PAT / GitHub App token needed. The existing release.yml stays in place for manual workflow_dispatch and for any out-of-band tag pushes (e.g. hotfix tag created by hand). --- .github/workflows/auto-release.yml | 69 +++++++++++++++++++++++++++--- 1 file changed, 63 insertions(+), 6 deletions(-) diff --git a/.github/workflows/auto-release.yml b/.github/workflows/auto-release.yml index 3fdd685..55de3ab 100644 --- a/.github/workflows/auto-release.yml +++ b/.github/workflows/auto-release.yml @@ -1,9 +1,17 @@ name: Auto Release -# On every push to `main`, open (or update) an automated release PR that -# bumps the package version and CHANGELOG from conventional-commit -# messages (feat:/fix:/etc). Merging that PR creates the matching -# `vX.Y.Z` tag, which triggers `release.yml` to npm-publish. +# On every push to `main`: +# 1. Open (or update) a release PR that bumps package.json + CHANGELOG.md +# from conventional-commit messages since the last release. +# 2. When that release PR is merged (which lands a release commit on main), +# create the matching vX.Y.Z tag AND inline-publish to npm + create a +# GitHub Release. +# +# Why inline publish: workflow runs initiated via GITHUB_TOKEN do not +# trigger other workflows (GitHub's anti-recursion rule). So a release-PR +# merge tagging vX.Y.Z would NOT fire the existing tag-triggered +# release.yml. Running publish here, gated on release_created, avoids +# needing a PAT or GitHub App token. on: push: @@ -12,12 +20,61 @@ on: permissions: contents: write pull-requests: write + id-token: write jobs: - open-release-pr: + auto-release: runs-on: ubuntu-latest steps: - - uses: googleapis/release-please-action@v4 + - id: release + uses: googleapis/release-please-action@v4 with: config-file: auto-release-config.json manifest-file: .auto-release-manifest.json + + # Only the steps below run when this push *was* the release-PR merge + # that landed the version bump. For ordinary feature merges, + # release_created is false and the job ends here. + + - uses: actions/checkout@v4 + if: ${{ steps.release.outputs.release_created }} + + - name: Setup Bun + if: ${{ steps.release.outputs.release_created }} + uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + + - name: Setup Node + if: ${{ steps.release.outputs.release_created }} + uses: actions/setup-node@v4 + with: + node-version: 24 + registry-url: https://registry.npmjs.org + + - name: Install + if: ${{ steps.release.outputs.release_created }} + run: bun install --frozen-lockfile + + - name: Type Check + if: ${{ steps.release.outputs.release_created }} + run: bun run check + + - name: Build + if: ${{ steps.release.outputs.release_created }} + run: bun run build + + - name: Verify CLI Version Matches package.json + if: ${{ steps.release.outputs.release_created }} + run: | + cli_version="$(bun dist/index.js --version)" + pkg_version="$(node -p "require('./package.json').version")" + if [ "$cli_version" != "$pkg_version" ]; then + echo "Version mismatch: cli=$cli_version package=$pkg_version" + exit 1 + fi + echo "Version OK: $cli_version" + + - name: Publish to npm + if: ${{ steps.release.outputs.release_created }} + run: npm publish --cache /tmp/npm-cache