Skip to content

Commit 7628330

Browse files
committed
ci,packit: Add merge queue support with tiered CI
Enable GitHub merge queues for bootc. Heavy integration tests (multi-OS matrix, Testing Farm, COPR builds) are expensive and should not block every PR, but must pass before merging. GitHub Actions CI now has three tiers: - Plain PR: only cheap/fast jobs (build, unit tests, docs). Heavy jobs are skipped but the `required-checks` sentinel still passes. - `ci/tier-1` label: adds centos-10 matrix for package+integration+upgrade. - `ci/merge` label or merge_group: full OS matrix, identical to what the merge queue runs. A `compute-ci-level` job emits dynamic JSON matrices based on the trigger/labels; matrix jobs consume these via `fromJson()`. The `required-checks` sentinel accepts `skipped` as success and uses explicit jq failure reporting instead of the fragile `!`-negation pattern. Packit (COPR builds + Testing Farm) is similarly label-gated: ci/tier-1 for primary targets (centos-10, fedora-44), ci/merge for the full set. Packit is NOT wired into the merge queue as a required check because it embeds the branch name in its check names (`rpm-build:gh-readonly-queue/main/...:target`), making it impractical to enforce via GitHub rulesets. Ref: bootc-dev/infra#143 Assisted-by: OpenCode (Claude Sonnet 4.6) Signed-off-by: Colin Walters <walters@verbum.org>
1 parent 77cab5f commit 7628330

2 files changed

Lines changed: 115 additions & 22 deletions

File tree

.github/workflows/ci.yml

Lines changed: 65 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,14 @@ name: CI
1010

1111
permissions:
1212
actions: read
13+
contents: read
1314

1415
on:
1516
push:
1617
branches: [main]
1718
pull_request:
1819
branches: [main]
20+
types: [opened, synchronize, reopened, labeled]
1921
merge_group:
2022
workflow_dispatch: {}
2123

@@ -31,6 +33,45 @@ concurrency:
3133
cancel-in-progress: true
3234

3335
jobs:
36+
# Determine the OS matrix for CI jobs based on context:
37+
# - merge_group / workflow_dispatch / ci/merge label: all OSes
38+
# - ci/tier-1 label: centos-10 only (fast feedback on the primary target)
39+
# - plain PR: no heavy jobs
40+
compute-ci-level:
41+
runs-on: ubuntu-24.04
42+
outputs:
43+
package_os_matrix: ${{ steps.matrix.outputs.package_os_matrix }}
44+
integration_os_matrix: ${{ steps.matrix.outputs.integration_os_matrix }}
45+
upgrade_os_matrix: ${{ steps.matrix.outputs.upgrade_os_matrix }}
46+
run_heavy: ${{ steps.matrix.outputs.run_heavy }}
47+
steps:
48+
- name: Compute OS matrices
49+
id: matrix
50+
run: |
51+
LABELS='${{ toJson(github.event.pull_request.labels.*.name) }}'
52+
EVENT='${{ github.event_name }}'
53+
54+
if [[ "$EVENT" == "merge_group" || "$EVENT" == "workflow_dispatch" ]] \
55+
|| echo "$LABELS" | jq -e 'index("ci/merge")' > /dev/null; then
56+
# Full suite: all OSes
57+
echo 'package_os_matrix=["fedora-43","fedora-44","fedora-45","centos-9","centos-10"]' >> "$GITHUB_OUTPUT"
58+
echo 'integration_os_matrix=["fedora-43","fedora-44","centos-9","centos-10"]' >> "$GITHUB_OUTPUT"
59+
echo 'upgrade_os_matrix=["fedora-43","centos-10"]' >> "$GITHUB_OUTPUT"
60+
echo 'run_heavy=true' >> "$GITHUB_OUTPUT"
61+
elif echo "$LABELS" | jq -e 'index("ci/tier-1")' > /dev/null; then
62+
# Tier-1 only: centos-10
63+
echo 'package_os_matrix=["centos-10"]' >> "$GITHUB_OUTPUT"
64+
echo 'integration_os_matrix=["centos-10"]' >> "$GITHUB_OUTPUT"
65+
echo 'upgrade_os_matrix=["centos-10"]' >> "$GITHUB_OUTPUT"
66+
echo 'run_heavy=true' >> "$GITHUB_OUTPUT"
67+
else
68+
# Plain PR: skip heavy jobs entirely
69+
echo 'package_os_matrix=[]' >> "$GITHUB_OUTPUT"
70+
echo 'integration_os_matrix=[]' >> "$GITHUB_OUTPUT"
71+
echo 'upgrade_os_matrix=[]' >> "$GITHUB_OUTPUT"
72+
echo 'run_heavy=false' >> "$GITHUB_OUTPUT"
73+
fi
74+
3475
# Run basic validation checks (linting, formatting, etc)
3576
validate:
3677
runs-on: ubuntu-24.04
@@ -125,10 +166,12 @@ jobs:
125166
run: just build-mdbook
126167
# Build packages for each test OS
127168
package:
169+
if: needs.compute-ci-level.outputs.run_heavy == 'true'
170+
needs: compute-ci-level
128171
strategy:
129172
fail-fast: false
130173
matrix:
131-
test_os: [fedora-43, fedora-44, fedora-45, centos-9, centos-10]
174+
test_os: ${{ fromJson(needs.compute-ci-level.outputs.package_os_matrix) }}
132175

