forked from Koenkk/zigbee-herdsman-converters
-
Notifications
You must be signed in to change notification settings - Fork 0
99 lines (84 loc) · 3.3 KB
/
Copy pathrequires_review.yml
File metadata and controls
99 lines (84 loc) · 3.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
name: Requires external review
on:
pull_request_target:
types:
- opened
- synchronize
- reopened
- ready_for_review
- labeled
- unlabeled
permissions:
contents: read
pull-requests: write
jobs:
requires-external-review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 1
- name: Check for files that require external review
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.pull_request.number }}
run: |
# Skip if PR already has the approval label
LABELS=$(gh pr view $PR_NUMBER --json labels --jq '.labels[].name')
for label in $LABELS; do
if [[ "$label" == "external-reviewer-approved" ]]; then
exit 0
fi
done
# Build reviewer map from CODEOWNERS
declare -a PATTERNS=()
declare -A PATTERN_REVIEWERS=()
while IFS= read -r line; do
line="${line%%#*}"
[[ -z "${line// }" ]] && continue
read -r pattern owners <<< "$line"
PATTERNS+=("$pattern")
PATTERN_REVIEWERS["$pattern"]="$owners"
done < CODEOWNERS
# pull_request_target runs in base-repo context; get changed files from the PR API.
CHANGED_FILES=$(gh pr view "$PR_NUMBER" --json files --jq '.files[].path')
MATCH=false
declare -A MATCHED_REVIEWERS=()
shopt -s extglob
for file in $CHANGED_FILES; do
for pattern in "${PATTERNS[@]}"; do
# CODEOWNERS patterns: leading "/" anchors to root (strip it for
# matching against repo-relative paths), otherwise match anywhere.
glob="$pattern"
[[ "$glob" == /* ]] && glob="${glob:1}"
if [[ $file == $glob ]]; then
reviewers="${PATTERN_REVIEWERS[$pattern]}"
echo "::error::Review required for '$file' by '$reviewers'"
MATCHED_REVIEWERS["$reviewers"]+="$file"$'\n'
MATCH=true
fi
done
done
# Post a comment tagging the owners (only once per PR)
if [ "$MATCH" = true ]; then
MARKER="<!-- requires-external-review -->"
EXISTING=$(gh pr view $PR_NUMBER --json comments \
--jq ".comments[].body | select(contains(\"$MARKER\"))" || true)
if [ -z "$EXISTING" ]; then
BODY="$MARKER"$'\n'
BODY+="## External review required"$'\n\n'
BODY+="This PR modifies files that require review from their code owners before merging."$'\n\n'
for reviewers in "${!MATCHED_REVIEWERS[@]}"; do
FILES="${MATCHED_REVIEWERS[$reviewers]}"
BODY+="**$reviewers**:"$'\n'
while IFS= read -r f; do
[[ -n "$f" ]] && BODY+="- \`$f\`"$'\n'
done <<< "$FILES"
BODY+=$'\n'
done
BODY+="Once reviewed, add the \`external-reviewer-approved\` label to unblock this check."
# Fork PRs may still get a read-only token; do not fail the job on comment alone.
gh pr comment $PR_NUMBER --body "$BODY" || echo "::warning::Could not post PR comment (token may lack pull-requests:write for this PR). Check logs for required reviewers."
fi
exit 1
fi