Skip to content

Commit 6982573

Browse files
ci: reduce pull request build matrices
Pull requests without the full-build-matrix label now build a reduced docker/static matrix (one bookworm variant per PHP version on linux/amd64), while pushes, schedules, releases, manual runs and labeled PRs keep the full matrix. Fixes #2580.
1 parent 6845134 commit 6982573

5 files changed

Lines changed: 136 additions & 15 deletions

File tree

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
5+
6+
assert_output() {
7+
local kind="$1"
8+
local full_matrix="$2"
9+
local expected="$3"
10+
local actual
11+
12+
actual="$(METADATA="${TEST_METADATA}" REBUILD_VARIANTS="${REBUILD_VARIANTS:-}" "${SCRIPT_DIR}/ci-build-matrix.sh" "${kind}" "${full_matrix}")"
13+
if [[ "${actual}" != "${expected}" ]]; then
14+
printf 'expected:\n%s\nactual:\n%s\n' "${expected}" "${actual}" >&2
15+
return 1
16+
fi
17+
}
18+
19+
TEST_METADATA='{
20+
"group": {
21+
"default": {
22+
"targets": [
23+
"builder-php-8-2-bookworm",
24+
"builder-php-8-2-trixie",
25+
"builder-php-8-3-bookworm",
26+
"builder-php-8-3-trixie",
27+
"runner-php-8-2-bookworm",
28+
"runner-php-8-2-trixie",
29+
"runner-php-8-3-bookworm",
30+
"runner-php-8-3-trixie"
31+
]
32+
}
33+
},
34+
"target": {
35+
"builder-php-8-2-bookworm": {
36+
"platforms": ["linux/amd64", "linux/arm64"]
37+
},
38+
"static-builder-musl": {
39+
"platforms": ["linux/amd64", "linux/arm64"]
40+
}
41+
}
42+
}'
43+
44+
assert_output docker false $'variants=["php-8-2-bookworm","php-8-3-bookworm"]\nplatforms=["linux/amd64"]'
45+
assert_output docker true $'variants=["php-8-2-bookworm","php-8-2-trixie","php-8-3-bookworm","php-8-3-trixie"]\nplatforms=["linux/amd64","linux/arm64"]'
46+
assert_output static false 'platforms=["linux/amd64"]'
47+
assert_output static true 'platforms=["linux/amd64","linux/arm64"]'
48+
49+
# On scheduled rebuilds REBUILD_VARIANTS narrows the docker matrix to the changed bases only.
50+
REBUILD_VARIANTS='["php-8-2-trixie","php-8-3-bookworm"]' \
51+
assert_output docker true $'variants=["php-8-2-trixie","php-8-3-bookworm"]\nplatforms=["linux/amd64","linux/arm64"]'
52+
# The empty-array sentinel leaves the matrix untouched.
53+
REBUILD_VARIANTS='[]' \
54+
assert_output docker true $'variants=["php-8-2-bookworm","php-8-2-trixie","php-8-3-bookworm","php-8-3-trixie"]\nplatforms=["linux/amd64","linux/arm64"]'

.github/scripts/ci-build-matrix.sh

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
# Platforms built on reduced pull-request runs.
5+
readonly REDUCED_PLATFORMS='["linux/amd64"]'
6+
# Sentinel emitted by docker-compute-fingerprints.sh when no variant needs a rebuild.
7+
readonly EMPTY_JSON_ARRAY='[]'
8+
9+
write_output() {
10+
if [[ -n "${GITHUB_OUTPUT:-}" ]]; then
11+
echo "$1" >>"${GITHUB_OUTPUT}"
12+
else
13+
echo "$1"
14+
fi
15+
}
16+
17+
kind="${1:?matrix kind is required}"
18+
full_matrix="${2:?full matrix flag is required}"
19+
20+
case "${kind}" in
21+
docker)
22+
if [[ "${full_matrix}" == "true" ]]; then
23+
variants="$(
24+
jq -c '.group.default.targets | map(sub("runner-|builder-"; "")) | unique' <<<"${METADATA}"
25+
)"
26+
platforms="$(jq -c 'first(.target[]) | .platforms' <<<"${METADATA}")"
27+
else
28+
variants="$(
29+
jq -c '.group.default.targets
30+
| map(sub("runner-|builder-"; ""))
31+
| unique
32+
| map(select(endswith("-bookworm")))' <<<"${METADATA}"
33+
)"
34+
platforms="${REDUCED_PLATFORMS}"
35+
fi
36+
37+
# On scheduled rebuilds, only build the variants whose base images changed.
38+
if [[ -n "${REBUILD_VARIANTS:-}" && "${REBUILD_VARIANTS}" != "${EMPTY_JSON_ARRAY}" ]]; then
39+
variants="$(
40+
jq -c --argjson rebuild "${REBUILD_VARIANTS}" \
41+
'map(select(. as $v | $rebuild | index($v)))' <<<"${variants}"
42+
)"
43+
fi
44+
45+
write_output "variants=${variants}"
46+
write_output "platforms=${platforms}"
47+
;;
48+
static)
49+
if [[ "${full_matrix}" == "true" ]]; then
50+
platforms="$(jq -c 'first(.target[]) | .platforms' <<<"${METADATA}")"
51+
else
52+
platforms="${REDUCED_PLATFORMS}"
53+
fi
54+
55+
write_output "platforms=${platforms}"
56+
;;
57+
*)
58+
echo "unknown matrix kind: ${kind}" >&2
59+
exit 1
60+
;;
61+
esac