133176
runs-on: ubuntu-24.04
134177

@@ -156,11 +199,12 @@ jobs:
156199
# running unit and integration tests (using TMT, leveraging the support for nested virtualization
157200
# in the GHA runners)
158201
test-integration:
159-
needs: package
202+
if: needs.compute-ci-level.outputs.run_heavy == 'true'
203+
needs: [compute-ci-level, package]
160204
strategy:
161205
fail-fast: false
162206
matrix:
163-
test_os: [fedora-43, fedora-44, centos-9, centos-10]
207+
test_os: ${{ fromJson(needs.compute-ci-level.outputs.integration_os_matrix) }}
164208
variant: [ostree, composefs]
165209
filesystem: ["ext4", "xfs"]
166210
bootloader: ["grub", "systemd"]
@@ -266,11 +310,12 @@ jobs:
266310
# then run readonly tests to verify the upgrade worked.
267311
# Excluded: centos-9 (lacks systemd.extra-unit.* support needed for --bind-storage-ro)
268312
test-upgrade:
269-
needs: package
313+
if: needs.compute-ci-level.outputs.run_heavy == 'true'
314+
needs: [compute-ci-level, package]
270315
strategy:
271316
fail-fast: false
272317
matrix:
273-
test_os: [fedora-43, centos-10]
318+
test_os: ${{ fromJson(needs.compute-ci-level.outputs.upgrade_os_matrix) }}
274319
variant: [ostree, composefs]
275320

276321
runs-on: ubuntu-24.04
@@ -316,7 +361,7 @@ jobs:
316361
# without a separate /boot partition isn't mounted in the initramfs anymore.
317362
# We need to change to use coreos-assembler.
318363
if: false
319-
needs: package
364+
needs: [compute-ci-level, package]
320365
runs-on: ubuntu-24.04
321366

322367
steps:
@@ -358,7 +403,8 @@ jobs:
358403
# Builds localhost/bootc, exports as tarball, installs via Anaconda in QEMU,
359404
# and verifies the resulting disk boots.
360405
test-container-export:
361-
needs: package
406+
if: needs.compute-ci-level.outputs.run_heavy == 'true'
407+
needs: [compute-ci-level, package]
362408
runs-on: ubuntu-24.04
363409

