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
70 changes: 70 additions & 0 deletions require-checks-in-pr/README.md
Original file line number Diff line number Diff line change
@@ -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 }}"
Comment on lines +33 to +35
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The examples pin the action to @main, which is vulnerable to supply-chain risk and can introduce unexpected breaking changes. Prefer pinning to an immutable ref (a commit SHA) or a release tag (e.g., @v1) and update the README examples accordingly.

Copilot uses AI. Check for mistakes.
```

## 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
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The examples pin the action to @main, which is vulnerable to supply-chain risk and can introduce unexpected breaking changes. Prefer pinning to an immutable ref (a commit SHA) or a release tag (e.g., @v1) and update the README examples accordingly.

Copilot uses AI. Check for mistakes.
with:
job-results: >-
${{ needs.build.result }}
${{ needs.lint.result }}
${{ needs.test.result }}
check-name: CI - KSail
```
49 changes: 49 additions & 0 deletions require-checks-in-pr/action.yaml
Original file line number Diff line number Diff line change
@@ -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
Comment on lines +31 to +42
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If job-results is provided as an empty/whitespace-only string, the loop never runs and the action will incorrectly succeed. Add an explicit validation that JOB_RESULTS contains at least one non-whitespace token and fail with a clear message if it doesn't.

Copilot uses AI. Check for mistakes.

Comment on lines +33 to +43
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default (*) branch treats any unexpected value as a failure/cancel and prints a message that may be inaccurate (e.g., typo/unknown result). Consider handling failure|cancelled explicitly, and for unknown values print an error like Unknown job result: <value> (optionally listing allowed values) and exit non-zero to make misconfigurations easier to diagnose.

Suggested change
for result in $JOB_RESULTS; do
case "$result" in
success|skipped)
;;
*)
failed=true
;;
esac
done
unknown_result=""
for result in $JOB_RESULTS; do
case "$result" in
success|skipped)
;;
failure|cancelled)
failed=true
;;
*)
unknown_result="$result"
break
;;
esac
done
if [ -n "$unknown_result" ]; then
echo "❌ $CHECK_NAME — Unknown job result: $unknown_result. Allowed values: success, failure, cancelled, skipped."
exit 1
fi

Copilot uses AI. Check for mistakes.
if [ "$failed" = true ]; then
echo "❌ $CHECK_NAME — at least one job failed or was cancelled."
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default (*) branch treats any unexpected value as a failure/cancel and prints a message that may be inaccurate (e.g., typo/unknown result). Consider handling failure|cancelled explicitly, and for unknown values print an error like Unknown job result: <value> (optionally listing allowed values) and exit non-zero to make misconfigurations easier to diagnose.

Copilot uses AI. Check for mistakes.
exit 1
fi

echo "✅ $CHECK_NAME — all jobs succeeded or were skipped."
Loading