Authored-By: Codex (GPT-5.6) <noreply@openai.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
# Branch and PR title naming-standard checker.
|
||||
# Branch, PR body, and commit contract checker.
|
||||
# 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
|
||||
@@ -7,6 +7,9 @@ set -euo pipefail
|
||||
BRANCH="${HEAD_BRANCH:-}"
|
||||
TITLE="${PR_TITLE:-}"
|
||||
AUTHOR="${PR_AUTHOR:-}"
|
||||
BODY="${PR_BODY:-}"
|
||||
BASE="${BASE_SHA:-}"
|
||||
HEAD="${HEAD_SHA:-}"
|
||||
|
||||
# Break-glass: dfritz is exempt from all naming checks.
|
||||
if [ "${AUTHOR}" = "dfritz" ]; then
|
||||
@@ -49,6 +52,72 @@ if [ "${BRANCH_KIND}" = "role-bug" ]; then
|
||||
echo "FAIL[check-naming]: bug-id mismatch — branch carries '${BRANCH_BUG}' but title carries '${TITLE_BUG}'"
|
||||
FAILED=1
|
||||
fi
|
||||
|
||||
tracking=$(printf '%s\n' "${BODY}" | awk '
|
||||
/^## Tracking[[:space:]]*$/ { in_section=1; next }
|
||||
/^## / && in_section { exit }
|
||||
in_section { print }
|
||||
')
|
||||
if [ -z "${tracking}" ]; then
|
||||
echo "FAIL[check-naming]: PR body must contain a non-empty ## Tracking section"
|
||||
FAILED=1
|
||||
else
|
||||
if ! printf '%s\n' "${tracking}" | grep -qE "(^|[[:space:]])Fixes[[:space:]]+${BRANCH_BUG}([^a-z0-9]|$)"; then
|
||||
echo "FAIL[check-naming]: ## Tracking must contain the literal token 'Fixes ${BRANCH_BUG}'"
|
||||
FAILED=1
|
||||
fi
|
||||
if ! printf '%s\n' "${tracking}" | grep -Fq "https://agenthub.fritzlab.net/${BRANCH_BUG}"; then
|
||||
echo "FAIL[check-naming]: ## Tracking must link https://agenthub.fritzlab.net/${BRANCH_BUG}"
|
||||
FAILED=1
|
||||
fi
|
||||
fi
|
||||
|
||||
attribution=$(printf '%s\n' "${BODY}" | awk '
|
||||
/^## Attribution[[:space:]]*$/ { in_section=1; next }
|
||||
/^## / && in_section { exit }
|
||||
in_section { print }
|
||||
')
|
||||
watermark_re='^[-*]?[[:space:]]*Authored-By: .+ \(.+\) <noreply@[[:alnum:].-]+>$'
|
||||
if ! printf '%s\n' "${attribution}" | grep -qE "${watermark_re}"; then
|
||||
echo "FAIL[check-naming]: ## Attribution must contain an Authored-By product/model watermark"
|
||||
FAILED=1
|
||||
fi
|
||||
|
||||
if ! printf '%s\n%s\n' "${BASE}" "${HEAD}" | grep -qEv '^[0-9a-f]{40,64}$'; then
|
||||
for revision in "${BASE}" "${HEAD}"; do
|
||||
if ! git cat-file -e "${revision}^{commit}" 2>/dev/null; then
|
||||
echo "FAIL[check-naming]: base-sha and head-sha must name available commits"
|
||||
FAILED=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
if git cat-file -e "${BASE}^{commit}" 2>/dev/null && git cat-file -e "${HEAD}^{commit}" 2>/dev/null; then
|
||||
commit_count=0
|
||||
while IFS= read -r commit; do
|
||||
[ -n "${commit}" ] || continue
|
||||
commit_count=$((commit_count + 1))
|
||||
message=$(git log -1 --format=%B "${commit}")
|
||||
if ! printf '%s\n' "${message}" | awk '
|
||||
{ line[NR]=$0 }
|
||||
END {
|
||||
n=NR
|
||||
while (n > 0 && line[n] == "") n--
|
||||
if (n < 3 || line[n-1] != "" || line[n] !~ /^Authored-By: .+ \(.+\) <noreply@[[:alnum:].-]+>$/) exit 1
|
||||
}
|
||||
'; then
|
||||
echo "FAIL[check-naming]: commit ${commit} must end with an Authored-By product/model trailer"
|
||||
FAILED=1
|
||||
fi
|
||||
done < <(git rev-list --reverse "${BASE}..${HEAD}" 2>/dev/null)
|
||||
if [ "${commit_count}" -eq 0 ]; then
|
||||
echo "FAIL[check-naming]: base-sha..head-sha contains no PR commits"
|
||||
FAILED=1
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo "FAIL[check-naming]: base-sha and head-sha must be lowercase hexadecimal commit SHAs"
|
||||
FAILED=1
|
||||
fi
|
||||
elif [ "${BRANCH_KIND}" = "chore" ] && [ -n "${TITLE_BUG}" ]; then
|
||||
echo "FAIL[check-naming]: chore branch should not carry a [bug-id] title prefix"
|
||||
FAILED=1
|
||||
|
||||
Reference in New Issue
Block a user