-
Notifications
You must be signed in to change notification settings - Fork 485
246 lines (214 loc) · 9.89 KB
/
pr-issue-validator.yaml
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
name: Validate Pull Request
on:
pull_request:
types:
- opened
- synchronize
- edited
- reopened
branches:
- 'main'
- 'release-**'
# paths-ignore:
# - 'docs/**'
# - '.github/'
# - 'CHANGELOG/'
# - 'charts/'
# - 'manifests/'
# - 'sample-docker-templates/'
jobs:
validate-PR-issue:
runs-on: ubuntu-latest
permissions:
issues: write
contents: read
pull-requests: write
steps:
- name: Checkout repository
uses: actions/checkout@v2
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
- name: Validate Issue Reference
env:
GITHUB_TOKEN: ${{ github.token }}
PR_BODY: ${{ github.event.pull_request.body }}
url: ${{ github.event.pull_request.url }}
PRNUM: ${{ github.event.pull_request.number }}
TITLE: ${{ github.event.pull_request.title }}
run: |
set -x
echo "base or target repo : ${{ github.event.pull_request.base.repo.full_name }}"
echo "head or source repo : ${{ github.event.pull_request.head.repo.full_name }}"
if [[ ${{ github.event.pull_request.head.repo.full_name }} == ${{ github.event.pull_request.base.repo.full_name }} ]]; then
export forked=false
else
export forked=true
fi
echo "forked: $forked"
if [[ "$TITLE" == *"doc:"* || "$TITLE" == *"docs:"* || "$TITLE" == *"misc:"* || "$TITLE" == *"release:"* || "$TITLE" == *"Release:"* ]]; then
echo "Skipping validation as this is a PR for documentation or misc."
if [[ $forked == true ]]; then
echo "PR:Ready-to-Review, exiting gracefully"
exit 0
fi
gh pr edit $PRNUM --remove-label "PR:Issue-verification-failed"
gh pr edit $PRNUM --add-label "PR:Ready-to-Review"
exit 0
fi
### For ex: Fixes #2123
### For ex: Fixes: #2123
pattern1="((Fixes|Resolves):? #[0-9]+)"
### For ex: Resolves https://github.com/devtron-labs/devtron/issues/2123
pattern2="((Fixes|Resolves):? https://github.com/devtron-labs/devtron/issues/[0-9]+)"
### For ex: Fixes devtron-labs/devtron#2123
pattern3="((Fixes|Resolves):? devtron-labs/devtron#[0-9]+)"
### For ex: Fixes [#4839](https://github.com/devtron-labs/devtron/issues/4839)
pattern4="(Fixes|Resolves):?\s+\[#([0-9]+)\]"
# Get the pull request body
PR_BODY=$(jq -r '.pull_request.body' $GITHUB_EVENT_PATH)
echo "PR_BODY = $PR_BODY"
### Checks if PR_BODY matches pattern1 or pattern2 or pattern3 or none
### grep -i (case insensitive) -E (enables extended regular expression in grep) -q (this option suppresses normal output)
if echo "$PR_BODY" | grep -iEq "$pattern1"; then
### Here we are taking only the numerical value ie. issue number
### head -n1 only prints the 1st line.
### grep -o -E "[0-9]+ basically outputs only the number between [0-9]+
echo "$PR_BODY" | grep -iE "$pattern1" | head -n1 | grep -o -E "[0-9]+" | tr -d '\r\n' > issue_num
issue_num=$(cat issue_num)
echo "issue_num is : $issue_num"
elif echo "$PR_BODY" | grep -iEq "$pattern2"; then
echo "$PR_BODY" | grep -iE "$pattern2" | head -n1 | awk -F '/' '{print $NF}' | tr -d '\r\n' > issue_num
issue_num=$(cat issue_num)
echo "issue_num is : $issue_num"
elif echo "$PR_BODY" | grep -iEq "$pattern3"; then
echo "$PR_BODY" | grep -iE "$pattern3" | head -n1 | awk -F '#' '{print $NF}' | tr -d '\r\n' > issue_num
issue_num=$(cat issue_num)
echo "issue_num is : $issue_num"
elif echo "$PR_BODY" | grep -iEq "$pattern4"; then
echo "$PR_BODY" | grep -oP "$pattern4" | head -n1 | grep -oP '#\K[0-9]+' | tr -d '\r\n' > issue_num
issue_num=$(cat issue_num)
echo "issue_num is : $issue_num"
else
echo "No Issue number detected hence failing the PR Validation check."
if [[ $forked == true ]]; then
echo "PR:Issue-verification-failed, exiting forcefully!"
exit 1
fi
gh pr edit $PRNUM --add-label "PR:Issue-verification-failed"
gh pr edit $PRNUM --remove-label "PR:Ready-to-Review"
exit 1
fi
### Here we are setting the Internal Field Separator to "/"
### read -r -> reads input from variable $url
### -a url_parts -> tells read command to store input into an array named url_parts[]
IFS="/" read -r -a url_parts <<< "$url"
# Remove the last two elements (repos and the issue number)
unset url_parts[-1]
unset url_parts[-1]
# Reattach the URL pieces
url=$(IFS=/; echo "${url_parts[*]}")
# Add the issue number to the URL
url="${url}/issues/${issue_num}"
echo "$url"
response_code=$(curl -s -o /dev/null -w "%{http_code}" "$url")
if [[ "$response_code" -eq 200 ]]; then
# Check if issue is open or closed
text=$(curl -s "$url")
echo "checking status of the issue"
if [[ $(echo "$text" | jq -r '.state') == "open" ]]; then
echo "Issue #$issue_num is open"
echo "Issue reference found in the pull request body."
if [[ $forked == true ]]; then
echo "PR:Ready-to-Review, exiting gracefully"
exit 0
fi
gh pr edit $PRNUM --remove-label "PR:Issue-verification-failed"
gh pr edit $PRNUM --add-label "PR:Ready-to-Review"
exit 0
else
echo "Issue #$issue_num is not open"
if [[ $forked == true ]]; then
echo "PR:Issue-verification-failed, exiting forcefully!"
exit 1
fi
gh pr edit $PRNUM --add-label "PR:Issue-verification-failed"
gh pr edit $PRNUM --remove-label "PR:Ready-to-Review"
exit 1
fi
else
echo "Invalid Response Code obtained - error code: $response_code"
echo "No valid issue reference found in the pull request body."
gh pr comment $PRNUM --body "PR is not linked to any issue, please make the corresponding changes in the body."
if [[ $forked == true ]]; then
echo "PR:Issue-verification-failed, exiting forcefully!"
exit 1
fi
gh pr edit $PRNUM --add-label "PR:Issue-verification-failed"
gh pr edit $PRNUM --remove-label "PR:Ready-to-Review"
exit 1
fi
- name: Check SQL file format and duplicates
shell: bash
env:
pr_no: ${{ github.event.pull_request.number }}
GH_TOKEN: ${{ github.token }}
run: |
# Fetch the latest changes from the main branch
git fetch origin main
# Get the list of changed files
git diff origin/main...HEAD --name-only > diff
echo "Changed files:"
cat diff
echo "Changed SQL files-:"
# Filter SQL files from the list of changed files
awk '/scripts\/sql\//' diff
# Count the number of changed SQL files in the 'scripts/sql' directory
count=$(awk '/scripts\/sql\//' diff | wc -l)
# Check if no SQL files were changed
if [[ $count == "0" ]]; then
echo "No SQL files were added, Exiting from this action."
exit 0
fi
# Iterate through each changed SQL file
for filename in $(awk '/scripts\/sql\//' diff); do
echo "Checking File: $filename"
# Check if the SQL file name is in the correct format (i.e., it ends with either '.up.sql' or '.down.sql')
if [[ "$filename" =~ \.(up|down)\.sql$ ]]; then
# Print a message that the file name is in the correct format
echo "File name: $filename is in the correct format"
else
# Print an error message
echo "Error: The SQL file name is not in the correct format: $filename."
# Post a comment on a GitHub pull request with the error message
gh pr comment $pr_no --body "The SQL file name: $filename is not in the correct format."
# Exit the script with a non-zero status code
exit 1
fi
# Navigate to the SQL files directory
sql_dir="scripts/sql"
echo "Current directory: $(pwd)"
cd "$sql_dir"
echo "SQL files directory: $(pwd)"
# Extract the migration number from the SQL file name
migration_no=$(echo "$filename" | cut -d "/" -f 3 | cut -d "_" -f 1)
echo "Migration Number: $migration_no"
# Count the number of files with the same migration number
migration_files_present_of_this_no=$(ls | cut -d "_" -f 1 | grep -w -c "$migration_no")
# Navigate back to the original directory
cd ../..
# Check the conditions based on the number of files with the same migration number
if [[ $migration_files_present_of_this_no == "2" ]]; then
echo "All looks good for this migration number."
elif [[ $migration_files_present_of_this_no == "1" ]]; then
# Only one file is present for this migration number
echo "Only single migration file was present for migration no.: $migration_no. either up or down migration is missing! EXITING"
gh pr comment $pr_no --body "Error: Only a single migration file was present for this number: $migration_no."
exit 1
else
# Migration number is repeated
echo "Error: Migration number is repeated."
gh pr comment $pr_no --body "Error: The SQL file number: $migration_no is duplicated"
exit 1
fi
done