Skip to content

Commit bb55256

Browse files
GeekTrainerCopilot
andcommitted
Add tests-passed summary job and update workshop content
- Add tests-passed summary job to run-tests.yml for stable status check name - Fix output reference in composite action (steps.set-output) - Fix output reference in module 7 instructions - Rewrite module 9 for rulesets with tests-passed check name Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent a223cb7 commit bb55256

File tree

4 files changed

+71
-59
lines changed

4 files changed

+71
-59
lines changed

.github/actions/setup-python-env/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ inputs:
1414
outputs:
1515
database-file:
1616
description: 'Path to the seeded database file'
17-
value: ${{ steps.seed.outputs.database-file }}
17+
value: ${{ steps.set-output.outputs.database-file }}
1818

1919
runs:
2020
using: 'composite'

.github/workflows/run-tests.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,15 @@ jobs:
6565
run: npx playwright test
6666
env:
6767
DATABASE_PATH: ${{ steps.seed.outputs.database-file }}
68+
69+
tests-passed:
70+
if: always()
71+
needs: [test-api, test-e2e]
72+
runs-on: ubuntu-latest
73+
steps:
74+
- name: Check results
75+
run: |
76+
if [[ "${{ needs.test-api.result }}" != "success" || "${{ needs.test-e2e.result }}" != "success" ]]; then
77+
echo "One or more jobs failed"
78+
exit 1
79+
fi

content/github-actions/7-custom-actions.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ Let's create a composite action that sets up Python, installs dependencies, and
5656
outputs:
5757
database-file:
5858
description: 'Path to the seeded database file'
59-
value: ${{ steps.seed.outputs.database-file }}
59+
value: ${{ steps.set-output.outputs.database-file }}
6060
6161
runs:
6262
using: 'composite'
@@ -88,7 +88,7 @@ Let's create a composite action that sets up Python, installs dependencies, and
8888

8989
3. Review the key parts of the action:
9090
- **Inputs** provide sensible defaults so callers only need to override what's different.
91-
- **Outputs** reference the `seed` step's output, making the database path available to the calling workflow.
91+
- **Outputs** reference the `set-output` step's output, making the database path available to the calling workflow.
9292
- Each `run` step explicitly declares `shell: bash` as required by composite actions.
9393

9494
## Use the action in the CI workflow

content/github-actions/9-required-workflows.md

Lines changed: 56 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,28 @@
1-
# Required Workflows, Protection & Wrap-Up
1+
# Rulesets, Required Workflows & Wrap-Up
22

33
| [← Reusable Workflows][walkthrough-previous] | [Next: GitHub Actions section overview →][walkthrough-next] |
44
|:-----------------------------------|------------------------------------------:|
55

6-
Building a CI/CD pipeline is only half the battle — you also need to enforce it. Branch protection rules ensure that code can't be merged without passing checks. Required workflows go further, allowing organizations to mandate specific workflows across all repositories. In this final exercise, you'll configure branch protection, explore required workflows and rulesets, and add manual deployment triggers.
6+
Building a CI/CD pipeline is only half the battle — you also need to enforce it. Repository rulesets ensure that code can't be merged without passing checks and getting reviewed. Required workflows go further, allowing organizations to mandate specific workflows across all repositories. In this final exercise, you'll configure a ruleset on `main`, explore required workflows, and wrap up the workshop.
77

88
## Scenario
99

10-
The shelter's CI/CD pipeline is comprehensive, but nothing currently prevents someone from merging code without passing CI — meaning untested code could reach `main` and trigger a deployment. The organization also wants to ensure all repositories run security scanning. Let's lock things down with branch protection and explore how required workflows enforce standards at scale.
10+
The shelter's CI/CD pipeline is comprehensive, but nothing currently prevents someone from merging code without passing CI — meaning untested code could reach `main` and trigger a deployment. The organization also wants to ensure all repositories run security scanning. Let's lock things down with rulesets and explore how required workflows enforce standards at scale.
1111

1212
## Background
1313

