-
Notifications
You must be signed in to change notification settings - Fork 123
133 lines (118 loc) · 6.34 KB
/
validate.yml
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
name: PR Validation
on:
pull_request:
types: [edited, opened, synchronize, reopened]
branches: ["*"]
jobs:
validate-pr:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Determine if PR is from fork
id: check_fork
run: |
if [ "${{ github.event.pull_request.head.repo.full_name }}" != "${{ github.repository }}" ]; then
echo "is_fork=true" >> $GITHUB_ENV
else
echo "is_fork=false" >> $GITHUB_ENV
fi
- name: Clear all PR labels
run: |
pr_number=${{ github.event.pull_request.number }}
labels=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
"https://api.github.com/repos/${{ github.repository }}/issues/$pr_number/labels" | jq -r '.[].name // empty')
for label in $labels; do
curl -s -X DELETE -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
"https://api.github.com/repos/${{ github.repository }}/issues/$pr_number/labels/$label"
done
- name: Validate PR
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
pr_body="${{ github.event.pull_request.body }}"
pr_author="${{ github.event.pull_request.user.login }}"
pr_number="${{ github.event.pull_request.number }}"
pr_url="${{ github.event.pull_request.html_url }}"
repo_full_name="${{ github.repository }}"
message="Hello @${pr_author}, your PR is being processed. Here are the results:\n\n"
exit_code=0
echo "Starting PR validation for PR #${pr_number} by ${pr_author}"
# Function to make GitHub API calls
github_api_call() {
local method=$1
local endpoint=$2
local data=$3
local url="https://api.github.com/repos/${repo_full_name}/${endpoint}"
response=$(curl -s -X ${method} -H "Authorization: token ${GITHUB_TOKEN}" -H "Accept: application/vnd.github.v3+json" ${data:+-d "$data"} "$url")
echo "API call to ${endpoint}: $response" >&2
echo "$response"
}
# Check if PR author is a maintainer
permissions=$(github_api_call GET "collaborators/${pr_author}/permission")
is_maintainer=$(echo $permissions | jq -r '.permission')
echo "Author permissions: $is_maintainer"
if [[ "$is_maintainer" == "admin" || "$is_maintainer" == "maintain" ]]; then
echo "Author is a maintainer, bypassing checks"
message+="As a maintainer, your PR is automatically approved and will bypass further checks.\n"
github_api_call POST "issues/${pr_number}/labels" '{"labels":["PR:maintainer-bypass"]}'
else
# echo "Proceeding with checks regardless of maintainer status for testing purposes"
# Check PR template
if [[ "$pr_body" != *"## Description"* ]] || [[ "$pr_body" != *"## Related issue"* ]]; then
exit_code=2
echo "PR template not respected. Exit code: $exit_code"
reason="PR template is not respected. Please update your PR description to include the required sections."
message+="\n- $reason\n\nHere's a minimal example of a valid PR body:\n\n"
message+='```markdown\n## Description\n\n[Provide a brief description of your changes]\n\n## Related issue\n\nFixes #123\n```\n'
github_api_call POST "issues/${pr_number}/labels" '{"labels":["PR:fix-template"]}'
else
echo "PR template respected, checking linked issues"
# Extract linked issues
# issue_numbers=$(echo "$pr_body" | grep -oP '#\K\d+')
issue_numbers=$(echo "$pr_body" | grep -o '#[0-9]\+' | cut -d'#' -f2)
echo "debug linked issues"
if [ -z "$issue_numbers" ]; then
echo "No linked issues detected. Setting default empty value for issue_numbers to avoid error."
issue_numbers="empty"
exit_code=3
echo "No linked issue found. Exit code: $exit_code"
reason="No linked issue found. Please link an issue in your PR description (e.g., 'Fixes #123')."
message+="\n- $reason"
github_api_call POST "issues/${pr_number}/labels" '{"labels":["PR:no-linked-issue"]}'
else
echo "Linked issues found: $issue_numbers"
# Check if PR author is assigned to the linked issue(s)
if [[ "$issue_numbers" != "empty" ]]; then
for issue_number in $issue_numbers; do
issue_data=$(github_api_call GET "issues/${issue_number}")
issue_assignees=$(echo "$issue_data" | jq -r '.assignees[].login')
if ! echo "$issue_assignees" | grep -q "$pr_author"; then
exit_code=4
echo "Author not assigned to issue #${issue_number}. Exit code: $exit_code"
reason="PR author is not assigned to the linked issue #$issue_number. Please assign yourself to the issue before submitting a PR."
message+="\n- $reason"
github_api_call POST "issues/${pr_number}/labels" '{"labels":["PR:author-not-assigned"]}'
else
echo "Author is assigned to issue #${issue_number}"
fi
done
fi
fi
fi
fi
# Finalize validation
if [ "$exit_code" = 0 ]; then
echo "PR is valid"
message+="\n\nYour PR is valid and ready for review. Thank you for your contribution!"
github_api_call POST "issues/${pr_number}/labels" '{"labels":["PR:ready-for-review"]}'
else
echo "PR is invalid. Closing PR."
message+="\n\nPlease address the above issues and update your PR. Once you've made the necessary changes, the PR will be automatically re-evaluated."
github_api_call PATCH "pulls/${pr_number}" '{"state":"closed"}'
fi
# Add comment to PR
echo "Adding comment to PR"
github_api_call POST "issues/${pr_number}/comments" "{\"body\":\"$message\"}"
echo "PR validation completed. Exit code: $exit_code"
exit $exit_code