Tomasz/con 4203 #3536
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: PR Compliance Checks | |
on: | |
pull_request: | |
types: [opened, synchronize, reopened, ready_for_review] | |
branches: [main] | |
workflow_dispatch: | |
concurrency: | |
group: ${{ github.workflow }}-${{ github.ref }} | |
cancel-in-progress: true | |
jobs: | |
conventional-commits: | |
name: Validate Conventional Commits | |
runs-on: ubuntu-latest | |
if: ${{ !github.event.pull_request.draft }} | |
continue-on-error: true | |
permissions: | |
pull-requests: write | |
issues: write | |
contents: read | |
steps: | |
- name: Validate PR title format | |
id: pr-title-check | |
run: | | |
PR_TITLE="${{ github.event.pull_request.title }}" | |
echo "Checking PR title: $PR_TITLE" | |
# Regex pattern for conventional commits | |
PATTERN="^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\(.+\))?!?: .+" | |
if [[ $PR_TITLE =~ $PATTERN ]]; then | |
echo "✅ PR title follows conventional commit format" | |
echo "valid=true" >> $GITHUB_OUTPUT | |
else | |
echo "❌ PR title does not follow conventional commit format" | |
echo "valid=false" >> $GITHUB_OUTPUT | |
# Don't exit with failure - just mark as invalid for comment | |
fi | |
- name: Add PR title guidance comment | |
if: always() && steps.pr-title-check.outputs.valid == 'false' | |
uses: actions/github-script@v8 | |
with: | |
script: | | |
const { data: comments } = await github.rest.issues.listComments({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
issue_number: context.issue.number, | |
}); | |
const botComment = comments.find(comment => | |
comment.user.type === 'Bot' && | |
comment.body.includes('PR Title Format') | |
); | |
if (!botComment) { | |
await github.rest.issues.createComment({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
issue_number: context.issue.number, | |
body: [ | |
"## ⚠️ PR Title Format", | |
"", | |
"Your PR title doesn't follow the conventional commit format, but **this won't block your PR from being merged**. We recommend using this format for better project organization.", | |
"", | |
"### Expected Format:", | |
"```", | |
"<type>[optional scope]: <description>", | |
"```", | |
"", | |
"### Examples:", | |
"- `feat: add changelog generation support`", | |
"- `fix: resolve login redirect issue`", | |
"- `docs: update README with new instructions`", | |
"- `chore: update dependencies`", | |
"", | |
"### Valid Types:", | |
"`feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`, `revert`", | |
"", | |
"This helps with:", | |
"- 📝 Automatic changelog generation", | |
"- 🚀 Automated semantic versioning", | |
"- 📊 Better project history tracking", | |
"", | |
"*This is a non-blocking warning - your PR can still be merged without fixing this.*" | |
].join('\n') | |
}); | |
} | |
- name: Ensure job always succeeds | |
if: always() | |
run: echo "✅ Conventional commits check completed (warning only)" | |
security-audit: | |
name: Security Audit | |
runs-on: ubuntu-latest | |
if: ${{ !github.event.pull_request.draft }} | |
permissions: | |
security-events: write | |
contents: read | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v5 | |
- name: Setup Node.js | |
uses: actions/setup-node@v5 | |
with: | |
node-version-file: ".nvmrc" | |
cache: "npm" | |
- name: Install dependencies | |
run: npm ci | |
- name: Fix vulnerabilities | |
run: npm audit fix | |
- name: Run npm audit | |
run: npm audit --audit-level=moderate | |
- name: Initialize CodeQL | |
uses: github/codeql-action/init@v4 | |
with: | |
languages: javascript | |
- name: Perform CodeQL Analysis | |
uses: github/codeql-action/analyze@v4 | |
# Use this for any files that we want to be certain exist | |
# Basically creates a forcing function to discuss were anyone to want to remove them | |
file-validation: | |
name: Required Files Check | |
runs-on: ubuntu-latest | |
if: ${{ !github.event.pull_request.draft }} | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v5 | |
- name: Check required files | |
run: | | |
required_files=( | |
"package.json" | |
"package-lock.json" | |
"README.md" | |
"LICENSE" | |
".gitignore" | |
"tsconfig.json" | |
"SECURITY.md" | |
"CONTRIBUTING.md" | |
".nvmrc" | |
".prettierrc" | |
".prettierignore" | |
) | |
missing_files=() | |
for file in "${required_files[@]}"; do | |
if [[ ! -f "$file" ]]; then | |
missing_files+=("$file") | |
fi | |
done | |
if [[ ${#missing_files[@]} -gt 0 ]]; then | |
echo "❌ Missing required files:" | |
printf '%s\n' "${missing_files[@]}" | |
exit 1 | |
else | |
echo "✅ All required files present" | |
fi | |
compliance-summary: | |
name: Compliance Summary | |
runs-on: ubuntu-latest | |
needs: [conventional-commits, security-audit, file-validation] | |
if: always() && !github.event.pull_request.draft | |
steps: | |
- name: Check compliance status | |
run: | | |
echo "## 🔍 Compliance Check Results" >> $GITHUB_STEP_SUMMARY | |
echo "" >> $GITHUB_STEP_SUMMARY | |
if [[ "${{ needs.conventional-commits.result }}" == "success" ]]; then | |
echo "✅ Conventional Commits: PASSED" >> $GITHUB_STEP_SUMMARY | |
elif [[ "${{ needs.conventional-commits.result }}" == "failure" ]]; then | |
echo "⚠️ Conventional Commits: WARNING (non-blocking)" >> $GITHUB_STEP_SUMMARY | |
else | |
echo "❌ Conventional Commits: SKIPPED" >> $GITHUB_STEP_SUMMARY | |
fi | |
if [[ "${{ needs.security-audit.result }}" == "success" ]]; then | |
echo "✅ Security Audit: PASSED" >> $GITHUB_STEP_SUMMARY | |
else | |
echo "❌ Security Audit: FAILED" >> $GITHUB_STEP_SUMMARY | |
fi | |
if [[ "${{ needs.file-validation.result }}" == "success" ]]; then | |
echo "✅ File Validation: PASSED" >> $GITHUB_STEP_SUMMARY | |
else | |
echo "❌ File Validation: FAILED" >> $GITHUB_STEP_SUMMARY | |
fi | |
echo "" >> $GITHUB_STEP_SUMMARY | |
echo "📊 **Overall Status**: ${{ job.status }}" >> $GITHUB_STEP_SUMMARY |