14-
GitHub provides two mechanisms for enforcing rules on branches: **branch protection rules** and **repository rulesets**. Both can prevent code from being merged without meeting criteria you define, but they work differently.
15-
16-
### Branch protection rules
17-
18-
[Branch protection rules][about-protected-branches] are the original way to protect important branches. You configure them per-branch (e.g. `main`) to enforce requirements like:
19-
20-
- **Required status checks** — CI must pass before merging.
21-
- **Required pull request reviews** — a minimum number of approvals before merging.
22-
- **Restrict who can push** — limit direct pushes to specific people or teams.
23-
24-
Branch protection rules are available on all GitHub plans (including Free for public repos) and are configured at **Settings > Branches** in each repository.
25-
2614
### Repository rulesets
2715

28-
[Rulesets][about-rulesets] are the newer, more flexible approach. They offer several advantages over branch protection rules:
16+
[Rulesets][about-rulesets] are GitHub's recommended approach for enforcing rules on branches and tags. They offer flexibility and visibility that legacy branch protection rules don't:
2917

30-
| | Branch Protection Rules | Repository Rulesets |
31-
|---|---|---|
32-
| **Layering** | One rule per branch pattern | Multiple rulesets can apply to the same branch; the most restrictive rule wins |
33-
| **Status management** | Delete to disable | Toggle between **Active** and **Disabled** without losing configuration |
34-
| **Visibility** | Only admins can view | Anyone with read access can see active rulesets |
35-
| **Scope** | Repository-level only | Repository-level or organization-wide (GitHub Enterprise) |
36-
| **Bypass permissions** | Limited | Granular bypass for specific roles, teams, or GitHub Apps |
37-
| **Required workflows** | Not supported | Can require specific workflows to pass before merging |
18+
- **Layering** — Multiple rulesets can apply to the same branch; the most restrictive rule wins.
19+
- **Status management** — Toggle between **Active** and **Disabled** without losing configuration.
20+
- **Visibility** — Anyone with read access can see active rulesets (not just admins).
21+
- **Bypass permissions** — Granular bypass for specific roles, teams, or GitHub Apps.
22+
- **Scope** — Repository-level or organization-wide (on GitHub Enterprise).
23+
- **Required workflows** — Rulesets can require specific workflows to pass before merging.
3824

39-
Rulesets and branch protection rules can coexist — when both apply to the same branch, their rules are aggregated and the most restrictive version of each rule applies.
25+
Rulesets are available on all GitHub plans for public repositories, and on GitHub Pro, Team, and Enterprise plans for private repositories.
4026

4127
### Required workflows
4228

@@ -46,53 +32,65 @@ One of the most powerful ruleset features is the ability to **require specific w
4632
2. An organization-wide ruleset requires that workflow for all (or a subset of) repositories.
4733
3. Every PR across those repositories now runs the required workflow automatically — individual repository owners can't skip it.
4834

49-
Common use cases include security scanning, license compliance, and code quality checks. Required workflows via rulesets replaced the earlier "Actions Required Workflows" feature, which was deprecated in October 2023.
35+
Common use cases include security scanning, license compliance, and code quality checks.
5036

51-
## Configure branch protection
37+
## Create a ruleset for `main`
5238

53-
Branch protection rules prevent code from being merged into important branches without meeting specific criteria.
39+
Let's create a ruleset that requires CI to pass and pull requests to be reviewed before merging to `main`.
5440

