Skip to content

feat(WO-6): Test

feat(WO-6): Test #42

Workflow file for this run

name: Auto-Merge PRs
on:
pull_request:
types: [opened, labeled, synchronize, reopened, edited]
pull_request_review:
types: [ submitted ]
jobs:
validate-pr-title-and-description:
runs-on: ubuntu-22.04
strategy:
fail-fast: true
steps:
- name: Validate PR Title
run: |
PR_TITLE="${{ github.event.pull_request.title }}"
if [[ ! "$PR_TITLE" =~ ^(feat|fix|docs|style|refactor|perf|test|build|chore)\(WO-[0-9]+\):\ .+$ ]]; then
echo "❌ ERROR: PR title does not follow the required format!"
exit 1
fi
- name: Validate PR Description
run: |
PR_DESCRIPTION="${{ github.event.pull_request.body }}"
# Check if description is empty
if [[ -z "$PR_DESCRIPTION" ]]; then
echo "❌ ERROR: PR description cannot be empty!"
exit 1
fi
# Check if description follows the commit message convention (e.g., imperative tone)
if [[ ! "$PR_DESCRIPTION" =~ ^(Add|Fix|Improve|Update|Remove|Refactor|Implement|Optimize|Enhance|Correct|Revert|Modify|Deprecate|Restructure|Format|Document)\ .+ ]]; then
echo "❌ ERROR: PR description does not follow the standard commit message convention!"
exit 1
fi
# Check if description has at least 3 lines (adjust number as needed)
LINE_COUNT=$(echo "$PR_DESCRIPTION" | awk 'NF {count++} END {print count}')
if [[ "$LINE_COUNT" -lt 3 ]]; then
echo "❌ ERROR: PR description must contain at least 3 meaningful lines!"
exit 1
fi
echo "✅ PR description is valid."
shell: bash
# Check for reviewers and their approvals
check-if-pr-approve:
runs-on: ubuntu-22.04
strategy:
fail-fast: true
needs: validate-pr-title-and-description
if: success()
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Install GitHub CLI
run: sudo apt update && sudo apt install -y gh
- name: Authenticate with GitHub CLI
run: gh auth status
- name: Fetch PR Details
run: |
PR_NUMBER="${{ github.event.pull_request.number }}"
BASE_BRANCH=$(gh pr view "$PR_NUMBER" --json baseRefName --jq '.baseRefName')
HEAD_BRANCH=$(gh pr view "$PR_NUMBER" --json headRefName --jq '.headRefName')
echo "Base Branch: $BASE_BRANCH"
echo "Head Branch: $HEAD_BRANCH"
echo "PR_NUMBER=$PR_NUMBER" >> $GITHUB_ENV
echo "BASE_BRANCH=$BASE_BRANCH" >> $GITHUB_ENV
echo "HEAD_BRANCH=$HEAD_BRANCH" >> $GITHUB_ENV
- name: Check if PR is Approved
run: |
PR_NUMBER="${{ github.event.pull_request.number }}"
# Fetch assigned reviewers (those explicitly assigned)
ASSIGNED_REVIEWERS=$(gh pr view "$PR_NUMBER" --json reviewRequests --jq '[.reviewRequests[].users[].login]')
# Fetch latest reviewers (who actually reviewed the PR)
LATEST_REVIEWERS=$(gh pr view "$PR_NUMBER" --json latestReviews --jq '[.latestReviews[].author.login]')
# Merge both lists and remove duplicates
ALL_REVIEWERS=$(jq -n --argjson a "$ASSIGNED_REVIEWERS" --argjson b "$LATEST_REVIEWERS" '$a + $b | unique')
# Fetch approvals
APPROVED_REVIEWERS=$(gh pr view "$PR_NUMBER" --json reviews --jq '[.reviews[] | select(.state == "APPROVED") | .author.login]')
# Count reviewers
REVIEWER_COUNT=$(echo "$ALL_REVIEWERS" | jq 'length')
# Fail if no reviewers exist
if [[ "$REVIEWER_COUNT" -eq 0 ]]; then
echo "❌ ERROR: No reviews found. At least one reviewer approval is required before merging."
exit 1
fi
# Ensure all reviewers have approved
for reviewer in $(echo "$ALL_REVIEWERS" | jq -r '.[]'); do
if ! echo "$APPROVED_REVIEWERS" | jq -r '.[]' | grep -q "^$reviewer$"; then
echo "❌ PR #$PR_NUMBER is NOT fully approved. Missing approval from: $reviewer"
exit 1
fi
done
echo "✅ All assigned and reviewed users have approved. Proceeding with squash merge..."
# Run Tests Before Merging
test-before-merge:
runs-on: ubuntu-22.04
strategy:
fail-fast: true
needs: check-if-pr-approve
if: success()
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Setup Test Environment
uses: ./.github/actions/setup-environment/
with:
env_type: "test"
- name: Run Tests
uses: ./.github/actions/run-tests/
# Prepare for Merge (Squash but Don't Push Yet)
prepare-merge:
runs-on: ubuntu-22.04
strategy:
fail-fast: true
needs: test-before-merge
if: success()
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Install GitHub CLI
run: sudo apt update && sudo apt install -y gh
- name: Authenticate with GitHub CLI
run: gh auth status
- name: Fetch and Checkout PR Branch
run: |
git fetch origin $HEAD_BRANCH
git checkout $HEAD_BRANCH
env:
HEAD_BRANCH: ${{ github.event.pull_request.head.ref }}
- name: Set Merge Message
run: |
if [[ "$COMMIT_COUNT" -eq 1 ]]; then
COMMIT_MESSAGE=$(git log --format=%B -n 1 HEAD)
else
COMMIT_MESSAGE="${{ github.event.pull_request.title }} - ${{ github.event.pull_request.body }}"
fi
# Write the multi-line commit message safely to GITHUB_ENV
{
echo "COMMIT_MESSAGE<<EOF"
echo "$COMMIT_MESSAGE"
echo "EOF"
} >> "$GITHUB_ENV"
- name: Debug Token Permissions
run: |
echo "Checking token permissions..."
gh auth status || echo "GitHub CLI is not authenticated"
gh api user || echo "GitHub API request failed"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Squash Merge PR
run: |
gh pr merge "$PR_NUMBER" --squash --subject "$COMMIT_MESSAGE"
- name: Squash Merge PR (But Don't Push Yet)
run: |
gh pr merge "$PR_NUMBER" --squash --subject "$COMMIT_MESSAGE"
# Run Tests on Merged Code Before Pushing
test-after-merge:
runs-on: ubuntu-22.04
strategy:
fail-fast: true
needs: prepare-merge
if: success()
steps:
- name: Checkout Production Branch
uses: actions/checkout@v4
with:
ref: production
- name: Setup Test Environment
uses: ./.github/actions/setup-environment/
with:
env_type: "test"
- name: Run Tests on Merged Code
uses: ./.github/actions/run-tests/
# Push to Production If All Tests Pass
push-to-production:
runs-on: ubuntu-22.04
strategy:
fail-fast: true
needs: test-after-merge
if: success()
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- name: Fetch PR Details
run: |
HEAD_BRANCH=$(gh pr view "$PR_NUMBER" --json headRefName --jq '.headRefName')
echo "Head Branch: $HEAD_BRANCH"
echo "HEAD_BRANCH=$HEAD_BRANCH" >> $GITHUB_ENV
- name: Checkout Production Branch
uses: actions/checkout@v4
with:
ref: production
- name: Push Merged Code to Production
run: git push origin production
- name: Delete Feature Branch After Merge
run: |
if [[ "$HEAD_BRANCH" != "production" && "$HEAD_BRANCH" != "staging" ]]; then
echo "🗑️ Deleting feature branch: $HEAD_BRANCH"
gh api -X DELETE repos/${{ github.repository }}/git/refs/heads/$HEAD_BRANCH
else
echo "❌ Not deleting protected branch: $HEAD_BRANCH"
fi