Skip to content

chore: syntax fixes

chore: syntax fixes #2

Workflow file for this run

name: Centralized PR Validation
on:
workflow_call:
inputs:
validate_sql:
description: "Check SQL migrations"
required: true
type: boolean
secrets:
GH_PR_VALIDATOR_TOKEN:
jobs:
pr-validation:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Set up jq (for parsing JSON)
run: sudo apt-get install -y jq
- name: Debug Print token
run: echo "Token value: ${{ secrets.GH_PR_VALIDATOR_TOKEN }}" #REMOVE AFTER DEBUGGING

Check failure on line 25 in .github/workflows/pr-validator.yaml

View workflow run for this annotation

GitHub Actions / .github/workflows/pr-validator.yaml

Invalid workflow file

You have an error in your yaml syntax on line 25
- name: PR Validation Script
env:
PR_BODY: ${{ github.event.pull_request.body }}
PRNUM: ${{ github.event.pull_request.number }}
TITLE: ${{ github.event.pull_request.title }}
GH_PR_VALIDATOR_TOKEN: ${{ secrets.GH_PR_VALIDATOR_TOKEN }}
BASE_REPO: ${{ github.event.pull_request.base.repo.full_name }}
HEAD_REPO: ${{ github.event.pull_request.head.repo.full_name }}
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 }}"
echo "$GH_PR_VALIDATOR_TOKEN" | gh auth login --with-token
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:|Release:|release:|Sync:|sync:) ]]; 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|sprint-tasks|devops-sprint|devtron-enterprise)/issues/[0-9]+)"
"((Fixes|Resolves):? https://github.com/devtron-labs/(devtron|sprint-tasks|devops-sprint|devtron-enterprise)/issues/[0-9]+)"
"((Fixes|Resolves) devtron-labs/devtron#[0-9]+)"
"((Fixes|Resolves) devtron-labs/sprint-tasks#[0-9]+)"
"((Fixes|Resolves) devtron-labs/devops-sprint#[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]+)"
)
# 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=$(curl -s -w "%{http_code}" "$issue_api_url") # Get the response body and status code in one go
else
echo "Adding extra arguments for authentication: private repository detected."
response=$(curl -s -w "%{http_code}" --header "Authorization: Bearer ${{ secrets.GH_PR_VALIDATOR_TOKEN }}" \
--header "Accept: application/vnd.github+json" "$issue_api_url")
fi
# Extract HTTP status code from the response
response_code=$(echo "$response" | tail -n 1) # Status code is the last line
response_body=$(echo "$response" | head -n -1) # The body is everything except the last line (status code)
echo "Response Code: $response_code"
html_url=$(echo "$response_body" | jq -r '.html_url') # Extract html_url from the JSON response
# Check if the html_url contains "pull-request"
if [[ "$html_url" == *"pull"* ]]; then
echo "The issue URL contains a pull-request link, marking as invalid."
gh pr comment $PRNUM --body "PR is linked to a pull request URL, which is invalid. 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
# If response_code is 200, proceed with validating the issue
if [[ "$response_code" -eq 200 ]]; then
echo "Issue Number: #$issue_num is valid and exists in Repo: $repo."
gh pr edit $PRNUM --remove-label "PR:Issue-verification-failed"
gh pr edit $PRNUM --add-label "PR:Ready-to-Review"
echo "PR:Ready-to-Review, exiting gracefully"
exit 0
else
echo "Issue not found. Invalid URL or issue number."
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 (if enabled)
if: inputs.validate_sql
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
BASE_BRANCH: ${{ github.event.pull_request.base.ref }}
HEAD_BRANCH: ${{ github.event.pull_request.head.ref }}
run: |
# Fetch the latest changes from the base and target branches
git fetch origin "$BASE_BRANCH"
git fetch origin "$HEAD_BRANCH"
# Get the list of changed files between the base and target branches
git diff origin/"$BASE_BRANCH"...origin/"$HEAD_BRANCH" --name-only > diff
# Specify the directory containing migration files
MIGRATION_DIR="scripts/sql"
# Print the current directory and the contents of the diff file
echo "Current directory:"
pwd
echo "Files changed between $BASE_BRANCH and $HEAD_BRANCH:"
cat diff
# Initialize an empty variable to hold .up.sql files
changed_files=""
# Loop through the list of changed files and filter .up.sql files in the migration directory
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"
# If no .up.sql migration files are found, exit early
if [[ -z "$changed_files" ]]; then
echo "No .up.sql migration files found in the changes."
exit 0
fi
# Extract unique migration numbers from the existing migration files in the directory
existing_migrations=$(ls "$MIGRATION_DIR" | grep -E "\.up\.sql$" | grep -oE "[0-9]{6}[0-9]{2}" | sort -n | uniq)
# Loop through each changed .up.sql file to validate
is_valid=true
processed_migrations=()
while IFS= read -r file; do
# Extract migration number from the file
migration_number=$(basename "$file" | grep -oE "[0-9]{6}[0-9]{2}")
# Validate the file name format (ensure it has the full XXXPPPNN format)
if [[ ! $(basename "$file") =~ ^[0-9]{6}[0-9]{2}_ ]]; then
echo "Error: Migration file $file does not have the complete XXXPPPNN format."
is_valid=false
continue
fi
# Check if we could extract a valid migration number
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 already exists
if echo "$existing_migrations" | grep -q "$migration_number"; then
echo "Error: Migration number $migration_number already exists in the directory."
is_valid=false
fi
# Check if the migration number is greater than previous ones (order check)
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"
# Final validation check
if [ "$is_valid" = false ]; then
echo "Validation failed. Please fix the errors before merging."
gh pr comment "$pr_no" --body "The Migration files provided inside the PR do 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!!"
exit 0