5541
1. Navigate to your repository on GitHub.
56-
2. Select **Settings** > **Branches** (under **Code and automation** in the sidebar).
57-
3. Select **Add branch protection rule** (or **Add rule** if using rulesets).
58-
4. Under **Branch name pattern**, enter `main`.
59-
5. Enable **Require status checks to pass before merging**.
60-
- Select **Require branches to be up to date before merging**.
61-
- In the search box, search for and select your CI workflow status check names (for example, `test-api` and `build-client`).
62-
6. Optionally enable **Require a pull request before merging** to ensure peer review.
63-
7. Select **Create** (or **Save changes**) to apply the rule.
42+
2. Select **Settings**, then in the left sidebar under **Code and automation**, expand **Rules** and select **Rulesets**.
43+
3. Select **New ruleset** > **New branch ruleset**.
44+
4. Under **Ruleset name**, enter `main-gate`.
45+
5. Set the **Enforcement status** to **Active**.
46+
6. Under **Target branches**, select **Add target** > **Include default branch**. This targets `main`.
47+
7. Under **Branch rules**, enable the following rules:
48+
49+
| Rule | Configuration |
50+
|------|--------------|
51+
| **Require a pull request before merging** | Set **Required approvals** to `1` |
52+
| **Require status checks to pass** | Check **Require branches to be up to date before merging**, then add `tests-passed` as a required check |
53+
| **Block force pushes** | *(enabled by default)* |
54+
55+
8. Select **Create** to save the ruleset.
56+
57+
> [!TIP]
58+
> The `tests-passed` check is a **summary job** in the CI workflow that aggregates results from all matrix and test jobs into a single status check. This is a best practice — matrix jobs report with dynamic names like `test-api (3.12)`, which change if you modify the matrix. A summary job provides one stable check name for rulesets to reference.
6459
6560
> [!TIP]
66-
> If your status checks don't appear in the search, make sure the CI workflow has run at least once on the repository. GitHub only shows status checks that have been reported previously.
61+
> If your status checks don't appear when searching, make sure the CI workflow has run at least once on the repository. GitHub only shows status checks that have been reported previously.
62+
63+
> [!NOTE]
64+
> You can start a ruleset in **Disabled** mode to test it before enforcing. This lets you preview which PRs would be blocked without actually blocking anyone.
6765
68-
## Test the protection
66+
## Test the ruleset
6967

70-
Let's verify that branch protection is working as expected.
68+
Let's verify the ruleset is working.
7169

72-
1. Return to your codespace and open the terminal (<kbd>Ctl</kbd>+<kbd>`</kbd> to toggle). Create a new branch and make a small change (for example, update a comment in `server/app.py`):
70+
1. Return to your codespace and open the terminal (<kbd>Ctl</kbd>+<kbd>`</kbd> to toggle). Create a new branch and make a small change:
7371

7472
```bash
75-
git checkout -b test-protection
73+
git checkout -b test-ruleset
7674
echo "# test change" >> server/app.py
7775
git add server/app.py
78-
git commit -m "Test branch protection"
79-
git push -u origin test-protection
76+
git commit -m "Test ruleset enforcement"
77+
git push -u origin test-ruleset
8078
```
8179

82-
2. Navigate to your repository on GitHub and create a pull request from `test-protection` to `main`.
83-
3. Observe that the **Merge pull request** button is disabled and a message indicates that required status checks must pass.
84-
4. Watch the CI workflow run. Once all required checks pass, the merge button becomes enabled.
85-
5. You can merge or close the pull request — the important thing is that the protection is working!
80+
2. Navigate to your repository on GitHub and create a pull request from `test-ruleset` to `main`.
81+
3. Observe that the **Merge pull request** button is disabled — the required status checks must pass and the PR needs an approving review.
82+
4. Watch the CI workflow run. Even after all checks pass, the merge button remains disabled until the review requirement is satisfied.
83+
5. You can close the pull request — the important thing is that the ruleset is enforced!
8684

