Skip to content

fix: fix cd-trigger-plugin #9745

fix: fix cd-trigger-plugin

fix: fix cd-trigger-plugin #9745

name: Validate Pull Request
on:
pull_request:
types:
- opened
- synchronize
- edited
- reopened
branches:
- 'main'
- 'release-**'
- 'develop'
# 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
repository-projects: read
steps:
- name: Checkout repository
uses: actions/checkout@v2
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
- name: Validate Issue Reference
env:
GH_TOKEN: ${{ github.token }}
PR_BODY: ${{ github.event.pull_request.body }}
PRNUM: ${{ github.event.pull_request.number }}
TITLE: ${{ github.event.pull_request.title }}
run: |
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
set -x
# Skip validation for documentation or chore PRs
if [[ "$TITLE" =~ ^(doc:|docs:|chore:|misc:) ]]; then
echo "Skipping validation for docs/chore PR."
echo "PR NUMBER-: $PRNUM "
gh pr edit $PRNUM --remove-label "PR:Issue-verification-failed"
gh pr edit $PRNUM --add-label "PR:Ready-to-Review"
exit 0
fi
# Define all issue matching patterns
patterns=(
"((Fixes|Resolves) #[0-9]+)"
"((Fixes|Resolves) https://github.com/devtron-labs/devtron/issues/[0-9]+)"
"((Fixes|Resolves) devtron-labs/devtron#[0-9]+)"
"(Fixes|Resolves):?\\s+\\[#([0-9]+)\\]"
"((Fixes|Resolves):? #devtron-labs/devops-sprint/issues/[0-9]+)"
"((Fixes|Resolves):? #devtron-labs/sprint-tasks/issues/[0-9]+)"
"((Fixes|Resolves) https://github.com/devtron-labs/devops-sprint/issues/[0-9]+)"
"((Fixes|Resolves) https://github.com/devtron-labs/sprint-tasks/issues/[0-9]+)"
"((Fixes|Resolves):? #devtron-labs/sprint-tasks#[0-9]+)"
)
# Extract issue number and repo from PR body
extract_issue_number() {
local pattern="$1" # Get the pattern as the first argument to the function
# Check if PR_BODY matches the provided pattern using Bash's =~ regex operator
if [[ "$PR_BODY" =~ $pattern ]]; then
echo "matched for this pattern $pattern"
issue_num=$(echo "$PR_BODY" | grep -oE "$pattern" | grep -oE "[0-9]+")
# Extract the repository name (e.g., devtron-labs/devtron) from PR_BODY using grep
repo=$(echo "$PR_BODY" | grep -oE "devtron-labs/[a-zA-Z0-9_-]+")
echo "Extracted issue number: $issue_num from repo: $repo"
return 0 # Return success
else
echo "No match for the pattern $pattern"
fi
return 1 # Return failure if no match
}
issue_num=""
repo="devtron-labs/devtron" # Default repo
for pattern in "${patterns[@]}"; do
echo "Now checking for $pattern"
extract_issue_number "$pattern" && break
done
if [[ -z "$issue_num" ]]; then
echo "No valid issue number found."
gh pr edit $PRNUM --add-label "PR:Issue-verification-failed"
gh pr edit $PRNUM --remove-label "PR:Ready-to-Review"
exit 1
fi
# Form the issue API URL dynamically
issue_api_url="https://api.github.com/repos/$repo/issues/$issue_num"
echo "API URL: $issue_api_url"
if [[ $repo == "devtron-labs/devtron" || $repo == "devtron-labs/devtron-services" || $repo == "devtron-labs/dashboard" ]]; then
echo "No extra arguments needed: public repository detected."
response_code=$(curl -s -o /dev/null -w "%{http_code}" \
"$issue_api_url")
else
echo "Adding extra arguments for authentication: private repository detected."
response_code=$(curl -s -o /dev/null -w "%{http_code}" \
--header "authorization: Bearer ${{ secrets.GH_PR_VALIDATOR_TOKEN }}" \
"$issue_api_url")
fi
echo "Response Code: $response_code"
if [[ "$response_code" -eq 200 ]]; then
echo "Issue #$issue_num is valid and exists in $repo."
# Fetch the current state of the issue (open/closed) from the private repository.
if [[ $repo == "devtron-labs/devtron" || $repo == "devtron-labs/devtron-services" || $repo == "devtron-labs/dashboard" ]]; then
echo "No extra arguments needed: public repository detected."
issue_status=$(curl -s \
"$issue_api_url"| jq '.state'|tr -d \")
else
echo "Adding extra arguments for authentication: private repository detected."
issue_status=$(curl -s \
--header "authorization: Bearer ${{ secrets.GH_PR_VALIDATOR_TOKEN }}" \
"$issue_api_url"| jq '.state'|tr -d \")
fi
echo "Issue Status: $issue_status"
# Check if the issue is still open.
if [[ "$issue_status" == open ]]; then
echo "Issue #$issue_num is opened."
if [[ $forked == true ]]; then
echo "PR:Ready-to-Review, exiting gracefully"
exit 0
fi
# Remove the 'Issue-verification-failed' label (if present) and add 'Ready-to-Review'.
gh pr edit $PRNUM --remove-label "PR:Issue-verification-failed"
gh pr edit $PRNUM --add-label "PR:Ready-to-Review"
else
echo "Issue #$issue_num is closed. Please link an open issue to proceed."
if [[ $forked == true ]]; then
echo "PR:Ready-to-Review, exiting gracefully"
exit 0
fi
# Add a comment to the PR indicating the issue is not linked correctly.
gh pr comment $PRNUM --body "PR is linked to a closed issue. Please link an open issue to proceed."
# Add the 'Issue-verification-failed' label and remove 'Ready-to-Review'.
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 "Issue not found. Invalid URL or issue number."
# Add a comment to the PR indicating the issue is not linked correctly.
gh pr comment $PRNUM --body "PR is not linked to a valid issue. Please update the issue link."
# Apply 'Issue-verification-failed' label and remove 'Ready-to-Review' label.
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
# Specify the directory containing migration files
MIGRATION_DIR="scripts/sql"
ls
pwd
# Print changed files
echo "Changed files:"
cat diff
changed_files=""
while IFS= read -r file; do
if [[ $file == $MIGRATION_DIR/* && $file == *.up.sql ]]; then
changed_files+="$file\n"
fi
done < diff
# Print the filtered .up.sql files
echo "Filtered .up.sql files:"
echo -e "$changed_files"
# Check if there are any .up.sql migration files in the changed files list
if [ -z "$changed_files" ]; then
echo "No .up.sql migration files found in the changes."
else
# Extract unique migration numbers from the directory (considering only .up.sql files)
existing_migrations=$(ls $MIGRATION_DIR | grep -E "\.up\.sql$" | grep -oE "[0-9]{3}[0-9]{3}[0-9]{2}" | sort | uniq)
# Exclude migration numbers from changed files in existing_migrations
while read -r file; do
migration_number=$(basename "$file" | grep -oE "[0-9]{3}[0-9]{3}[0-9]{2}")
existing_migrations=$(echo "$existing_migrations" | grep -v "$migration_number")
done <<< "$changed_files"
# Validate each changed .up.sql migration file
is_valid=true
processed_migrations=()
while read -r file; do
# Extract migration number from the filename
migration_number=$(basename "$file" | grep -oE "[0-9]{3}[0-9]{3}[0-9]{2}")
# Check if the filename has the full XXXPPPNN format
if [[ ! $(basename "$file") =~ ^[0-9]{3}[0-9]{3}[0-9]{2}_ ]]; then
echo "Error: Migration file $file does not have the complete XXXPPPNN format."
is_valid=false
continue
fi
if [ -z "$migration_number" ]; then
echo "Warning: Could not extract migration number from $file."
continue
fi
# Check if this migration number has already been processed
if [[ " ${processed_migrations[@]} " =~ " $migration_number " ]]; then
continue
fi
processed_migrations+=("$migration_number")
# Check if the migration number is unique
if echo "$existing_migrations" | grep -q "$migration_number"; then
echo "Error: Migration number $migration_number already exists."
is_valid=false
fi
# Check if the migration number is greater than previous ones
last_migration=$(echo "$existing_migrations" | tail -n 1)
if [ "$migration_number" -le "$last_migration" ]; then
echo "Error: Migration number $migration_number is not greater than the latest ($last_migration)."
is_valid=false
fi
# Check for sequential hotfix requirement (if NN > 01, check for NN-1)
hotfix_number=$(echo "$migration_number" | grep -oE "[0-9]{2}$")
if [ "$hotfix_number" -gt "01" ]; then
previous_hotfix=$(printf "%02d" $((10#$hotfix_number - 1)))
expected_previous_number="${migration_number:0:6}$previous_hotfix"
if ! echo "$existing_migrations" | grep -q "$expected_previous_number"; then
echo "Error: Previous hotfix migration $expected_previous_number not found for $migration_number."
is_valid=false
fi
fi
done <<< "$changed_files"
if [ "$is_valid" = false ]; then
echo "Validation failed. Please fix the errors before merging."
gh pr comment $pr_no --body "The Migration files providede inside of the PR does not pass the criteria!!"
exit 1
fi
echo "All .up.sql migration file validations passed."
gh pr comment $pr_no --body "The migration files have successfully passed the criteria!!"
fi