|
| 1 | +#!/usr/bin/env bash |
| 2 | +# |
| 3 | +# check_change_id.sh - Fail if any commit message contains a Gerrit "Change-Id:" |
| 4 | +# trailer. |
| 5 | +# |
| 6 | +# The repo ships a Gerrit-style commit-msg hook (repo/hooks/commit-msg) that |
| 7 | +# auto-inserts Change-Id lines. Those are meaningful only when pushing to the |
| 8 | +# internal Gerrit; on the public GitHub mirror they are noise. This guard |
| 9 | +# catches such lines before they land on a protected branch. |
| 10 | +# |
| 11 | +# Usage: |
| 12 | +# Tools/check_change_id.sh [<range>] |
| 13 | +# |
| 14 | +# <range> Git revision range to inspect (e.g. origin/main..HEAD). |
| 15 | +# If omitted, the range is derived from environment variables set by |
| 16 | +# CI (GitHub Actions), falling back to just the tip commit (HEAD). |
| 17 | +# |
| 18 | +# Exit codes: |
| 19 | +# 0 no Change-Id found |
| 20 | +# 1 one or more commits contain a Change-Id trailer |
| 21 | + |
| 22 | +set -euo pipefail |
| 23 | + |
| 24 | +PATTERN='^Change-Id:' |
| 25 | + |
| 26 | +resolve_range() { |
| 27 | + # 1) explicit arg wins |
| 28 | + if [ "$#" -ge 1 ] && [ -n "${1:-}" ]; then |
| 29 | + echo "$1" |
| 30 | + return |
| 31 | + fi |
| 32 | + |
| 33 | + # 2) GitHub Actions pull_request: compare base..head |
| 34 | + if [ -n "${GITHUB_BASE_REF:-}" ]; then |
| 35 | + # base ref is the target branch of the PR |
| 36 | + if git rev-parse --verify --quiet "origin/${GITHUB_BASE_REF}" >/dev/null; then |
| 37 | + echo "origin/${GITHUB_BASE_REF}..HEAD" |
| 38 | + return |
| 39 | + fi |
| 40 | + fi |
| 41 | + |
| 42 | + # 3) GitHub Actions push: event range before..after |
| 43 | + if [ -n "${GITHUB_EVENT_BEFORE:-}" ] \ |
| 44 | + && [ "${GITHUB_EVENT_BEFORE}" != "0000000000000000000000000000000000000000" ] \ |
| 45 | + && git rev-parse --verify --quiet "${GITHUB_EVENT_BEFORE}" >/dev/null; then |
| 46 | + echo "${GITHUB_EVENT_BEFORE}..HEAD" |
| 47 | + return |
| 48 | + fi |
| 49 | + |
| 50 | + # 4) fallback: inspect only the tip commit |
| 51 | + echo "HEAD~1..HEAD" |
| 52 | +} |
| 53 | + |
| 54 | +RANGE="$(resolve_range "$@")" |
| 55 | + |
| 56 | +# Guard: if the range endpoints are missing (shallow clone), degrade to HEAD. |
| 57 | +if ! git rev-list "$RANGE" >/dev/null 2>&1; then |
| 58 | + echo "⚠️ Range '$RANGE' not resolvable (shallow clone?); checking HEAD only." |
| 59 | + RANGE="HEAD~1..HEAD" |
| 60 | + if ! git rev-list "$RANGE" >/dev/null 2>&1; then |
| 61 | + RANGE="HEAD" |
| 62 | + fi |
| 63 | +fi |
| 64 | + |
| 65 | +echo "🔍 Checking commit messages for Change-Id in range: $RANGE" |
| 66 | + |
| 67 | +offenders="" |
| 68 | +for sha in $(git rev-list "$RANGE"); do |
| 69 | + if git log -1 --format='%B' "$sha" | grep -Eq "$PATTERN"; then |
| 70 | + offenders="$offenders $sha" |
| 71 | + fi |
| 72 | +done |
| 73 | + |
| 74 | +if [ -n "$offenders" ]; then |
| 75 | + echo "❌ Found Gerrit Change-Id trailer in the following commit(s):" |
| 76 | + for sha in $offenders; do |
| 77 | + subject=$(git log -1 --format='%h %s' "$sha") |
| 78 | + echo " - $subject" |
| 79 | + done |
| 80 | + echo "" |
| 81 | + echo "These Change-Id lines come from the Gerrit commit-msg hook and must" |
| 82 | + echo "not be pushed to this branch. Remove them, e.g.:" |
| 83 | + echo "" |
| 84 | + echo " git rebase -i <base> --exec \\" |
| 85 | + echo " 'git commit --amend -m \"\$(git log -1 --format=%B | sed \"/^Change-Id: /d\")\"'" |
| 86 | + echo "" |
| 87 | + echo "or for the tip commit only:" |
| 88 | + echo "" |
| 89 | + echo " git commit --amend -m \"\$(git log -1 --format=%B | sed '/^Change-Id: /d')\"" |
| 90 | + exit 1 |
| 91 | +fi |
| 92 | + |
| 93 | +echo "✅ No Change-Id trailers found." |
0 commit comments