8785
> [!IMPORTANT]
88-
> Branch protection ensures that your CI pipeline isn't just a suggestion — it's a requirement. Code cannot reach `main` without passing the checks you've defined.
86+
> Rulesets ensure your CI pipeline isn't just a suggestion — it's a requirement. Code cannot reach `main` without passing the checks and reviews you've defined. Since your deploy workflow only triggers on pushes to `main`, this means only validated, reviewed code gets deployed.
8987
90-
## Required workflows in practice
88+
## Organizational required workflows
9189
92-
As covered in the background section, organization-wide rulesets can mandate that specific workflows run across all repositories. This pairs naturally with the reusable workflows you built in the [previous exercise](8-reusable-workflows.md) — an organization could create a reusable security-scanning workflow in a central `.github` repository, then enforce it via a ruleset so every PR across the organization runs it automatically.
90+
Organization-wide rulesets can mandate that specific workflows run across all repositories. This pairs naturally with the reusable workflows you built in the [previous exercise](8-reusable-workflows.md) — an organization could create a reusable security-scanning workflow in a central `.github` repository, then enforce it via a ruleset so every PR across the organization runs it automatically.
9391
9492
> [!NOTE]
95-
> Organization-wide rulesets with required workflows require a GitHub Enterprise plan. For personal repositories or Free/Team organizations, repository-level branch protection (as configured above) provides similar enforcement.
93+
> Organization-wide rulesets are available on GitHub Team and GitHub Enterprise plans. For personal repositories on the Free plan, repository-level rulesets (as configured above) provide similar enforcement at the repo level.
9694
9795
## Advanced features to explore
9896
@@ -101,6 +99,7 @@ Here are some additional GitHub Actions features you can explore on your own:
10199
- **Service containers**: Spin up databases, caches, or other services alongside your test jobs. Define them under `services` in a job, and GitHub Actions handles the lifecycle for you.
102100
- **Job summaries**: Write Markdown to the `$GITHUB_STEP_SUMMARY` environment file to create rich, formatted output that appears on the workflow run summary page.
103101
- **Self-hosted runners**: Run workflows on your own infrastructure for specialized hardware needs, compliance requirements, or to stay within your network. Useful when you need GPUs, specific OS versions, or access to internal resources.
102+
- **Larger runners**: GitHub-hosted runners with more CPU and memory (up to 96-core x64 and 64-core ARM), available on Team and Enterprise plans. Swap `runs-on: ubuntu-latest` for a larger runner label when your builds or tests need more compute. See the [larger runners documentation][larger-runners].
104103
- **`repository_dispatch`**: Trigger workflows from external events via the GitHub API. This is useful for integrating GitHub Actions with external systems like monitoring tools, chatbots, or other CI/CD platforms.
105104
106105
## Wrap-up and congratulations
@@ -112,7 +111,7 @@ Congratulations! You've built a complete CI/CD pipeline for the pet shelter appl
112111
- **Custom actions**: Encapsulated Python setup and database seeding into a reusable composite action, eliminating duplication across jobs.
113112
- **Reusable workflows**: Extracted the deployment pattern into a callable workflow template, shared by both the automated CD pipeline and a manual deploy workflow for rollbacks.
114113
- **Manual deployment**: Added on-demand deployment capability for rollbacks and hotfixes, using `workflow_dispatch` with a git ref input.
115-
- **Branch protection**: Enforced quality gates so code can't be merged without passing CI checks — the production safeguard that ensures only validated code gets deployed.
114+
- **Rulesets**: Enforced quality gates so code can't be merged without passing CI checks and peer review — the production safeguard that ensures only validated code gets deployed.
116115
117116
This pipeline follows the same patterns used by teams across GitHub. As the shelter's application grows, this foundation will scale with it.
118117

@@ -127,22 +126,23 @@ If you want to keep exploring, here are some suggested next steps:
127126

128127
## Resources
129128

130-
- [About protected branches][about-protected-branches]
131129
- [About rulesets][about-rulesets]
132-
- [Required workflows][required-workflows]
130+
- [Creating rulesets for a repository][creating-rulesets]
131+
- [Available rules for rulesets][available-rules]
133132
- [The `workflow_dispatch` event][workflow-dispatch]
134133
- [GitHub Skills: Deploy to Azure][skills-deploy-azure]
135134
- [GitHub Actions Marketplace][actions-marketplace]
136135

137136
| [← Reusable Workflows][walkthrough-previous] | [Next: GitHub Actions section overview →][walkthrough-next] |
138137
|:-----------------------------------|------------------------------------------:|
139138

140-
[about-protected-branches]: https://docs.github.com/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/about-protected-branches
141139
[about-rulesets]: https://docs.github.com/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/about-rulesets
142140
[actions-marketplace]: https://github.com/marketplace?type=actions
141+
[available-rules]: https://docs.github.com/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/available-rules-for-rulesets
142+
[creating-rulesets]: https://docs.github.com/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/creating-rulesets-for-a-repository
143143
[environments-docs]: https://docs.github.com/actions/managing-workflow-runs-and-deployments/managing-deployments/managing-environments-for-deployment
144144
[github-security]: https://github.com/features/security
145-
[required-workflows]: https://docs.github.com/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/available-rules-for-rulesets
145+
[larger-runners]: https://docs.github.com/actions/using-github-hosted-runners/using-larger-runners
146146
[skills-deploy-azure]: https://github.com/skills/deploy-to-azure
147147
[workflow-dispatch]: https://docs.github.com/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#workflow_dispatch
148148
[walkthrough-previous]: 8-reusable-workflows.md

0 commit comments

Comments
 (0)