From 001b2a3d6b36e43f3a1f40bc35675b17bfc94f34 Mon Sep 17 00:00:00 2001 From: Juergen Klaassen Date: Wed, 20 May 2026 10:16:41 -0600 Subject: [PATCH] ci: validate semver label on PR events, not just at merge The Check-PR-Labels job in release.yml only runs on `pull_request closed`, so a merge with no label produces a failed release run that can't be re-fired (re-running uses the cached event payload, which still has no labels). Run the same check on PR open/sync/labeled/unlabeled so the problem surfaces while it's still fixable. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/pr-labels.yml | 35 +++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 .github/workflows/pr-labels.yml diff --git a/.github/workflows/pr-labels.yml b/.github/workflows/pr-labels.yml new file mode 100644 index 0000000..0901059 --- /dev/null +++ b/.github/workflows/pr-labels.yml @@ -0,0 +1,35 @@ +name: PR Label Check + +# Validates that every PR carries exactly one semver label before merge. +# The release workflow re-checks this on `pull_request closed`, but by then +# it's too late — a merge with no label produces no release. Running the +# same check on PR events surfaces the problem while it's still fixable. +on: + pull_request: + types: [opened, synchronize, reopened, labeled, unlabeled] + branches: [main] + +permissions: + contents: read + +jobs: + Check-PR-Labels: + runs-on: ubuntu-latest + steps: + - name: Parse PR labels + uses: actions/github-script@v7 + with: + script: | + const valid = ['major', 'minor', 'patch', 'no version']; + const labels = context.payload.pull_request.labels.map(l => l.name); + core.info(`Labels on PR: ${labels.join(', ') || '(none)'}`); + + const matches = labels.filter(name => valid.includes(name)); + if (matches.length !== 1) { + core.setFailed( + `Expected exactly one of: ${valid.map(v => `'${v}'`).join(', ')}. Found ${matches.length}.` + ); + return; + } + + core.info(`Release type: ${matches[0]}`);