Skip to content
Open
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
54 changes: 54 additions & 0 deletions .github/scripts/ci-build-matrix-test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/usr/bin/env bash
set -euo pipefail

SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"

assert_output() {
local kind="$1"
local full_matrix="$2"
local expected="$3"
local actual

actual="$(METADATA="${TEST_METADATA}" REBUILD_VARIANTS="${REBUILD_VARIANTS:-}" "${SCRIPT_DIR}/ci-build-matrix.sh" "${kind}" "${full_matrix}")"
if [[ "${actual}" != "${expected}" ]]; then
printf 'expected:\n%s\nactual:\n%s\n' "${expected}" "${actual}" >&2
return 1
fi
}

TEST_METADATA='{
"group": {
"default": {
"targets": [
"builder-php-8-2-bookworm",
"builder-php-8-2-trixie",
"builder-php-8-3-bookworm",
"builder-php-8-3-trixie",
"runner-php-8-2-bookworm",
"runner-php-8-2-trixie",
"runner-php-8-3-bookworm",
"runner-php-8-3-trixie"
]
}
},
"target": {
"builder-php-8-2-bookworm": {
"platforms": ["linux/amd64", "linux/arm64"]
},
"static-builder-musl": {
"platforms": ["linux/amd64", "linux/arm64"]
}
}
}'

assert_output docker false $'variants=["php-8-2-bookworm","php-8-3-bookworm"]\nplatforms=["linux/amd64"]'
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"]'
assert_output static false 'platforms=["linux/amd64"]'
assert_output static true 'platforms=["linux/amd64","linux/arm64"]'

# On scheduled rebuilds REBUILD_VARIANTS narrows the docker matrix to the changed bases only.
REBUILD_VARIANTS='["php-8-2-trixie","php-8-3-bookworm"]' \
assert_output docker true $'variants=["php-8-2-trixie","php-8-3-bookworm"]\nplatforms=["linux/amd64","linux/arm64"]'
# The empty-array sentinel leaves the matrix untouched.
REBUILD_VARIANTS='[]' \
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"]'
61 changes: 61 additions & 0 deletions .github/scripts/ci-build-matrix.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/usr/bin/env bash
set -euo pipefail

# Platforms built on reduced pull-request runs.
readonly REDUCED_PLATFORMS='["linux/amd64"]'
# Sentinel emitted by docker-compute-fingerprints.sh when no variant needs a rebuild.
readonly EMPTY_JSON_ARRAY='[]'

write_output() {
if [[ -n "${GITHUB_OUTPUT:-}" ]]; then
echo "$1" >>"${GITHUB_OUTPUT}"
else
echo "$1"
fi
}

kind="${1:?matrix kind is required}"
full_matrix="${2:?full matrix flag is required}"

case "${kind}" in
docker)
if [[ "${full_matrix}" == "true" ]]; then
variants="$(
jq -c '.group.default.targets | map(sub("runner-|builder-"; "")) | unique' <<<"${METADATA}"
)"
platforms="$(jq -c 'first(.target[]) | .platforms' <<<"${METADATA}")"
else
variants="$(
jq -c '.group.default.targets
| map(sub("runner-|builder-"; ""))
| unique
| map(select(endswith("-bookworm")))' <<<"${METADATA}"
)"
platforms="${REDUCED_PLATFORMS}"
fi

# On scheduled rebuilds, only build the variants whose base images changed.
if [[ -n "${REBUILD_VARIANTS:-}" && "${REBUILD_VARIANTS}" != "${EMPTY_JSON_ARRAY}" ]]; then
variants="$(
jq -c --argjson rebuild "${REBUILD_VARIANTS}" \
'map(select(. as $v | $rebuild | index($v)))' <<<"${variants}"
)"
fi

write_output "variants=${variants}"
write_output "platforms=${platforms}"
;;
static)
if [[ "${full_matrix}" == "true" ]]; then
platforms="$(jq -c 'first(.target[]) | .platforms' <<<"${METADATA}")"
else
platforms="${REDUCED_PLATFORMS}"
fi

