From db4783b138385ba52d36fe6c4218eafc7aa874b4 Mon Sep 17 00:00:00 2001 From: Ayesh Karunaratne Date: Mon, 6 Jul 2026 01:17:30 +0700 Subject: [PATCH 1/2] feat(build): multi-arch builds + pinned actions #0000 This is a rather large commit that makes several improvements to how the `php-docker-base` images are built and cleaned up. Multi-arch images ================= Although these images are used in linux x64 servers, developers could be running on other CPU architectures. For example, some of our friends and colleagues (and @Ayesh himself after he spilled water on his X64 laptop) use Mac Books that lately use Arm64 CPUs (Apple Sillicon M series). Right now, downstream projects such as Onatal, Onatal-API, Plaza, Peri-connect, etc use this image, but on Arm64, it has to emulate Amd64 (x64), which can be slow. On M series, this has no noticeable slow down, but the author of this PR has too much time on his rainy Sunday evening, and this PR proposes to build Amd64 and Arm64 images using native GitHub runners, and merge those images and tag them. This ensures that once the images are rebuilt, on the next fresh, any consumer that use the `php-docker-base` image will pull an Arm64 image instead of emulating the Amd64 image. Pinning third-part action SHAs ============================== This combines the external actions in the `production.yaml` workflow to the pinned versions. They are identical versions used in linkorb/repo-ansible as at v0.25.0. Checkout with `persist-credentials: false` ========================================= Combines security improvement suggested in linkorb/repo-ansible#165. Using `docker/*` actions ======================== Instead of calling `docker` commands directly in bash, this PR suggests to use relevant `docker/` GitHub reusable actions. The same version+shasums are used here as repo-ansible. Why a big PR? ============= This combines SHA pinning + `docker/` action migration, and multi-arch builds in one PR. If I were to do this one by one, it will have to be in a merge queue, increasing the merge and review times. This also aims to bring us to the final goal immediately, instead of doin it in smaller steps that cannot convey the final goal that easily. --- .github/workflows/production.yml | 185 +++++++++++++++++++++++++++---- 1 file changed, 163 insertions(+), 22 deletions(-) diff --git a/.github/workflows/production.yml b/.github/workflows/production.yml index ea4ba2c..2096c7f 100644 --- a/.github/workflows/production.yml +++ b/.github/workflows/production.yml @@ -14,49 +14,190 @@ permissions: jobs: build: - runs-on: ubuntu-latest + name: "Build: ${{ matrix.php }}-${{ matrix.platform_name }}" - name: Build Docker image strategy: matrix: - php: - - php7 - - php8 - - php8latest + include: + - php: php7 + platform: linux/amd64 + runner: ubuntu-latest + platform_name: amd64 + + - php: php7 + platform: linux/arm64 + runner: ubuntu-24.04-arm + platform_name: arm64 + + - php: php8 + platform: linux/amd64 + runner: ubuntu-latest + platform_name: amd64 + + - php: php8 + platform: linux/arm64 + runner: ubuntu-24.04-arm + platform_name: arm64 + + - php: php8latest + platform: linux/amd64 + runner: ubuntu-latest + platform_name: amd64 + + - php: php8latest + platform: linux/arm64 + runner: ubuntu-24.04-arm + platform_name: arm64 + + runs-on: ${{ matrix.runner }} steps: + - name: Compute image name + id: image_name + run: | + echo "image_name=${GITHUB_REPOSITORY,,}" >> "$GITHUB_OUTPUT" + - name: Shallow clone code - uses: actions/checkout@v6 + # v6 https://github.com/actions/checkout/commit/de0fac2e4500dabe0009e67214ff5f5447ce83dd + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: fetch-depth: 0 + persist-credentials: false - - name: Login to Container Registry ghcr.io - uses: docker/login-action@v4 + # v4 https://github.com/docker/setup-qemu-action/commit/ce360397dd3f832beb865e1373c09c0e9f86d70a + - uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a + with: + image: tonistiigi/binfmt:qemu-v10.2.1@sha256:d3b963f787999e6c0219a48dba02978769286ff61a5f4d26245cb6a6e5567ea3 + platforms: ${{ matrix.platform }} + + # v4 https://github.com/docker/setup-buildx-action/commit/4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd + - uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd + with: + driver-opts: network=host,image=moby/buildkit:v0.28.0@sha256:37539dd4d60fc70968d164d3850d903a2c56f6402214a1953fbf9fcb81ada731 + platforms: ${{ matrix.platform }} + + # v4.1 https://github.com/docker/login-action/commit/4907a6ddec9925e35a0a9e82d7399ccc52663121 + - uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 with: registry: ghcr.io username: ${{ github.repository_owner }} # ghcr logins allow mixed case usernames password: ${{ secrets.GITHUB_TOKEN }} - - name: Build the container image - run: docker build . --tag "ghcr.io/$(echo '${{ github.repository }}' | tr '[:upper:]' '[:lower:]'):${{ matrix.php }}" --file Dockerfile.${{ matrix.php }} + # v7.1 https://github.com/docker/build-push-action/commit/bcafcacb16a39f128d818304e6c9c0c18556b85f + - uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f + name: Build and tag ${{ matrix.php }} + id: build + with: + context: . + file: Dockerfile.${{ matrix.php }} + platforms: ${{ matrix.platform }} + provenance: false + push: ${{ github.event_name != 'pull_request' }} + tags: "ghcr.io/${{ steps.image_name.outputs.image_name }}" + outputs: type=image,push-by-digest=true,name-canonical=true,push=true + + # v7.1 https://github.com/docker/build-push-action/commit/bcafcacb16a39f128d818304e6c9c0c18556b85f + - uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f + name: Build and tag ${{ matrix.php }}-review + id: review + with: + context: . + file: Dockerfile.${{ matrix.php }}-review + platforms: ${{ matrix.platform }} + provenance: false + push: ${{ github.event_name != 'pull_request' }} + tags: "ghcr.io/${{ steps.image_name.outputs.image_name }}" + outputs: type=image,push-by-digest=true,name-canonical=true,push=true + build-args: | + BASE_IMAGE=ghcr.io/${{ steps.image_name.outputs.image_name }}@${{ steps.build.outputs.digest }} + + - name: Save build digests + run: | + mkdir digests + echo "${{ steps.build.outputs.digest }}" \ + > digests/${{ matrix.php }}-${{ matrix.platform_name }}.digest + + echo "${{ steps.review.outputs.digest }}" \ + > digests/${{ matrix.php }}-${{ matrix.platform_name }}-review.digest - - name: Push with commit ${{ matrix.php }} tag - run: docker push "ghcr.io/$(echo '${{ github.repository }}' | tr '[:upper:]' '[:lower:]'):${{ matrix.php }}" - #review containers - - name: Build the review container image - run: docker build . --tag "ghcr.io/$(echo '${{ github.repository }}' | tr '[:upper:]' '[:lower:]'):${{ matrix.php }}-review" --file Dockerfile.${{ matrix.php }}-review + # v7.0.1 https://github.com/actions/upload-artifact/commit/043fb46d1a93c77aae656e7c1c64a875d1fc6a0a: + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a + with: + name: digests-${{ matrix.php }}-${{ matrix.platform_name }} + path: digests/* - - name: Push with commit *-review tag - run: docker push "ghcr.io/$(echo '${{ github.repository }}' | tr '[:upper:]' '[:lower:]'):${{ matrix.php }}-review" + merge: + needs: build + runs-on: ubuntu-latest + name: Merge and push ${{ matrix.php }} and review image + + strategy: + matrix: + php: + - php7 + - php8 + - php8latest + + steps: + + - name: Compute image name + id: image_name + run: | + echo "image_name=ghcr.io/${GITHUB_REPOSITORY,,}" >> "$GITHUB_OUTPUT" + + # v4.1 https://github.com/docker/login-action/commit/4907a6ddec9925e35a0a9e82d7399ccc52663121 + - uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} # ghcr logins allow mixed case usernames + password: ${{ secrets.GITHUB_TOKEN }} + + # v4 https://github.com/docker/setup-buildx-action/commit/4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd + - uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd + with: + driver-opts: network=host,image=moby/buildkit:v0.28.0@sha256:37539dd4d60fc70968d164d3850d903a2c56f6402214a1953fbf9fcb81ada731 + platforms: linux/amd64,linux/arm64 + + # v8.0.1 https://github.com/actions/download-artifact/commit/3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c + with: + path: digests + merge-multiple: true + + - name: Merge and push ${{ matrix.php }} image + run: | + AMD64=$(cat digests/${{ matrix.php }}-amd64.digest) + ARM64=$(cat digests/${{ matrix.php }}-arm64.digest) + + docker buildx imagetools create \ + -t ghcr.io/${{ steps.image_name.outputs.image_name }}:${{ matrix.php }} \ + ghcr.io/${{ steps.image_name.outputs.image_name }}@$AMD64 \ + ghcr.io/${{ steps.image_name.outputs.image_name }}@$ARM64 + + - name: Merge and push ${{ matrix.php }}-review image + run: | + AMD64=$(cat digests/${{ matrix.php }}-amd64-review.digest) + ARM64=$(cat digests/${{ matrix.php }}-arm64-review.digest) + + docker buildx imagetools create \ + -t ghcr.io/${{ steps.image_name.outputs.image_name }}:${{ matrix.php }}-review \ + ghcr.io/${{ steps.image_name.outputs.image_name }}@$AMD64 \ + ghcr.io/${{ steps.image_name.outputs.image_name }}@$ARM64 cleanup: - needs: [build] + needs: [merge] runs-on: ubuntu-latest steps: - - name: Login to Container Registry ghcr.io - uses: docker/login-action@v4 + - name: Compute image name + id: image_name + run: | + IMAGE_NAME="${GITHUB_REPOSITORY##*/}" + echo "package_name=${IMAGE_NAME,,}" >> "$GITHUB_OUTPUT" + + # v4.1 https://github.com/docker/login-action/commit/4907a6ddec9925e35a0a9e82d7399ccc52663121 + - uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 with: registry: ghcr.io username: ${{ github.repository_owner }} #ghcr logins allow mixed case usernames @@ -65,6 +206,6 @@ jobs: - name: Delete old versions of the package, keeping a few of the newest uses: actions/delete-package-versions@v5 with: - package-name: ${{ github.event.repository.name }} + package-name: ${{ steps.image_name.outputs.package_name }} package-type: container min-versions-to-keep: 8 From 4e3fb59c84ef50105d051ca43cfbbec2ada8ce6f Mon Sep 17 00:00:00 2001 From: Ayesh Karunaratne Date: Mon, 6 Jul 2026 01:16:52 +0700 Subject: [PATCH 2/2] feat(review-image): add a build `ARG` to override the base image #0000 --- Dockerfile.php7-review | 4 ++-- Dockerfile.php8-review | 4 ++-- Dockerfile.php8latest-review | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Dockerfile.php7-review b/Dockerfile.php7-review index fc54c9e..dcfa2f7 100644 --- a/Dockerfile.php7-review +++ b/Dockerfile.php7-review @@ -1,5 +1,5 @@ -FROM ghcr.io/linkorb/php-docker-base:php7 - +ARG BASE_IMAGE=ghcr.io/linkorb/php-docker-base:php7 +FROM ${BASE_IMAGE} RUN mkdir -p /opt diff --git a/Dockerfile.php8-review b/Dockerfile.php8-review index 839878f..e6217aa 100644 --- a/Dockerfile.php8-review +++ b/Dockerfile.php8-review @@ -1,5 +1,5 @@ -FROM ghcr.io/linkorb/php-docker-base:php8 - +ARG BASE_IMAGE=ghcr.io/linkorb/php-docker-base:php8 +FROM ${BASE_IMAGE} RUN mkdir -p /opt diff --git a/Dockerfile.php8latest-review b/Dockerfile.php8latest-review index dda53f9..af790bb 100644 --- a/Dockerfile.php8latest-review +++ b/Dockerfile.php8latest-review @@ -1,5 +1,5 @@ -FROM ghcr.io/linkorb/php-docker-base:php8latest - +ARG BASE_IMAGE=ghcr.io/linkorb/php-docker-base:php8latest +FROM ${BASE_IMAGE} RUN mkdir -p /opt