Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ci: add Docker tags containing the minor and major PHP version #373

Merged
merged 12 commits into from
Dec 13, 2023
Merged
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
79 changes: 44 additions & 35 deletions .github/workflows/docker.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ jobs:
runs-on: ubuntu-latest
outputs:
# Push only if it's a tag or if we're committing in the main branch
push: ${{toJson(startsWith(github.ref, 'refs/tags/') || (github.ref == 'refs/heads/main' && github.event_name != 'pull_request'))}}
push: ${{ toJson(startsWith(github.ref, 'refs/tags/') || (github.ref == 'refs/heads/main' && github.event_name != 'pull_request')) }}
variants: ${{ steps.matrix.outputs.variants }}
platforms: ${{ steps.matrix.outputs.platforms }}
metadata: ${{ steps.matrix.outputs.metadata }}
php_version: ${{ steps.matrix.outputs.php_version }}
steps:
-
uses: actions/checkout@v4
Expand All @@ -32,15 +33,22 @@ jobs:
name: Create variants matrix
id: matrix
run: |
# Fetch latest versions of PHP
PHP_82_LATEST=$(skopeo inspect docker://docker.io/library/php:8.2 --override-os linux --override-arch amd64 | jq -r '.Env[] | select(test("^PHP_VERSION=")) | sub("^PHP_VERSION="; "")')
PHP_83_LATEST=$(skopeo inspect docker://docker.io/library/php:8.3 --override-os linux --override-arch amd64 | jq -r '.Env[] | select(test("^PHP_VERSION=")) | sub("^PHP_VERSION="; "")')
export PHP_VERSION="${PHP_83_LATEST},${PHP_82_LATEST}"

METADATA="$(docker buildx bake --print | jq -c)"

{
echo php_version="$PHP_VERSION"
echo metadata="$METADATA"
echo variants="$(jq -c '.group.default.targets|map(sub("runner-|builder-"; ""))|unique' <<< "$METADATA")"
echo platforms="$(jq -c 'first(.target[]) | .platforms' <<< "$METADATA")"
} >> "$GITHUB_OUTPUT"
env:
SHA: ${{github.sha}}
VERSION: ${{github.ref_type == 'tag' && github.ref_name || github.sha}}
SHA: ${{ github.sha }}
VERSION: ${{ github.ref_type == 'tag' && github.ref_name || github.sha }}
build:
runs-on: ubuntu-latest
needs:
Expand All @@ -66,41 +74,42 @@ jobs:
if: matrix.qemu
uses: docker/setup-qemu-action@v3
with:
platforms: ${{matrix.platform}}
platforms: ${{ matrix.platform }}
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
platforms: ${{matrix.platform}}
platforms: ${{ matrix.platform }}
version: latest
-
name: Login to DockerHub
if: fromJson(needs.prepare.outputs.push)
uses: docker/login-action@v3
with:
username: ${{secrets.REGISTRY_USERNAME}}
password: ${{secrets.REGISTRY_PASSWORD}}
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
-
name: Build
id: build
uses: docker/bake-action@v4
with:
pull: true
load: ${{!fromJson(needs.prepare.outputs.push)}}
load: ${{ !fromJson(needs.prepare.outputs.push) }}
targets: |
builder-${{matrix.variant}}
runner-${{matrix.variant}}
builder-${{ matrix.variant }}
runner-${{ matrix.variant }}
# Remove tags to prevent "can't push tagged ref [...] by digest" error
set: |
*.tags=
*.platform=${{matrix.platform}}
*.cache-from=type=gha,scope=${{github.ref}}-${{matrix.platform}}
*.cache-from=type=gha,scope=refs/heads/main-${{matrix.platform}}
*.cache-to=type=gha,scope=${{github.ref}}-${{matrix.platform}}
${{fromJson(needs.prepare.outputs.push) && '*.output=type=image,name=dunglas/frankenphp,push-by-digest=true,name-canonical=true,push=true' || ''}}
*.platform=${{ matrix.platform }}
*.cache-from=type=gha,scope=${{ github.ref }}-${{ matrix.platform }}
*.cache-from=type=gha,scope=refs/heads/main-${{ matrix.platform }}
*.cache-to=type=gha,scope=${{ github.ref }}-${{ matrix.platform }}
${{ fromJson(needs.prepare.outputs.push) && '*.output=type=image,name=dunglas/frankenphp,push-by-digest=true,name-canonical=true,push=true' || '' }}
env:
SHA: ${{github.sha}}
VERSION: ${{github.ref_type == 'tag' && github.ref_name || github.sha}}
SHA: ${{ github.sha }}
VERSION: ${{ github.ref_type == 'tag' && github.ref_name || github.sha }}
PHP_VERSION: ${{ needs.prepare.outputs.php_version }}
-
# Workaround for https://github.com/actions/runner/pull/2477#issuecomment-1501003600
name: Export metadata
Expand All @@ -109,20 +118,20 @@ jobs:
mkdir -p /tmp/metadata/builder /tmp/metadata/runner

# shellcheck disable=SC2086
builderDigest=$(jq -r '."builder-${{matrix.variant}}"."containerimage.digest"' <<< $METADATA)
builderDigest=$(jq -r '."builder-${{ matrix.variant }}"."containerimage.digest"' <<< $METADATA)
touch "/tmp/metadata/builder/${builderDigest#sha256:}"

# shellcheck disable=SC2086
runnerDigest=$(jq -r '."runner-${{matrix.variant}}"."containerimage.digest"' <<< $METADATA)
runnerDigest=$(jq -r '."runner-${{ matrix.variant }}"."containerimage.digest"' <<< $METADATA)
touch "/tmp/metadata/runner/${runnerDigest#sha256:}"
env:
METADATA: ${{steps.build.outputs.metadata}}
METADATA: ${{ steps.build.outputs.metadata }}
-
name: Upload runner metadata
name: Upload builder metadata
if: fromJson(needs.prepare.outputs.push)
uses: actions/upload-artifact@v3
with:
name: metadata-builder-${{matrix.variant}}
name: metadata-builder-${{ matrix.variant }}
path: /tmp/metadata/builder/*
if-no-files-found: error
retention-days: 1
Expand All @@ -131,20 +140,20 @@ jobs:
if: fromJson(needs.prepare.outputs.push)
uses: actions/upload-artifact@v3
with:
name: metadata-runner-${{matrix.variant}}
name: metadata-runner-${{ matrix.variant }}
path: /tmp/metadata/runner/*
if-no-files-found: error
retention-days: 1
-
name: Run tests
if: '!matrix.qemu'
continue-on-error: ${{fromJson(needs.prepare.outputs.push)}}
continue-on-error: ${{ fromJson(needs.prepare.outputs.push) }}
run: |
docker run --platform=${{matrix.platform}} --rm \
"$(jq -r '."builder-${{matrix.variant}}"."containerimage.config.digest"' <<< "$METADATA")" \
sh -c 'go test ${{matrix.race}} -v ./... && cd caddy && go test ${{matrix.race}} -v ./...'
docker run --platform=${{ matrix.platform }} --rm \
"$(jq -r '."builder-${{ matrix.variant }}"."containerimage.config.digest"' <<< "$METADATA")" \
sh -c 'go test ${{ matrix.race }} -v ./... && cd caddy && go test ${{ matrix.race }} -v ./...'
env:
METADATA: ${{steps.build.outputs.metadata}}
METADATA: ${{ steps.build.outputs.metadata }}
# Adapted from https://docs.docker.com/build/ci/github-actions/multi-platform/
push:
runs-on: ubuntu-latest
Expand All @@ -162,7 +171,7 @@ jobs:
name: Download metadata
uses: actions/download-artifact@v3
with:
name: metadata-${{matrix.target}}-${{matrix.variant}}
name: metadata-${{ matrix.target }}-${{ matrix.variant }}
path: /tmp/metadata
-
name: Set up Docker Buildx
Expand All @@ -173,21 +182,21 @@ jobs:
name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{secrets.REGISTRY_USERNAME}}
password: ${{secrets.REGISTRY_PASSWORD}}
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
-
name: Create manifest list and push
working-directory: /tmp/metadata
run: |
# shellcheck disable=SC2046,SC2086
docker buildx imagetools create $(jq -cr '.target."${{matrix.target}}-${{matrix.variant}}".tags | map("-t " + .) | join(" ")' <<< $METADATA) \
docker buildx imagetools create $(jq -cr '.target."${{ matrix.target }}-${{ matrix.variant }}".tags | map("-t " + .) | join(" ")' <<< $METADATA) \
$(printf 'dunglas/frankenphp@sha256:%s ' *)
env:
METADATA: ${{needs.prepare.outputs.metadata}}
METADATA: ${{ needs.prepare.outputs.metadata }}
-
name: Inspect image
run: |
# shellcheck disable=SC2046,SC2086
docker buildx imagetools inspect $(jq -cr '.target."${{matrix.target}}-${{matrix.variant}}".tags | first' <<< $METADATA)
docker buildx imagetools inspect $(jq -cr '.target."${{ matrix.target }}-${{ matrix.variant }}".tags | first' <<< $METADATA)
env:
METADATA: ${{needs.prepare.outputs.metadata}}
METADATA: ${{ needs.prepare.outputs.metadata }}
36 changes: 28 additions & 8 deletions docker-bake.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ variable "VERSION" {
default = "dev"
}

variable "PHP_VERSION" {
default = "8.2,8.3"
}

variable "GO_VERSION" {
default = "1.21"
}
Expand All @@ -20,13 +24,17 @@ variable "CACHE" {
default = ""
}

variable DEFAULT_PHP_VERSION {
default = "8.3"
}

function "tag" {
params = [version, os, php-version, tgt]
result = [
version != "" ? format("%s:%s%s-php%s-%s", IMAGE_NAME, version, tgt == "builder" ? "-builder" : "", php-version, os) : "",
php-version == "8.3" && os == "bookworm" && version != "" ? format("%s:%s%s", IMAGE_NAME, version, tgt == "builder" ? "-builder" : "") : "",
php-version == "8.3" && version != "" ? format("%s:%s%s-%s", IMAGE_NAME, version, tgt == "builder" ? "-builder" : "", os) : "",
php-version == "8.3" && version == "latest" ? format("%s:%s%s", IMAGE_NAME, os, tgt == "builder" ? "-builder" : "") : "",
php-version == DEFAULT_PHP_VERSION && os == "bookworm" && version != "" ? format("%s:%s%s", IMAGE_NAME, version, tgt == "builder" ? "-builder" : "") : "",
php-version == DEFAULT_PHP_VERSION && version != "" ? format("%s:%s%s-%s", IMAGE_NAME, version, tgt == "builder" ? "-builder" : "", os) : "",
php-version == DEFAULT_PHP_VERSION && version == "latest" ? format("%s:%s%s", IMAGE_NAME, os, tgt == "builder" ? "-builder" : "") : "",
os == "bookworm" && version != "" ? format("%s:%s%s-php%s", IMAGE_NAME, version, tgt == "builder" ? "-builder" : "", php-version) : "",
]
}
Expand Down Expand Up @@ -55,11 +63,21 @@ function "__semver" {
result = v == {} ? [clean_tag(VERSION)] : v.prerelease == null ? ["latest", v.major, "${v.major}.${v.minor}", "${v.major}.${v.minor}.${v.patch}"] : ["${v.major}.${v.minor}.${v.patch}-${v.prerelease}"]
}

function "php_version" {
params = [v]
result = _php_version(v, regexall("(?P<major>\\d+)\\.(?P<minor>\\d+)", v)[0])
}

function "_php_version" {
params = [v, m]
result = "${m.major}.${m.minor}" == DEFAULT_PHP_VERSION ? [v, "${m.major}.${m.minor}", "${m.major}"] : [v, "${m.major}.${m.minor}"]
}

target "default" {
name = "${tgt}-php-${replace(php-version, ".", "-")}-${os}"
matrix = {
os = ["bookworm", "alpine"]
php-version = ["8.2", "8.3"]
php-version = split(",", PHP_VERSION)
tgt = ["builder", "runner"]
}
contexts = {
Expand All @@ -76,10 +94,12 @@ target "default" {
"linux/arm/v7",
"linux/arm64",
]
tags = distinct(flatten([
LATEST ? tag("latest", os, php-version, tgt) : [],
tag(SHA == "" ? "" : "sha-${substr(SHA, 0, 7)}", os, php-version, tgt),
[for v in semver(VERSION) : tag(v, os, php-version, tgt)]
tags = distinct(flatten(
[for pv in php_version(php-version) : flatten([
LATEST ? tag("latest", os, pv, tgt) : [],
tag(SHA == "" ? "" : "sha-${substr(SHA, 0, 7)}", os, pv, tgt),
[for v in semver(VERSION) : tag(v, os, pv, tgt)]
])
]))
labels = {
"org.opencontainers.image.created" = "${timestamp()}"
Expand Down
Loading