.github/scripts/docker-compute-fingerprints.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,17 @@ main() {
7171
local METADATA
7272
METADATA="$(PHP_VERSION="${PHP_VERSION}" docker buildx bake --print | jq -c)"
7373

74+
# On reduced pull-request runs only the Bookworm variants are built, so restrict the
75+
# metadata to them and avoid fingerprinting (and failing on) base images we never build.
76+
if [[ "${FULL_BUILD_MATRIX:-true}" != "true" ]]; then
77+
METADATA="$(
78+
jq -c '
79+
.group.default.targets |= map(select(endswith("-bookworm")))
80+
| .target |= with_entries(select(.key | endswith("-bookworm")))
81+
' <<<"${METADATA}"
82+
)"
83+
fi
84+
7485
# Collect the base images (docker-image:// contexts) of each variant. The variant key
7586
# is derived from the php-base ref (e.g. "php:8.4.23-zts-trixie" -> "8.4.23-trixie") and
7687
# matches the "${php-version}-${os}" keys expected by docker-bake.hcl for BASE_FINGERPRINTS.

.github/workflows/docker.yaml

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ on:
99
- main
1010
paths:
1111
- "docker-bake.hcl"
12+
- ".github/scripts/ci-build-matrix.sh"
1213
- ".github/workflows/docker.yaml"
1314
- "**cgo.go"
1415
- "**Dockerfile"
@@ -73,6 +74,7 @@ jobs:
7374
id: check
7475
env:
7576
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
77+
FULL_BUILD_MATRIX: ${{ github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'full-build-matrix') }}
7678
run: ./.github/scripts/docker-compute-fingerprints.sh
7779
- name: Create variants matrix
7880
if: ${{ !fromJson(steps.check.outputs.skip) }}
@@ -81,21 +83,14 @@ jobs:
8183
run: |
8284
set -e
8385
METADATA="$(docker buildx bake --print | jq -c)"
84-
variants="$(jq -c '.group.default.targets|map(sub("runner-|builder-"; ""))|unique' <<< "${METADATA}")"
85-
# On scheduled rebuilds, only build the variants whose base images changed
86-
if [[ -n "${REBUILD_VARIANTS}" && "${REBUILD_VARIANTS}" != "[]" ]]; then
87-
variants="$(jq -c --argjson rebuild "${REBUILD_VARIANTS}" 'map(select(. as $v | $rebuild | index($v)))' <<< "${variants}")"
88-
fi
89-
{
90-
echo metadata="${METADATA}"
91-
echo variants="${variants}"
92-
echo platforms="$(jq -c 'first(.target[]) | .platforms' <<< "${METADATA}")"
93-
} >> "${GITHUB_OUTPUT}"
86+
echo metadata="${METADATA}" >> "${GITHUB_OUTPUT}"
87+
METADATA="${METADATA}" ./.github/scripts/ci-build-matrix.sh docker "${FULL_BUILD_MATRIX}"
9488
env:
9589
SHA: ${{ github.sha }}
9690
VERSION: ${{ (github.ref_type == 'tag' && github.ref_name) || steps.check.outputs.ref || 'dev' }}
9791
PHP_VERSION: ${{ steps.check.outputs.php_version }}
9892
REBUILD_VARIANTS: ${{ steps.check.outputs.rebuild_variants }}
93+
FULL_BUILD_MATRIX: ${{ github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'full-build-matrix') }}
9994
build:
10095
runs-on: ${{ startsWith(matrix.platform, 'linux/arm') && 'ubuntu-24.04-arm' || 'ubuntu-24.04' }}
10196
needs:

.github/workflows/static.yaml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ on:
1010
- main
1111
paths:
1212
- "docker-bake.hcl"
13+
- ".github/scripts/ci-build-matrix.sh"
1314
- ".github/workflows/static.yaml"
1415
- "**cgo.go"
1516
- "**Dockerfile"
@@ -74,14 +75,13 @@ jobs:
7475
run: |
7576
METADATA="$(docker buildx bake --print static-builder-musl | jq -c)"
7677
GNU_METADATA="$(docker buildx bake --print static-builder-gnu | jq -c)"
77-
{
78-
echo metadata="${METADATA}"
79-
echo platforms="$(jq -c 'first(.target[]) | .platforms' <<< "${METADATA}")"
80-
echo gnu_metadata="${GNU_METADATA}"
81-
} >> "${GITHUB_OUTPUT}"
78+
echo metadata="${METADATA}" >> "${GITHUB_OUTPUT}"
79+
METADATA="${METADATA}" ./.github/scripts/ci-build-matrix.sh static "${FULL_BUILD_MATRIX}"
80+
echo gnu_metadata="${GNU_METADATA}" >> "${GITHUB_OUTPUT}"
8281
env:
8382
SHA: ${{ github.sha }}
8483
VERSION: ${{ steps.check.outputs.ref || 'dev' }}
84+
FULL_BUILD_MATRIX: ${{ github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'full-build-matrix') }}
8585

8686
build-linux-musl:
8787
permissions:

0 commit comments

Comments
 (0)