From 9bfbd24461dc493508db876c8e49aba6f673ef24 Mon Sep 17 00:00:00 2001 From: Evelyn Chen Date: Sun, 26 Jul 2026 18:05:26 +0000 Subject: [PATCH] v2: fail (exit 1) on naming violation The four wired repos flip the naming job to a required status check (agenthub#557 WS6); a check that always exits 0 can never gate. v2 makes the script exit nonzero with FAIL lines; warn-only stays available via job-level continue-on-error or the legacy @v1 tag. dfritz break-glass exemption unchanged. Co-Authored-By: Claude Fable 5 --- README.md | 30 +++++++++++++++++++----------- action.yaml | 5 +++-- check.sh | 25 +++++++++++++------------ tests/run | 24 +++++++++--------------- 4 files changed, 44 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index 4f89d30..4649515 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,9 @@ # action/check-naming Composite Gitea Action that validates a pull request's head branch name -and title against the fritzlab naming standard. Always exits 0 — -warn-only until the Bugs tracking system is live (see +and title against the fritzlab naming standard. `@v2` fails (exits 1) on +any violation; `@v1` is the legacy warn-only release that never fails +(Bugs program: see [fritzlab/agenthub#557](https://code.fritzlab.net/fritzlab/agenthub/issues/557)). ## Standard @@ -26,15 +27,17 @@ jobs: naming: runs-on: fritzlab timeout-minutes: 5 - continue-on-error: true # non-required until Bugs cutover steps: - - uses: https://code.fritzlab.net/action/check-naming@v1 + - uses: https://code.fritzlab.net/action/check-naming@v2 with: head-branch: ${{ github.head_ref }} pr-title: ${{ github.event.pull_request.title }} pr-author: ${{ github.event.pull_request.user.login }} ``` +To wire a new repo warn-only first, add `continue-on-error: true` to the +job — the step still fails, but the job cannot block the PR. + ## Inputs | Name | Required | Description | @@ -49,16 +52,21 @@ The check validates two things: 1. **Branch form** — must be `/bug-/` or `chore/`. Unknown roles, missing `bug-` segment, uppercase bug-ids, and empty - kebab descriptions all produce a `WARN[check-naming]` log line. + kebab descriptions all produce a `FAIL[check-naming]` log line. -2. **Title form** — for a `role/bug` branch the title should start with - `[bug-] `. For a `chore` branch the title should have no `[bug-id]` +2. **Title form** — for a `role/bug` branch the title must start with + `[bug-] `. For a `chore` branch the title must have no `[bug-id]` prefix. If both carry a bug-id they must match. -All violations print a `WARN[check-naming]: ...` line. The step always -exits 0 so it cannot block a PR. To harden to required after the Bugs -cutover: remove `continue-on-error: true` from the consuming workflow -and add the job's context to the repo's `status_check_contexts`. +Every violation prints a `FAIL[check-naming]: ...` line and the step +exits 1. To make the check required on a repo: drop any +`continue-on-error: true` from the consuming workflow and add the job's +context to the repo's `status_check_contexts` in agenthub `hub/hub.yaml`. + +## Versions + +- `v2` — enforcing: exits 1 on violation (current). +- `v1` — legacy warn-only: logs `WARN` lines, always exits 0. ## Tests diff --git a/action.yaml b/action.yaml index fbb7503..885b48b 100644 --- a/action.yaml +++ b/action.yaml @@ -1,8 +1,9 @@ name: Check branch/PR naming description: | Validates that a PR's head branch and title follow the fritzlab naming - standard. Always exits 0 — warn-only until the Bugs system is live. - Produces WARN log lines for any violation. + standard. Fails (exits 1) on any violation, with FAIL log lines naming + it. Warn-only wiring is the consumer's choice: set + continue-on-error: true on the job (or pin @v1, which never fails). Standard: branch: /bug-/ e.g. dev/bug-x7k2m9/fix-terminal-resize diff --git a/check.sh b/check.sh index 4631f78..98654e9 100755 --- a/check.sh +++ b/check.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash # Branch and PR title naming-standard checker. -# Always exits 0 — warn-only until the Bugs system is live and STRICT=1 is set. +# v2: exits 1 on violation. Consumers that want warn-only set +# continue-on-error: true on the job (or stay on @v1). set -euo pipefail BRANCH="${HEAD_BRANCH:-}" @@ -13,7 +14,7 @@ if [ "${AUTHOR}" = "dfritz" ]; then exit 0 fi -WARN=0 +FAILED=0 BRANCH_KIND="invalid" BRANCH_BUG="" @@ -26,10 +27,10 @@ if echo "${BRANCH}" | grep -qE "^(dev|ux|ops|security|perf|architect|support)/bu elif echo "${BRANCH}" | grep -qE "^chore/[a-z0-9][a-z0-9-]*$"; then BRANCH_KIND="chore" else - echo "WARN[check-naming]: branch '${BRANCH}' does not match convention" + echo "FAIL[check-naming]: branch '${BRANCH}' does not match convention" echo " expected: /bug-/ (role: dev|ux|ops|security|perf|architect|support)" echo " or: chore/" - WARN=1 + FAILED=1 fi # ---- title form ---- @@ -40,19 +41,19 @@ fi if [ "${BRANCH_KIND}" = "role-bug" ]; then if [ -z "${TITLE_BUG}" ]; then - echo "WARN[check-naming]: title missing [${BRANCH_BUG}] prefix for branch '${BRANCH}'" - WARN=1 + echo "FAIL[check-naming]: title missing [${BRANCH_BUG}] prefix for branch '${BRANCH}'" + FAILED=1 elif [ "${TITLE_BUG}" != "${BRANCH_BUG}" ]; then - echo "WARN[check-naming]: bug-id mismatch — branch carries '${BRANCH_BUG}' but title carries '${TITLE_BUG}'" - WARN=1 + echo "FAIL[check-naming]: bug-id mismatch — branch carries '${BRANCH_BUG}' but title carries '${TITLE_BUG}'" + FAILED=1 fi elif [ "${BRANCH_KIND}" = "chore" ] && [ -n "${TITLE_BUG}" ]; then - echo "WARN[check-naming]: chore branch should not carry a [bug-id] title prefix" - WARN=1 + echo "FAIL[check-naming]: chore branch should not carry a [bug-id] title prefix" + FAILED=1 fi -if [ "${WARN}" -eq 0 ]; then +if [ "${FAILED}" -eq 0 ]; then echo "check-naming: ok" fi -exit 0 +exit "${FAILED}" diff --git a/tests/run b/tests/run index 1e75f51..f141a31 100755 --- a/tests/run +++ b/tests/run @@ -7,22 +7,16 @@ PASS=0 FAIL=0 check() { - local desc="$1" want_warn="$2" branch="$3" title="$4" author="$5" + local desc="$1" want_fail="$2" branch="$3" title="$4" author="$5" local out rc=0 out=$(HEAD_BRANCH="$branch" PR_TITLE="$title" PR_AUTHOR="$author" bash "$SCRIPT" 2>&1) || rc=$? - if [ "$rc" -ne 0 ]; then - echo "FAIL [$desc]: script exited $rc (must always exit 0)" - echo " output: $out" - FAIL=$((FAIL + 1)) - return - fi - local got_warn=0 - echo "$out" | grep -qE "^WARN" && got_warn=1 || true - if [ "$got_warn" -eq "$want_warn" ]; then + local got_lines=0 + echo "$out" | grep -qE "^FAIL" && got_lines=1 || true + if [ "$rc" -eq "$want_fail" ] && [ "$got_lines" -eq "$want_fail" ]; then echo "PASS [$desc]" PASS=$((PASS + 1)) else - echo "FAIL [$desc]: expected warn=$want_warn got=$got_warn" + echo "FAIL [$desc]: expected exit=$want_fail fail-lines=$want_fail, got exit=$rc fail-lines=$got_lines" echo " output: $out" FAIL=$((FAIL + 1)) fi @@ -45,16 +39,16 @@ check "support/bug matching title" 0 "support/bug-sup9/clarify-error" check "chore — no title prefix" 0 "chore/bump-deps" "Bump dependency versions" "dev" check "chore — plain title" 0 "chore/fix-a-typo" "Fix typo in README" "ops" -# warn: role/bug branch but no [bug-id] title prefix +# fail: role/bug branch but no [bug-id] title prefix check "role/bug no title prefix" 1 "dev/bug-x7k2m9/fix-resize" "Fix resize" "dev" -# warn: bug-id mismatch between branch and title +# fail: bug-id mismatch between branch and title check "bug-id mismatch" 1 "dev/bug-x7k2m9/fix-resize" "[bug-zzzzz1] Fix resize" "dev" -# warn: chore branch with [bug-id] title prefix +# fail: chore branch with [bug-id] title prefix check "chore with bug-id title" 1 "chore/bump-deps" "[bug-abc123] Bump deps" "dev" -# warn: invalid branch forms +# fail: invalid branch forms check "invalid — no role prefix" 1 "feature/foo-bar" "Add feature" "dev" check "invalid — missing bug segment" 1 "dev/fix-something" "Fix something" "dev" check "invalid — unknown role" 1 "unknown/bug-abc/thing" "[bug-abc] Thing" "dev"