1111 - ' main'
1212 - ' release-**'
1313 - ' develop'
14- - ' hotfix-v0 **'
14+ - ' hotfix-**'
1515 # paths-ignore:
1616 # - 'docs/**'
1717 # - '.github/'
1818 # - 'CHANGELOG/'
1919 # - 'charts/'
2020 # - 'manifests/'
2121 # - 'sample-docker-templates/'
22-
2322jobs :
2423 validate-PR-issue :
2524 runs-on : ubuntu-latest
26- permissions :
27- issues : write
28- contents : read
29- pull-requests : write
30- repository-projects : read
25+
3126 steps :
3227 - name : Checkout repository
3328 uses : actions/checkout@v2
34- with :
35- ref : ${{ github.event.pull_request.head.sha }}
36- fetch-depth : 0
3729
38- - name : Validate Issue Reference
30+ - name : Set up jq (for parsing JSON)
31+ run : sudo apt-get install -y jq
32+
33+ - name : PR Validation Script
3934 env :
40- GH_TOKEN : ${{ github.token }}
4135 PR_BODY : ${{ github.event.pull_request.body }}
4236 PRNUM : ${{ github.event.pull_request.number }}
4337 TITLE : ${{ github.event.pull_request.title }}
38+ GH_TOKEN : ${{ github.token }}
39+ GH_PR_VALIDATOR_TOKEN : ${{ secrets.GH_PR_VALIDATOR_TOKEN }}
40+ BASE_REPO : ${{ github.event.pull_request.base.repo.full_name }}
41+ HEAD_REPO : ${{ github.event.pull_request.head.repo.full_name }}
4442 run : |
45-
46- echo "base or target repo : ${{ github.event.pull_request.base.repo.full_name }}"
47- echo "head or source repo : ${{ github.event.pull_request.head.repo.full_name }}"
48-
49- if [[ ${{ github.event.pull_request.head.repo.full_name }} == ${{ github.event.pull_request.base.repo.full_name }} ]]; then
50- export forked=false
51- else
52- export forked=true
53- fi
54-
55- set -x
56- # Skip validation for documentation or chore PRs
57- if [[ "$TITLE" =~ ^(doc:|docs:|chore:|misc:|Release:|release:|Sync:|sync:) ]]; then
58- echo "Skipping validation for docs/chore PR."
59- echo "PR NUMBER-: $PRNUM "
60- gh pr edit $PRNUM --remove-label "PR:Issue-verification-failed"
61- gh pr edit $PRNUM --add-label "PR:Ready-to-Review"
62- exit 0
63- fi
64-
65- # Define all issue matching patterns
66- patterns=(
67- " ((Fixes|Resolves) #[0-9]+)"
68- " ((Fixes|Resolves) https://github.com/devtron-labs/devtron/issues/[0-9]+)"
69- " ((Fixes|Resolves) devtron-labs/devtron#[0-9]+)"
70- " (Fixes|Resolves):?\\ s+\\ [#([0-9]+)\\ ]"
71- " ((Fixes|Resolves):? #devtron-labs/devops-sprint/issues/[0-9]+)"
72- " ((Fixes|Resolves):? #devtron-labs/sprint-tasks/issues/[0-9]+)"
73- " ((Fixes|Resolves) https://github.com/devtron-labs/devops-sprint/issues/[0-9]+)"
74- " ((Fixes|Resolves) https://github.com/devtron-labs/sprint-tasks/issues/[0-9]+)"
75- " ((Fixes|Resolves):? #devtron-labs/sprint-tasks#[0-9]+)"
76- )
77-
78- # Extract issue number and repo from PR body
79- extract_issue_number() {
80- local pattern="$1" # Get the pattern as the first argument to the function
81-
82- # Check if PR_BODY matches the provided pattern using Bash's =~ regex operator
83- if [[ "$PR_BODY" =~ $pattern ]]; then
84- echo "matched for this pattern $pattern"
85-
86- issue_num=$(echo "$PR_BODY" | grep -oE "$pattern" | grep -oE "[0-9]+")
87-
88- # Extract the repository name (e.g., devtron-labs/devtron) from PR_BODY using grep
89- repo=$(echo "$PR_BODY" | grep -oE "devtron-labs/[a-zA-Z0-9_-]+")
90- echo "Extracted issue number : $issue_num from repo: $repo"
91-
92- return 0 # Return success
93- else
94- echo "No match for the pattern $pattern"
95- fi
96- return 1 # Return failure if no match
97- }
98-
99- issue_num=""
100- repo="devtron-labs/devtron" # Default repo
101- for pattern in "${patterns[@]}"; do
102- echo "Now checking for $pattern"
103- extract_issue_number "$pattern" && break
104- done
105-
106- if [[ -z "$issue_num" ]]; then
107- echo "No valid issue number found."
108- gh pr edit $PRNUM --add-label "PR:Issue-verification-failed"
109- gh pr edit $PRNUM --remove-label "PR:Ready-to-Review"
110- exit 1
111- fi
112-
113- # Form the issue API URL dynamically
114- issue_api_url="https://api.github.com/repos/$repo/issues/$issue_num"
115- echo "API URL : $issue_api_url"
116-
117- if [[ $repo == "devtron-labs/devtron" || $repo == "devtron-labs/devtron-services" || $repo == "devtron-labs/dashboard" ]]; then
118- echo "No extra arguments needed : public repository detected."
119- response_code=$(curl -s -o /dev/null -w "%{http_code}" \
120- " $issue_api_url" )
121-
122- else
123- echo "Adding extra arguments for authentication : private repository detected."
124- response_code=$(curl -s -o /dev/null -w "%{http_code}" \
125- --header "authorization : Bearer ${{ secrets.GH_PR_VALIDATOR_TOKEN }}" \
126- " $issue_api_url" )
127- fi
128-
129- echo "Response Code : $response_code"
130- if [[ "$response_code" -eq 200 ]]; then
131- echo "Issue # $issue_num is valid and exists in $repo."
132-
133- # Fetch the current state of the issue (open/closed) from the private repository.
134- if [[ $repo == "devtron-labs/devtron" || $repo == "devtron-labs/devtron-services" || $repo == "devtron-labs/dashboard" ]]; then
135- echo "No extra arguments needed : public repository detected."
136- issue_status=$(curl -s \
137- " $issue_api_url" | jq '.state'|tr -d \")
138- else
139- echo "Adding extra arguments for authentication : private repository detected."
140- issue_status=$(curl -s \
141- --header "authorization : Bearer ${{ secrets.GH_PR_VALIDATOR_TOKEN }}" \
142- " $issue_api_url" | jq '.state'|tr -d \")
143- fi
144- echo "Issue Number : $issue_num Status: $issue_status"
145- # Check if the issue is still open.
146- # if [[ "$issue_status" == open ]]; then
147- # echo "Issue #$issue_num is opened."
148- if [[ $forked == true ]]; then
149- echo "PR:Ready-to-Review, exiting gracefully"
150- exit 0
151- fi
152- # Remove the 'Issue-verification-failed' label (if present) and add 'Ready-to-Review'.
153- gh pr edit $PRNUM --remove-label "PR:Issue-verification-failed"
154- gh pr edit $PRNUM --add-label "PR:Ready-to-Review"
155- echo "PR:Ready-to-Review, exiting gracefully"
156- exit 0
157- # else
158- # echo "Issue #$issue_num is closed. Please link an open issue to proceed."
159- # if [[ $forked == true ]]; then
160- # echo "PR:Ready-to-Review, exiting gracefully"
161- # exit 0
162- # fi
163- # Add a comment to the PR indicating the issue is not linked correctly.
164- # gh pr comment $PRNUM --body "PR is linked to a closed issue. Please link an open issue to proceed."
165-
166- # Add the 'Issue-verification-failed' label and remove 'Ready-to-Review'.
167- # gh pr edit $PRNUM --add-label "PR:Issue-verification-failed"
168- # gh pr edit $PRNUM --remove-label "PR:Ready-to-Review"
169- # exit 1
170- # fi
171- else
172- echo "Issue not found. Invalid URL or issue number."
173- # Add a comment to the PR indicating the issue is not linked correctly.
174- gh pr comment $PRNUM --body "PR is not linked to a valid issue. Please update the issue link."
175-
176- # Apply 'Issue-verification-failed' label and remove 'Ready-to-Review' label.
177- gh pr edit $PRNUM --add-label "PR:Issue-verification-failed"
178- gh pr edit $PRNUM --remove-label "PR:Ready-to-Review"
179- exit 1
180- fi
181- - name : Check SQL file format and duplicates
182- shell : bash
183- env :
184- pr_no : ${{ github.event.pull_request.number }}
185- GH_TOKEN : ${{ github.token }}
186- run : |
187- # Fetch the latest changes from the main branch
188- git fetch origin main
189-
190- # Get the list of changed files
191- git diff origin/main...HEAD --name-only > diff
192-
193- # Specify the directory containing migration files
194- MIGRATION_DIR="scripts/sql"
195- ls
196- pwd
197-
198- # Print changed files
199- echo "Changed files:"
200- cat diff
201-
202- changed_files=""
203- while IFS= read -r file; do
204- if [[ $file == $MIGRATION_DIR/* && $file == *.up.sql ]]; then
205- changed_files+="$file\n"
206- fi
207- done < diff
208-
209- # Print the filtered .up.sql files
210- echo "Filtered .up.sql files:"
211- echo -e "$changed_files"
212-
213- # Check if there are any .up.sql migration files in the changed files list
214- if [ -z "$changed_files" ]; then
215- echo "No .up.sql migration files found in the changes."
216- else
217- # Extract unique migration numbers from the directory (considering only .up.sql files)
218- existing_migrations=$(ls $MIGRATION_DIR | grep -E "\.up\.sql$" | grep -oE "[0-9]{3}[0-9]{3}[0-9]{2}" | sort | uniq)
219-
220- # Exclude migration numbers from changed files in existing_migrations
221- while read -r file; do
222- migration_number=$(basename "$file" | grep -oE "[0-9]{3}[0-9]{3}[0-9]{2}")
223- existing_migrations=$(echo "$existing_migrations" | grep -v "$migration_number")
224- done <<< "$changed_files"
225-
226- # Validate each changed .up.sql migration file
227- is_valid=true
228- processed_migrations=()
229- while read -r file; do
230- # Extract migration number from the filename
231- migration_number=$(basename "$file" | grep -oE "[0-9]{3}[0-9]{3}[0-9]{2}")
232-
233- # Check if the filename has the full XXXPPPNN format
234- if [[ ! $(basename "$file") =~ ^[0-9]{3}[0-9]{3}[0-9]{2}_ ]]; then
235- echo "Error: Migration file $file does not have the complete XXXPPPNN format."
236- is_valid=false
237- continue
238- fi
239-
240- if [ -z "$migration_number" ]; then
241- echo "Warning: Could not extract migration number from $file."
242- continue
243- fi
244-
245- # Check if this migration number has already been processed
246- if [[ " ${processed_migrations[@]} " =~ " $migration_number " ]]; then
247- continue
248- fi
249- processed_migrations+=("$migration_number")
250-
251- # Check if the migration number is unique
252- if echo "$existing_migrations" | grep -q "$migration_number"; then
253- echo "Error: Migration number $migration_number already exists."
254- is_valid=false
255- fi
256-
257- # Check if the migration number is greater than previous ones
258- last_migration=$(echo "$existing_migrations" | tail -n 1)
259- if [ "$migration_number" -le "$last_migration" ]; then
260- echo "Error: Migration number $migration_number is not greater than the latest ($last_migration)."
261- is_valid=false
262- fi
263-
264- # Check for sequential hotfix requirement (if NN > 01, check for NN-1)
265- hotfix_number=$(echo "$migration_number" | grep -oE "[0-9]{2}$")
266- if [ "$hotfix_number" -gt "01" ]; then
267- previous_hotfix=$(printf "%02d" $((10#$hotfix_number - 1)))
268- expected_previous_number="${migration_number:0:6}$previous_hotfix"
269- if ! echo "$existing_migrations" | grep -q "$expected_previous_number"; then
270- echo "Error: Previous hotfix migration $expected_previous_number not found for $migration_number."
271- is_valid=false
272- fi
273- fi
274-
275- done <<< "$changed_files"
276-
277- if [ "$is_valid" = false ]; then
278- echo "Validation failed. Please fix the errors before merging."
279- gh pr comment $pr_no --body "The Migration files providede inside of the PR does not pass the criteria!!"
280- exit 1
281- fi
282-
283- echo "All .up.sql migration file validations passed."
284- gh pr comment $pr_no --body "The migration files have successfully passed the criteria!!"
285- fi
43+ wget https://raw.githubusercontent.com/devtron-labs/utilities/feat/central-pr-validator/.github/workflows/validateIssue.sh
44+ chmod +x validateIssue.sh
45+ ./validateIssue.sh
0 commit comments