Skip to content
Draft
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
43 changes: 43 additions & 0 deletions .github/REQUIRED_CHECKS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Required CI Checks Configuration

This document explains how to configure required status checks for this repository to prevent merging broken PRs.

## Overview

The CI workflow includes a special `required` job that depends on all critical CI jobs:
- `svlint` - Linting checks
- `build_and_test` - Build and test the core
- `riscof` - RISCOF compliance tests
- `de1-soc` - DE1-SoC environment build and test

The `required` job will only pass if all these jobs succeed, providing a single status check to mark as required.

## Configuring Branch Protection

To enable required status checks:

1. Go to your repository on GitHub
2. Navigate to **Settings** → **Branches**
3. Under "Branch protection rules", click **Add rule** or edit an existing rule
4. For "Branch name pattern", enter `main` (or your default branch)
5. Check **Require status checks to pass before merging**
6. Search for and select the `required` status check
7. Optionally, also check **Require branches to be up to date before merging**
8. Click **Create** or **Save changes**

## How It Works

The `required` job:
- Uses `if: always()` to ensure it runs even if some jobs fail
- Declares all critical jobs in its `needs` list
- Checks the result of each job and fails if any job didn't succeed
- Provides clear output showing which jobs failed

This pattern ensures:
- A consistent status check name (`required`) that can be marked as required in branch protection
- All critical CI jobs must pass before the PR can be merged
- Clear feedback when jobs fail

## Testing

When you open a PR, you should see the `required` check in the status checks list. It will only pass if all dependent jobs succeed.
32 changes: 32 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -155,3 +155,35 @@ jobs:
with:
name: de1-soc-sof
path: envs/de1-soc/quartus/output_files/utoss-risc-v.sof

# This job ensures all CI checks pass before allowing PR merges
# Mark this job as required in branch protection settings
required:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

i thought that there was some sort a flag i can attach to a job that will mark it as required and not let me merge a PR if its not passing; i remember that such jobs has a "required" tag on them

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

You're right that jobs marked as required in branch protection settings show a "Required" badge in the PR checks UI. However, there's no workflow-level attribute (like required: true) that automatically makes a job required - you still need to configure it in Settings → Branches → Branch protection rules.

The required job I added provides a single, stable status check name that you can mark as required in branch protection. This is the standard pattern because:

  • Individual job names can change when workflows are modified
  • A single gating job is easier to manage than multiple required checks
  • It ensures all critical jobs pass with one configuration

To enable it: Go to Settings → Branches → Add/edit rule for main → Check "Require status checks to pass" → Select the required check.

runs-on: ubuntu-latest
if: always()
needs:
- svlint
- build_and_test
- riscof
- de1-soc
steps:
- name: Check all jobs status
run: |
# Check if any job failed or was cancelled
# Note: skipped status is treated as success since jobs are only skipped intentionally
if [[ "${{ needs.svlint.result }}" == "failure" || \
"${{ needs.svlint.result }}" == "cancelled" || \
"${{ needs.build_and_test.result }}" == "failure" || \
"${{ needs.build_and_test.result }}" == "cancelled" || \
"${{ needs.riscof.result }}" == "failure" || \
"${{ needs.riscof.result }}" == "cancelled" || \
"${{ needs.de1-soc.result }}" == "failure" || \
"${{ needs.de1-soc.result }}" == "cancelled" ]]; then
echo "One or more required jobs failed or were cancelled:"
echo " svlint: ${{ needs.svlint.result }}"
echo " build_and_test: ${{ needs.build_and_test.result }}"
echo " riscof: ${{ needs.riscof.result }}"
echo " de1-soc: ${{ needs.de1-soc.result }}"
exit 1
fi
echo "All required jobs passed successfully!"