From 62050538c3fb2ef38a4ea2c24424287c60bc313f Mon Sep 17 00:00:00 2001 From: Test User Date: Sun, 18 Jan 2026 17:43:33 +0100 Subject: [PATCH] feat(workflows): add gate jobs for branch protection in CI, lint, and security workflows - Introduced `ci-complete`, `lint-complete`, and `security-summary` jobs to aggregate results from respective workflows. - Each job checks the success of dependent jobs and provides a single status check for branch protection. - Enhances visibility of CI, linting, and security results, ensuring all checks pass before merging. --- .github/workflows/ci.yml | 24 ++++++++++++++++ .github/workflows/lint.yml | 20 ++++++++++++++ .github/workflows/quality-security.yml | 38 ++++++++++++++++++++++++++ 3 files changed, 82 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 64d738b9..b1f2e0b2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -139,3 +139,27 @@ jobs: - name: Build application working-directory: apps/frontend run: npm run build + + # -------------------------------------------------------------------------- + # Gate Job - Single check for branch protection + # -------------------------------------------------------------------------- + ci-complete: + name: CI Complete + runs-on: ubuntu-latest + needs: [test-python, test-frontend] + if: always() + steps: + - name: Check all CI jobs passed + run: | + echo "CI Job Results:" + echo " test-python: ${{ needs.test-python.result }}" + echo " test-frontend: ${{ needs.test-frontend.result }}" + echo "" + + if [[ "${{ needs.test-python.result }}" != "success" ]] || \ + [[ "${{ needs.test-frontend.result }}" != "success" ]]; then + echo "❌ One or more CI jobs failed" + exit 1 + fi + + echo "✅ All CI checks passed" diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index b359cbe5..f612b9f2 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -67,3 +67,23 @@ jobs: # biome ci fails on errors by default; warnings are reported but don't block # Use --error-on-warnings when ready to enforce all rules run: biome ci . + + # -------------------------------------------------------------------------- + # Gate Job - Single check for branch protection + # -------------------------------------------------------------------------- + lint-complete: + name: Lint Complete + runs-on: ubuntu-latest + needs: [python, typescript] + if: always() + steps: + - name: Check lint results + run: | + if [[ "${{ needs.python.result }}" != "success" ]] || \ + [[ "${{ needs.typescript.result }}" != "success" ]]; then + echo "❌ Linting failed" + echo " Python: ${{ needs.python.result }}" + echo " TypeScript: ${{ needs.typescript.result }}" + exit 1 + fi + echo "✅ All linting passed" diff --git a/.github/workflows/quality-security.yml b/.github/workflows/quality-security.yml index 471188d1..59f63bba 100644 --- a/.github/workflows/quality-security.yml +++ b/.github/workflows/quality-security.yml @@ -141,3 +141,41 @@ jobs: } else { console.log('No high severity security issues found'); } + + # -------------------------------------------------------------------------- + # Gate Job - Single check for branch protection + # -------------------------------------------------------------------------- + security-summary: + name: Security Summary + runs-on: ubuntu-latest + needs: [codeql, python-security] + if: always() + timeout-minutes: 5 + steps: + - name: Check security results + uses: actions/github-script@v7 + with: + script: | + const codeql = '${{ needs.codeql.result }}'; + const bandit = '${{ needs.python-security.result }}'; + + console.log('Security Check Results:'); + console.log(` CodeQL: ${codeql}`); + console.log(` Bandit: ${bandit}`); + + // Only 'failure' is a real failure; 'skipped' is acceptable (e.g., path filters, PR skipping CodeQL) + const acceptable = ['success', 'skipped']; + const codeqlOk = acceptable.includes(codeql); + const banditOk = acceptable.includes(bandit); + const allPassed = codeqlOk && banditOk; + + if (allPassed) { + console.log('\n✅ All security checks passed'); + core.summary.addRaw('## ✅ Security Checks Passed\n\nAll security scans completed successfully.'); + } else { + console.log('\n❌ Some security checks failed'); + core.summary.addRaw('## ❌ Security Checks Failed\n\nOne or more security scans found issues.'); + core.setFailed('Security checks failed'); + } + + await core.summary.write();