write_output "platforms=${platforms}"
;;
*)
echo "unknown matrix kind: ${kind}" >&2
exit 1
;;
esac
11 changes: 11 additions & 0 deletions .github/scripts/docker-compute-fingerprints.sh
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,17 @@ main() {
local METADATA
METADATA="$(PHP_VERSION="${PHP_VERSION}" docker buildx bake --print | jq -c)"

# On reduced pull-request runs only the Bookworm variants are built, so restrict the
# metadata to them and avoid fingerprinting (and failing on) base images we never build.
if [[ "${FULL_BUILD_MATRIX:-true}" != "true" ]]; then
METADATA="$(
jq -c '
.group.default.targets |= map(select(endswith("-bookworm")))
| .target |= with_entries(select(.key | endswith("-bookworm")))
' <<<"${METADATA}"
)"
fi

# Collect the base images (docker-image:// contexts) of each variant. The variant key
# is derived from the php-base ref (e.g. "php:8.4.23-zts-trixie" -> "8.4.23-trixie") and
# matches the "${php-version}-${os}" keys expected by docker-bake.hcl for BASE_FINGERPRINTS.
Expand Down
15 changes: 5 additions & 10 deletions .github/workflows/docker.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ on:
- main
paths:
- "docker-bake.hcl"
- ".github/scripts/ci-build-matrix.sh"
- ".github/workflows/docker.yaml"
- "**cgo.go"
- "**Dockerfile"
Expand Down Expand Up @@ -73,6 +74,7 @@ jobs:
id: check
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
FULL_BUILD_MATRIX: ${{ github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'full-build-matrix') }}
run: ./.github/scripts/docker-compute-fingerprints.sh
- name: Create variants matrix
if: ${{ !fromJson(steps.check.outputs.skip) }}
Expand All @@ -81,21 +83,14 @@ jobs:
run: |
set -e
METADATA="$(docker buildx bake --print | jq -c)"
variants="$(jq -c '.group.default.targets|map(sub("runner-|builder-"; ""))|unique' <<< "${METADATA}")"
# On scheduled rebuilds, only build the variants whose base images changed
if [[ -n "${REBUILD_VARIANTS}" && "${REBUILD_VARIANTS}" != "[]" ]]; then
variants="$(jq -c --argjson rebuild "${REBUILD_VARIANTS}" 'map(select(. as $v | $rebuild | index($v)))' <<< "${variants}")"
fi
{
echo metadata="${METADATA}"
echo variants="${variants}"
echo platforms="$(jq -c 'first(.target[]) | .platforms' <<< "${METADATA}")"
} >> "${GITHUB_OUTPUT}"
echo metadata="${METADATA}" >> "${GITHUB_OUTPUT}"
METADATA="${METADATA}" ./.github/scripts/ci-build-matrix.sh docker "${FULL_BUILD_MATRIX}"
env:
SHA: ${{ github.sha }}
VERSION: ${{ (github.ref_type == 'tag' && github.ref_name) || steps.check.outputs.ref || 'dev' }}
PHP_VERSION: ${{ steps.check.outputs.php_version }}
REBUILD_VARIANTS: ${{ steps.check.outputs.rebuild_variants }}
FULL_BUILD_MATRIX: ${{ github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'full-build-matrix') }}
build:
runs-on: ${{ startsWith(matrix.platform, 'linux/arm') && 'ubuntu-24.04-arm' || 'ubuntu-24.04' }}
needs:
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/static.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ on:
- main
paths:
- "docker-bake.hcl"
- ".github/scripts/ci-build-matrix.sh"
- ".github/workflows/static.yaml"
- "**cgo.go"
- "**Dockerfile"
Expand Down Expand Up @@ -74,14 +75,13 @@ jobs:
run: |
METADATA="$(docker buildx bake --print static-builder-musl | jq -c)"
GNU_METADATA="$(docker buildx bake --print static-builder-gnu | jq -c)"
{
echo metadata="${METADATA}"
echo platforms="$(jq -c 'first(.target[]) | .platforms' <<< "${METADATA}")"
echo gnu_metadata="${GNU_METADATA}"
} >> "${GITHUB_OUTPUT}"
echo metadata="${METADATA}" >> "${GITHUB_OUTPUT}"
METADATA="${METADATA}" ./.github/scripts/ci-build-matrix.sh static "${FULL_BUILD_MATRIX}"
echo gnu_metadata="${GNU_METADATA}" >> "${GITHUB_OUTPUT}"
env:
SHA: ${{ github.sha }}
VERSION: ${{ steps.check.outputs.ref || 'dev' }}
FULL_BUILD_MATRIX: ${{ github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'full-build-matrix') }}

build-linux-musl:
permissions:
Expand Down
Loading