364410
steps:
@@ -389,17 +435,19 @@ jobs:
389435
name: container-export-test-${{ env.ARCH }}
390436
path: target/anaconda-test/*.log
391437

392-
# Sentinel job for required checks - configure this job name in repository settings
438+
# Sentinel job for required checks - configure this job name in repository settings.
439+
# Accepts 'skipped' as success so that merge_group-only jobs don't block PRs.
393440
required-checks:
394441
if: always()
395-
needs: [cargo-deny, validate, package, test-integration, test-upgrade, test-container-export]
442+
needs: [compute-ci-level, cargo-deny, validate, install-tests, docs, package, test-integration, test-upgrade, test-container-export]
396443
runs-on: ubuntu-latest
397444
steps:
398-
- run: exit 1
399-
if: >-
400-
needs.cargo-deny.result != 'success' ||
401-
needs.validate.result != 'success' ||
402-
needs.package.result != 'success' ||
403-
needs.test-integration.result != 'success' ||
404-
needs.test-upgrade.result != 'success' ||
405-
needs.test-container-export.result != 'success'
445+
- name: Check all jobs
446+
env:
447+
NEEDS: ${{ toJson(needs) }}
448+
run: |
449+
FAILED=$(echo "$NEEDS" | jq -r 'to_entries[] | select(.value.result | IN("success","skipped") | not) | .key')
450+
if [ -n "$FAILED" ]; then
451+
echo "The following jobs did not succeed: $FAILED"
452+
exit 1
453+
fi

.packit.yaml

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,32 @@ actions:
2929
- bash -c "ls -al contrib/packaging/"
3030

3131
jobs:
32+
# copr_build on PRs: only runs when ci/tier-1 or ci/merge label is present.
33+
# ci/tier-1: centos-10 + fedora-44 (primary targets, all arches)
3234
- job: copr_build
3335
trigger: pull_request
36+
identifier: tier-1
37+
require:
38+
label:
39+
present:
40+
- ci/tier-1
41+
targets:
42+
- centos-stream-10-x86_64
43+
- centos-stream-10-aarch64
44+
- centos-stream-10-s390x
45+
- fedora-44-x86_64
46+
- fedora-44-aarch64
47+
- fedora-44-s390x
48+
49+
# ci/merge: full target set (mirrors what runs in the merge queue)
50+
- job: copr_build
51+
trigger: pull_request
52+
identifier: full
53+
require:
54+
label:
55+
present:
56+
- ci/merge
3457
targets:
35-
# Primary targets are c9s, c10s and supported fedora right now,
36-
# which build for all architectures
3758
- centos-stream-9-x86_64
3859
- centos-stream-9-aarch64
3960
- centos-stream-9-s390x
@@ -46,9 +67,6 @@ jobs:
4667
- fedora-44-x86_64
4768
- fedora-44-aarch64
4869
- fedora-44-s390x
49-
# Sanity check on secondary targets, fewer architectures just
50-
# because the chance that we break e.g. ppc64le *just* on
51-
# rawhide is basically nil.
5270
- fedora-rawhide-x86_64
5371
- fedora-rawhide-aarch64
5472
# Temporarily disabled due to too old Rust...reenable post 9.6
@@ -63,8 +81,35 @@ jobs:
6381
project: bootc
6482
enable_net: true
6583

84+
# Testing Farm on PRs: only runs when ci/tier-1 or ci/merge label is present.
85+
# ci/tier-1: centos-10 + fedora-44 (primary targets)
86+
- job: tests
87+
trigger: pull_request
88+
identifier: tier-1
89+
require:
90+
label:
91+
present:
92+
- ci/tier-1
93+
targets:
94+
- centos-stream-10-x86_64
95+
- centos-stream-10-aarch64
96+
- fedora-44-x86_64
97+
- fedora-44-aarch64
98+
tmt_plan: /tmt/plans/integration
99+
tf_extra_params:
100+
environments:
101+
- tmt:
102+
context:
103+
running_env: "packit"
104+
105+
# ci/merge: full target set
66106
- job: tests
67107
trigger: pull_request
108+
identifier: full
109+
require:
110+
label:
111+
present:
112+
- ci/merge
68113
targets:
69114
- centos-stream-9-x86_64
70115
- centos-stream-9-aarch64

0 commit comments

Comments
 (0)