Skip to content

Commit f9c0c3a

Browse files
authored
Merge pull request #2094 from devtron-labs/pr-validator-fix
fix: modified the pr-validator script to attach issues correctly
2 parents 68391b5 + 9167b2e commit f9c0c3a

File tree

1 file changed

+87
-114
lines changed

1 file changed

+87
-114
lines changed
Lines changed: 87 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
name: Validate Pull Request
23

34
on:
@@ -10,14 +11,7 @@ on:
1011
branches:
1112
- 'main'
1213
- 'release-**'
13-
# paths-ignore:
14-
# - 'docs/**'
15-
# - '.github/'
16-
# - 'CHANGELOG/'
17-
# - 'charts/'
18-
# - 'manifests/'
19-
# - 'sample-docker-templates/'
20-
14+
2115
jobs:
2216
validate-PR-issue:
2317
runs-on: ubuntu-latest
@@ -31,128 +25,107 @@ jobs:
3125

3226
- name: Validate Issue Reference
3327
env:
34-
GITHUB_TOKEN: ${{ github.token }}
28+
GH_TOKEN: ${{ github.token }}
3529
PR_BODY: ${{ github.event.pull_request.body }}
36-
url: ${{ github.event.pull_request.url }}
3730
PRNUM: ${{ github.event.pull_request.number }}
3831
TITLE: ${{ github.event.pull_request.title }}
3932
run: |
40-
set -x
41-
if [[ "$TITLE" == *"doc:"* || "$TITLE" == *"docs:"* || "$TITLE" == *"chore:"* ]]; then
42-
echo "Skipping validation as this is a PR for documentation or chore."
33+
set -x
34+
# Skip validation for documentation or chore PRs
35+
if [[ "$TITLE" =~ ^(doc:|docs:|chore:|misc:) ]]; then
36+
echo "Skipping validation for docs/chore PR."
37+
echo "PR NUMBER-: $PRNUM "
4338
gh pr edit $PRNUM --remove-label "PR:Issue-verification-failed"
4439
gh pr edit $PRNUM --add-label "PR:Ready-to-Review"
4540
exit 0
4641
fi
47-
48-
### For ex: Fixes #2123
49-
pattern1="((Fixes|Resolves) #[0-9]+)"
50-
51-
### For ex: Resolves https://github.com/devtron-labs/devtron/issues/2123
52-
pattern2="((Fixes|Resolves) https://github.com/devtron-labs/devtron/issues/[0-9]+)"
53-
54-
### For ex: Fixes devtron-labs/devtron#2123
55-
pattern3="((Fixes|Resolves) devtron-labs/devtron#[0-9]+)"
56-
57-
### For ex: Fixes [#4839](https://github.com/devtron-labs/devtron/issues/4839)
58-
pattern4="(Fixes|Resolves):?\s+\[#([0-9]+)\]"
59-
60-
### For ex: Fixes devtron-labs/devops-sprint#2123
61-
pattern5="((Fixes|Resolves):? #devtron-labs/devops-sprint/issues/[0-9]+)"
62-
63-
### For ex: Fixes devtron-labs/sprint-tasks#2123
64-
pattern6="((Fixes|Resolves):? #devtron-labs/sprint-tasks/issues/[0-9]+)"
42+
43+
# Define all issue matching patterns
44+
patterns=(
45+
"((Fixes|Resolves) #[0-9]+)"
46+
"((Fixes|Resolves) https://github.com/devtron-labs/devtron/issues/[0-9]+)"
47+
"((Fixes|Resolves) devtron-labs/devtron#[0-9]+)"
48+
"(Fixes|Resolves):?\\s+\\[#([0-9]+)\\]"
49+
"((Fixes|Resolves):? #devtron-labs/devops-sprint/issues/[0-9]+)"
50+
"((Fixes|Resolves):? #devtron-labs/sprint-tasks/issues/[0-9]+)"
51+
"((Fixes|Resolves) https://github.com/devtron-labs/devops-sprint/issues/[0-9]+)"
52+
"((Fixes|Resolves) https://github.com/devtron-labs/sprint-tasks/issues/[0-9]+)"
53+
)
54+
55+
# Extract issue number and repo from PR body
56+
extract_issue_number() {
57+
local pattern="$1" # Get the pattern as the first argument to the function
6558

66-
### For ex: Resolves https://github.com/devtron-labs/devops-sprint/issues/2123
67-
pattern7="((Fixes|Resolves) https://github.com/devtron-labs/devops-sprint/issues/[0-9]+)"
68-
69-
### For ex: Resolves https://github.com/devtron-labs/sprint-tasks/issues/2123
70-
pattern8="((Fixes|Resolves) https://github.com/devtron-labs/sprint-tasks/issues/[0-9]+)"
71-
72-
# Get the pull request body
73-
PR_BODY=$(jq -r '.pull_request.body' $GITHUB_EVENT_PATH)
74-
echo "PR_BODY = $PR_BODY"
75-
76-
### Checks if PR_BODY matches pattern1 or pattern2 or pattern3 or none
77-
### grep -i (case insensitive) -E (enables extended regular expression in grep) -q (this option suppresses normal output)
78-
if echo "$PR_BODY" | grep -iEq "$pattern1"; then
79-
### Here we are taking only the numerical value ie. issue number
80-
### head -n1 only prints the 1st line.
81-
### grep -o -E "[0-9]+ basically outputs only the number between [0-9]+
82-
echo "$PR_BODY" | grep -iE "$pattern1" | head -n1 | grep -o -E "[0-9]+" | tr -d '\r\n' > issue_num
83-
issue_num=$(cat issue_num)
84-
echo "issue_num is : $issue_num"
85-
elif echo "$PR_BODY" | grep -iEq "$pattern2"; then
86-
echo "$PR_BODY" | grep -iE "$pattern2" | head -n1 | awk -F '/' '{print $NF}' | tr -d '\r\n' > issue_num
87-
issue_num=$(cat issue_num)
88-
echo "issue_num is : $issue_num"
89-
elif echo "$PR_BODY" | grep -iEq "$pattern3"; then
90-
echo "$PR_BODY" | grep -iE "$pattern3" | head -n1 | awk -F '#' '{print $NF}' | tr -d '\r\n' > issue_num
91-
issue_num=$(cat issue_num)
92-
echo "issue_num is : $issue_num"
93-
elif echo "$PR_BODY" | grep -iEq "$pattern4"; then
94-
echo "$PR_BODY" | grep -oP "$pattern4" | head -n1 | grep -oP '#\K[0-9]+' | tr -d '\r\n' > issue_num
95-
issue_num=$(cat issue_num)
96-
echo "issue_num is : $issue_num"
97-
elif echo "$PR_BODY" | grep -iEq "$pattern5|$pattern6"; then
98-
url_1="$(echo "$PR_BODY" | grep -iE "$pattern5" | head -n1 | awk '{print $2}')"
99-
url_2=${url_1:1}
100-
url=https://github.com/$url_2
101-
echo "$PR_BODY" | grep -oP "$pattern4" | head -n1 | grep -oP '#\K[0-9]+' | tr -d '\r\n' > issue_num
102-
issue_num=$(cat issue_num)
103-
echo "issue_num is : $issue_num"
104-
elif echo "$PR_BODY" | grep -iEq "$pattern7|$pattern8"; then
105-
url="$(echo "$PR_BODY" | grep -iE "$pattern7|$pattern8" | head -n1 | awk '{print $2}')"
106-
echo "$PR_BODY" | grep -oP "$pattern4" | head -n1 | grep -oP '#\K[0-9]+' | tr -d '\r\n' > issue_num
107-
issue_num=$(cat issue_num)
108-
echo "issue_num is : $issue_num"
109-
else
110-
echo "No Issue number detected hence failing the PR Validation check."
111-
gh pr edit $PRNUM --add-label "PR:Issue-verification-failed"
112-
gh pr edit $PRNUM --remove-label "PR:Ready-to-Review"
113-
exit 1
114-
fi
115-
116-
if echo "$PR_BODY" | grep -iEq "$pattern5|$pattern6|$pattern7|$pattern8"; then
117-
echo $url
118-
else
119-
### Here we are setting the Internal Field Separator to "/"
120-
### read -r -> reads input from variable $url
121-
### -a url_parts -> tells read command to store input into an array named url_parts[]
122-
IFS="/" read -r -a url_parts <<< "$url"
59+
# Check if PR_BODY matches the provided pattern using Bash's =~ regex operator
60+
if [[ "$PR_BODY" =~ $pattern ]]; then
61+
echo "matched for this pattern $pattern"
12362

124-
# Remove the last two elements (repos and the issue number)
125-
unset url_parts[-1]
126-
unset url_parts[-1]
127-
# Reattach the URL pieces
128-
url=$(IFS=/; echo "${url_parts[*]}")
63+
issue_num=$(echo "$PR_BODY" | grep -oE "$pattern" | grep -oE "[0-9]+")
64+
65+
# Extract the repository name (e.g., devtron-labs/devtron) from PR_BODY using grep
66+
repo=$(echo "$PR_BODY" | grep -oE "devtron-labs/[a-zA-Z0-9_-]+")
67+
echo "Extracted issue number: $issue_num from repo: $repo"
12968

130-
# Add the issue number to the URL
131-
url="${url}/issues/${issue_num}"
132-
echo "$url"
69+
return 0 # Return success
70+
else
71+
echo "No match for the pattern $pattern"
72+
fi
73+
return 1 # Return failure if no match
74+
}
75+
76+
issue_num=""
77+
repo="devtron-labs/devtron" # Default repo
78+
for pattern in "${patterns[@]}"; do
79+
echo "Now checking for $pattern"
80+
extract_issue_number "$pattern" && break
81+
done
82+
83+
if [[ -z "$issue_num" ]]; then
84+
echo "No valid issue number found."
85+
gh pr edit $PRNUM --add-label "PR:Issue-verification-failed"
86+
gh pr edit $PRNUM --remove-label "PR:Ready-to-Review"
87+
exit 1
13388
fi
134-
135-
response_code=$(curl -s -o /dev/null -w "%{http_code}" "$url")
89+
90+
# Form the issue API URL dynamically
91+
issue_api_url="https://api.github.com/repos/$repo/issues/$issue_num"
92+
echo "API URL: $issue_api_url"
93+
94+
# Check if the issue exists in the private repo
95+
response_code=$(curl -s -o /dev/null -w "%{http_code}" \
96+
--header "authorization: Bearer ${{ secrets.GH_PR_VALIDATOR_TOKEN }}" \
97+
"$issue_api_url")
98+
13699
if [[ "$response_code" -eq 200 ]]; then
137-
# Check if issue is open or closed
138-
text=$(curl -s "$url")
139-
echo "checking status of the issue"
140-
# Skipping this condition as the Issue can be in closed state as BE PRs are merged before FE
141-
# if [[ $(echo "$text" | jq -r '.state') == "open" ]]; then
142-
echo "Issue #$issue_num is open"
143-
echo "Issue reference found in the pull request body."
100+
echo "Issue #$issue_num is valid and exists in $repo."
101+
102+
# Fetch the current state of the issue (open/closed) from the private repository.
103+
issue_status=$(curl -s \
104+
--header "authorization: Bearer ${{ secrets.GH_PR_VALIDATOR_TOKEN }}" \
105+
"$issue_api_url" | jq '.state'|tr -d \")
106+
# Check if the issue is still open.
107+
if [[ "$issue_status" == open ]]; then
108+
echo "Issue #$issue_num is opened."
109+
# Remove the 'Issue-verification-failed' label (if present) and add 'Ready-to-Review'.
144110
gh pr edit $PRNUM --remove-label "PR:Issue-verification-failed"
145111
gh pr edit $PRNUM --add-label "PR:Ready-to-Review"
146-
exit 0
147-
# else
148-
# echo "Issue #$issue_num is not open"
149-
# exit 1
150-
# fi
151-
else
152-
echo "Invalid Response Code obtained - error code: $response_code"
153-
echo "No valid issue reference found in the pull request body."
154-
gh pr comment $PRNUM --body "PR is not linked to any issue, please make the corresponding changes in the body."
112+
else
113+
echo "Issue #$issue_num is closed. Please link an open issue to proceed."
114+
# Add a comment to the PR indicating the issue is not linked correctly.
115+
gh pr comment $PRNUM --body "PR is linked to a closed issue. Please link an open issue to proceed."
116+
117+
# Add the 'Issue-verification-failed' label and remove 'Ready-to-Review'.
155118
gh pr edit $PRNUM --add-label "PR:Issue-verification-failed"
156119
gh pr edit $PRNUM --remove-label "PR:Ready-to-Review"
157120
exit 1
121+
fi
122+
else
123+
echo "Issue not found. Invalid URL or issue number."
124+
# Add a comment to the PR indicating the issue is not linked correctly.
125+
gh pr comment $PRNUM --body "PR is not linked to a valid issue. Please update the issue link."
126+
127+
# Apply 'Issue-verification-failed' label and remove 'Ready-to-Review' label.
128+
gh pr edit $PRNUM --add-label "PR:Issue-verification-failed"
129+
gh pr edit $PRNUM --remove-label "PR:Ready-to-Review"
130+
exit 1
158131
fi

0 commit comments

Comments
 (0)