diff --git a/require-checks-in-pr/README.md b/require-checks-in-pr/README.md new file mode 100644 index 0000000..a17ee03 --- /dev/null +++ b/require-checks-in-pr/README.md @@ -0,0 +1,70 @@ +# Require Checks in PR + +A GitHub composite action that aggregates the results of multiple jobs into a single required check. Fails if any job failed or was cancelled. Useful for branch protection rules that need a single, stable check name. + +## Why? + +GitHub branch protection rules require a specific check to pass. When using matrix builds or conditional jobs, the check names can vary (e.g., `build (ubuntu, go-1.21)`, `build (macos, go-1.22)`). This action provides a single, stable check name that reports the aggregate status of all jobs. + +## Usage + +```yaml +jobs: + build: + strategy: + matrix: + os: [ubuntu-latest, macos-latest] + runs-on: ${{ matrix.os }} + steps: + - run: echo "Building..." + + test: + needs: build + runs-on: ubuntu-latest + steps: + - run: echo "Testing..." + + ci-required-checks: + name: CI - Required Checks + runs-on: ubuntu-latest + needs: [build, test] + if: ${{ always() }} + steps: + - uses: devantler-tech/actions/require-checks-in-pr@main + with: + job-results: "${{ needs.build.result }} ${{ needs.test.result }}" +``` + +## Inputs + +| Input | Description | Required | Default | +| ------------ | ---------------------------------------------------------- | -------- | ---------------------- | +| `job-results` | Space-separated list of job results to check | Yes | — | +| `check-name` | Display name used in success/failure messages | No | `CI - Required Checks` | + +## Job Result Values + +| Result | Description | Treated as | +| ----------- | ----------------------------------- | ---------- | +| `success` | Job completed successfully | ✅ Pass | +| `skipped` | Job was skipped (condition not met) | ✅ Pass | +| `failure` | Job failed | ❌ Fail | +| `cancelled` | Job was cancelled | ❌ Fail | + +## Custom Check Name + +```yaml + ci-ksail: + name: CI - KSail + runs-on: ubuntu-latest + needs: [build, lint, test] + if: ${{ always() }} + steps: + - uses: devantler-tech/actions/require-checks-in-pr@main + with: + job-results: >- + ${{ needs.build.result }} + ${{ needs.lint.result }} + ${{ needs.test.result }} + check-name: CI - KSail +``` diff --git a/require-checks-in-pr/action.yaml b/require-checks-in-pr/action.yaml new file mode 100644 index 0000000..47f686a --- /dev/null +++ b/require-checks-in-pr/action.yaml @@ -0,0 +1,49 @@ +name: Require Checks in PR +description: | + Aggregates the results of multiple jobs into a single required check. + Fails if any job failed or was cancelled. Skipped jobs are treated as + acceptable (non-failure). Useful for branch protection rules that need + a single, stable check name. +author: devantler-tech + +inputs: + job-results: + description: | + Space-separated list of job results to check. + Each result should be one of: success, failure, cancelled, skipped. + Example: "success success skipped failure" + required: true + check-name: + description: | + Display name used in success/failure messages. + required: false + default: "CI - Required Checks" + +runs: + using: composite + steps: + - name: "📊 Summarize workflow result" + shell: bash + env: + JOB_RESULTS: ${{ inputs.job-results }} + CHECK_NAME: ${{ inputs.check-name }} + run: | + set -Eeuo pipefail + failed=false + + for result in $JOB_RESULTS; do + case "$result" in + success|skipped) + ;; + *) + failed=true + ;; + esac + done + + if [ "$failed" = true ]; then + echo "❌ $CHECK_NAME — at least one job failed or was cancelled." + exit 1 + fi + + echo "✅ $CHECK_NAME — all jobs succeeded or were skipped."