1
+
1
2
name : Validate Pull Request
2
3
3
4
on :
10
11
branches :
11
12
- ' main'
12
13
- ' release-**'
13
- # paths-ignore:
14
- # - 'docs/**'
15
- # - '.github/'
16
- # - 'CHANGELOG/'
17
- # - 'charts/'
18
- # - 'manifests/'
19
- # - 'sample-docker-templates/'
20
-
14
+
21
15
jobs :
22
16
validate-PR-issue :
23
17
runs-on : ubuntu-latest
@@ -31,128 +25,107 @@ jobs:
31
25
32
26
- name : Validate Issue Reference
33
27
env :
34
- GITHUB_TOKEN : ${{ github.token }}
28
+ GH_TOKEN : ${{ github.token }}
35
29
PR_BODY : ${{ github.event.pull_request.body }}
36
- url : ${{ github.event.pull_request.url }}
37
30
PRNUM : ${{ github.event.pull_request.number }}
38
31
TITLE : ${{ github.event.pull_request.title }}
39
32
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 "
43
38
gh pr edit $PRNUM --remove-label "PR:Issue-verification-failed"
44
39
gh pr edit $PRNUM --add-label "PR:Ready-to-Review"
45
40
exit 0
46
41
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
65
58
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"
123
62
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"
129
68
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
133
88
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
+
136
99
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'.
144
110
gh pr edit $PRNUM --remove-label "PR:Issue-verification-failed"
145
111
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'.
155
118
gh pr edit $PRNUM --add-label "PR:Issue-verification-failed"
156
119
gh pr edit $PRNUM --remove-label "PR:Ready-to-Review"
157
120
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
158
131
fi
0 commit comments