chore: refactor workflows for improved parallelization #80
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
# ============================================================================= | |
# WORKFLOW: Pull Request Validation | |
# PURPOSE: Ensure code quality and security before merging to main | |
# TRIGGERS: Pull requests targeting main branch | |
# REQUIREMENTS: All checks must pass, changesets required for features/fixes | |
# ============================================================================= | |
name: PR | |
on: | |
pull_request: | |
branches: [main] | |
# Allow only one PR workflow per branch | |
# cancel-in-progress: true cancels old runs when new commits are pushed | |
# This speeds up feedback by focusing on the latest code | |
concurrency: | |
group: ${{ github.workflow }}-${{ github.ref }} | |
cancel-in-progress: true | |
# Minimal permissions for security | |
# contents: read - Read code for analysis | |
# security-events: write - Upload security findings | |
# actions: read - Access workflow artifacts | |
permissions: | |
contents: read | |
security-events: write | |
actions: read | |
jobs: | |
# ============================================================================= | |
# PARALLEL VALIDATION | |
# All checks run simultaneously for faster feedback | |
# ============================================================================= | |
# Core validation: audit, typecheck, lint, format, tests | |
# upload-coverage: true generates coverage reports for visibility | |
# FAILS IF: Any check fails or coverage drops below 80% | |
validate: | |
uses: ./.github/workflows/reusable-validate.yml | |
secrets: | |
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} | |
with: | |
validate-changesets: true | |
# Security: Static security analysis for TypeScript/JavaScript | |
# Scans for: XSS, injection attacks, insecure patterns | |
# Results appear in Security tab of the PR | |
security: | |
uses: ./.github/workflows/reusable-security.yml | |
# ============================================================================= | |
# DOCKER CONTAINER VALIDATION | |
# Build and scan Docker image for vulnerabilities | |
# ============================================================================= | |
# Docker: Build and security scan container image | |
# Only runs when ENABLE_DOCKER_RELEASE is configured | |
# Scans for: CVEs, misconfigurations, secrets in image layers | |
docker: | |
if: vars.ENABLE_DOCKER_RELEASE == 'true' | |
uses: ./.github/workflows/reusable-docker.yml | |
with: | |
platforms: 'linux/amd64' # Single platform for faster PR validation | |
save-artifact: false # Don't save artifact for PRs | |
image-name: 'sonarqube-mcp-server-pr' | |
# ============================================================================= | |
# FINAL STATUS CHECK | |
# Single job to verify all parallel checks succeeded | |
# ============================================================================= | |
# Final status check - ensures all jobs passed | |
# Required for branch protection rules | |
pr-status: | |
needs: [validate, security, docker] | |
if: always() # Run even if previous jobs failed | |
runs-on: ubuntu-latest | |
steps: | |
- name: Check status | |
# Aggregates results from all parallel jobs | |
# This single check can be used as a required status check | |
# FAILS IF: Any validation job failed | |
# Common failures: | |
# - validate: Tests fail, coverage below 80%, lint errors, workflow errors, missing changesets | |
# - security: Security vulnerabilities, vulnerable dependencies, audit failures | |
# - docker: Container vulnerabilities or build failures (when enabled) | |
run: | | |
# Check Docker job status | |
# The job can be: | |
# - success: Job ran and passed | |
# - failure: Job ran and failed | |
# - cancelled: Job was cancelled | |
# - skipped: Job condition was not met (e.g., ENABLE_DOCKER_RELEASE != 'true') | |
DOCKER_RESULT="${{ needs.docker.result }}" | |
# Docker is acceptable if it succeeded or was skipped | |
# It's a failure only if it actually ran and failed/was cancelled | |
if [ "$DOCKER_RESULT" == "failure" ] || [ "$DOCKER_RESULT" == "cancelled" ]; then | |
DOCKER_FAILED=true | |
else | |
DOCKER_FAILED=false | |
fi | |
if [ "${{ needs.validate.result }}" != "success" ] || \ | |
[ "${{ needs.security.result }}" != "success" ] || \ | |
[ "$DOCKER_FAILED" == "true" ]; then | |
echo "❌ PR validation failed" | |
# Check individual job results for debugging | |
echo "Validate: ${{ needs.validate.result }}" | |
echo "Security: ${{ needs.security.result }}" | |
echo "Docker: ${{ needs.docker.result }}" | |
exit 1 | |
fi | |
echo "✅ All PR checks passed" |