Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions .github/workflows/pr-body-validator.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: 📝 Validate PR Description

on:
pull_request:
types: [opened, edited, reopened]

jobs:
validate-pr-body:
runs-on: ubuntu-latest

steps:
- name: Validate PR Description
shell: bash
env:
PR_BODY: ${{ github.event.pull_request.body }}
run: |
CLEAN_BODY=$(echo "$PR_BODY" | sed 's/\r$//')

if [ -z "${CLEAN_BODY// }" ]; then
echo "❌ PR description is completely empty." >&2
exit 1
fi

REQUIRED_FIELDS=("## Description of Task?" "## Any background context you want to provide?" "## What are the relevant user stories or tasks links from Azure DevOps?")
OPTIONAL_FIELD="## Screenshots (if appropriate)"

current_field=""
declare -A field_content
errors=()

# Parse PR body
while IFS= read -r line; do
trimmed=$(echo "$line" | xargs)
for field in "${REQUIRED_FIELDS[@]}" "$OPTIONAL_FIELD"; do
if [[ "${trimmed,,}" == "${field,,}" ]]; then
current_field="$field"
field_content["$current_field"]=""
continue 2
fi
done

if [ -n "$current_field" ]; then
if [ -z "${field_content[$current_field]}" ]; then
field_content["$current_field"]="$trimmed"
else
field_content["$current_field"]="${field_content[$current_field]}"$'\n'"$trimmed"
fi
fi
done <<< "$CLEAN_BODY"

for field in "${REQUIRED_FIELDS[@]}"; do
content="${field_content[$field]}"
if [ -z "$content" ]; then
errors+=("❌ Missing content for: $field")
elif echo "$content" | grep -iq "^N/A$"; then
errors+=("❌ Field '$field' has invalid content: N/A")
fi
done

if [ ${#errors[@]} -gt 0 ]; then
printf "%s\n" "${errors[@]}" >&2
exit 1
fi

echo "✅ PR description is valid."
35 changes: 35 additions & 0 deletions .github/workflows/validate-branch-name.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: 🔀 Validate Branch Name

on:
pull_request:
types: [opened, reopened]

jobs:
validate-branch-name:
runs-on: ubuntu-latest
steps:
- name: Validate Branch Name Format
shell: bash
env:
BRANCH_NAME: ${{ github.head_ref }}
run: |
echo "🔍 Validating branch name: $BRANCH_NAME"

# Allowed types: ft, bg, ch, rf
# Format: {type}-{summary}-{id}
BRANCH_REGEX='^(ft|bg|ch|rf)-[a-z0-9]+(-[a-z0-9]+){1,2}-[0-9]+$'

if [[ "$BRANCH_NAME" =~ $BRANCH_REGEX ]]; then
echo "✅ Branch name format is valid."
else
echo "❌ Branch name format is invalid: \"$BRANCH_NAME\""
echo ""
echo "Expected format: {story-type}-{summary}-{task-id}"
echo "Where:"
echo " - story-type: ft, bg, ch, or rf"
echo " - summary: 2–3 lowercase words, dash-separated"
echo " - task-id: numeric Azure DevOps task ID"
echo ""
echo "Example: ft-add-auth-token-4521"
exit 1
fi
30 changes: 30 additions & 0 deletions .github/workflows/validate-commits.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: 🧪 Validate Commit Message

on:
push:

jobs:
validate-commit:
runs-on: ubuntu-latest
steps:
- name: Checkout current branch
uses: actions/checkout@v4
with:
fetch-depth: 0 # Needed to see full commit history

- name: Get last non-merge commit message on current branch
id: get_commit
run: |
LAST_COMMIT=$(git log --no-merges -1 --pretty=%s)
echo "📝 Commit subject: $LAST_COMMIT"
echo "commit_msg=$LAST_COMMIT" >> $GITHUB_OUTPUT

- name: Validate commit message
run: |
echo "Validating: '${{ steps.get_commit.outputs.commit_msg }}'"
if [[ ! "${{ steps.get_commit.outputs.commit_msg }}" =~ ^(feat|fix|chore|docs|style|refactor|test|perf|ci|build|revert)(\(.+\))?:\ .+ ]]; then
echo "❌ Invalid commit message format."
echo "💡 Expected format: 'type(scope): description', e.g., 'feat(auth): add login API'"
exit 1
fi
shell: bash
Loading