From b261cf98e5c50819982c8e91f174ab0601b8641f Mon Sep 17 00:00:00 2001 From: VU3ESV Date: Fri, 5 Jun 2026 12:54:10 +0200 Subject: [PATCH] ci: skip release for docs-only changes Add a 'gate' job that inspects the changed files (PR files API on pull_request, compare API on push) and skips the release when EVERY changed file is markdown, under docs/, or LICENSE. Tag pushes and manual dispatch always release. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/release.yml | 45 +++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 05d4d8b..d9187a2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -42,7 +42,52 @@ env: BUMP: patch jobs: + # Skip the release when a push-to-main / merged PR only changes documentation. + # Tag pushes and manual dispatch always release. + gate: + name: Decide whether to release (skip docs-only) + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read + outputs: + skip: ${{ steps.decide.outputs.skip }} + steps: + - id: decide + env: + GH_TOKEN: ${{ github.token }} + run: | + set -euo pipefail + ev="${{ github.event_name }}" + # Explicit releases are never skipped. + if [ "$ev" = "workflow_dispatch" ]; then echo "skip=false" >> "$GITHUB_OUTPUT"; exit 0; fi + if [ "$ev" = "push" ]; then + case "${{ github.ref }}" in + refs/tags/*) echo "skip=false" >> "$GITHUB_OUTPUT"; exit 0 ;; + esac + files="$(gh api --paginate "repos/${{ github.repository }}/compare/${{ github.event.before }}...${{ github.event.after }}" -q '.files[].filename' || true)" + elif [ "$ev" = "pull_request" ]; then + files="$(gh api --paginate "repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files" -q '.[].filename')" + else + echo "skip=false" >> "$GITHUB_OUTPUT"; exit 0 + fi + echo "Changed files:"; printf ' %s\n' "$files" + # Docs-only when EVERY changed file is markdown, under docs/, or LICENSE. + skip=true + [ -z "$files" ] && skip=false # unknown/empty diff -> release, don't skip + while IFS= read -r f; do + [ -z "$f" ] && continue + case "$f" in + *.md|docs/*|*/docs/*|LICENSE) : ;; + *) skip=false; break ;; + esac + done <<< "$files" + echo "skip=$skip" >> "$GITHUB_OUTPUT" + [ "$skip" = true ] && echo "::notice::Docs-only change — skipping release." + release: + needs: gate + if: needs.gate.outputs.skip != 'true' runs-on: macos-14 timeout-minutes: 25 steps: