From fcc1964b086179f85c33850216ac0a4cad4e72fc Mon Sep 17 00:00:00 2001 From: Jordan Ritter Date: Tue, 31 Mar 2026 15:33:53 -0700 Subject: [PATCH 1/2] ci: add unreleased changes check on push to main MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Warns when source commits accumulate on main without a version bump, preventing fixes from sitting unreleased like the v1.6.0 → v1.6.1 gap. --- .github/workflows/unreleased-check.yml | 36 ++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 .github/workflows/unreleased-check.yml diff --git a/.github/workflows/unreleased-check.yml b/.github/workflows/unreleased-check.yml new file mode 100644 index 00000000..02398a8e --- /dev/null +++ b/.github/workflows/unreleased-check.yml @@ -0,0 +1,36 @@ +name: Unreleased Changes Check +on: + push: + branches: [main] + +jobs: + check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: { fetch-depth: 0 } + + - name: Check for unreleased source changes + run: | + PKG_VERSION=$(node -p "require('./package.json').version") + TAG="v${PKG_VERSION}" + + # If the tag doesn't exist yet, this is the release commit itself — skip + if ! git rev-parse "${TAG}" >/dev/null 2>&1; then + echo "Tag ${TAG} not found — this push likely IS the release. Skipping." + exit 0 + fi + + # Count source-file commits since the last release tag + UNRELEASED=$(git log "${TAG}..HEAD" --oneline -- 'src/' | wc -l | tr -d ' ') + + if [ "$UNRELEASED" -gt 0 ]; then + echo "::warning::${UNRELEASED} source commits on main since ${TAG} — version has not been bumped." + echo "" + echo "Unreleased commits:" + git log "${TAG}..HEAD" --oneline -- 'src/' + echo "" + echo "Run: bump package.json version, update CHANGELOG.md, push to trigger publish." + else + echo "No unreleased source changes since ${TAG}." + fi From 9d98972e167df0f7f7544f769bf3d1381d21adcb Mon Sep 17 00:00:00 2001 From: Jordan Ritter Date: Tue, 31 Mar 2026 15:40:45 -0700 Subject: [PATCH 2/2] ci: ensure git tag exists before creating GitHub release Adds explicit git tag creation step before gh release create, so tags exist even if the release step fails partway. Also passes --verify-tag to gh release create for safety. --- .github/workflows/publish-release.yml | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 19f34f9e..31c6f232 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -8,6 +8,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + with: { fetch-depth: 0 } - uses: pnpm/action-setup@v4 - uses: actions/setup-node@v4 with: @@ -21,6 +22,7 @@ jobs: run: | PKG_NAME=$(node -p "require('./package.json').name") PKG_VERSION=$(node -p "require('./package.json').version") + echo "version=${PKG_VERSION}" >> "$GITHUB_OUTPUT" if npm view "${PKG_NAME}@${PKG_VERSION}" version 2>/dev/null; then echo "published=true" >> "$GITHUB_OUTPUT" else @@ -34,10 +36,20 @@ jobs: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + - name: Ensure git tag exists + if: steps.check.outputs.published == 'false' + run: | + TAG="v${{ steps.check.outputs.version }}" + if ! git rev-parse "${TAG}" >/dev/null 2>&1; then + git tag "${TAG}" + git push origin "${TAG}" + fi + - name: Create GitHub Release if: steps.check.outputs.published == 'false' run: | - PKG_VERSION=$(node -p "require('./package.json').version") - gh release create "v${PKG_VERSION}" --generate-notes --title "v${PKG_VERSION}" + TAG="v${{ steps.check.outputs.version }}" + # --verify-tag ensures the tag exists before creating the release + gh release create "${TAG}" --generate-notes --title "${TAG}" --verify-tag env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}