Skip to content

Fixes composer packages not retrieving latest available for current P… #254

Fixes composer packages not retrieving latest available for current P…

Fixes composer packages not retrieving latest available for current P… #254

name: Docker
on:
workflow_dispatch:
schedule:
- cron: '0 7 * * 2,4'
push:
branches: [ "1.x" ]
pull_request:
branches: [ "1.x" ]
env:
DOCKER_BUILDKIT: 1
# github.repository as <account>/<repo>
IMAGE_NAME: ${{ github.repository }}
PHP_VERSIONS_FILE: "scripts/conf/versions.yml"
PHP_VERSION_MIN: ${{ vars.PHP_VERSION_MIN != '' && vars.PHP_VERSION_MIN || '8.1' }}
COMPOSER_VERSION: "latest"
NODE_VERSION: "latest"
FRANKENPHP_VERSION: "latest"
RR_VERSION: "latest"
DENO_VERSION: "latest"
BUN_VERSION: "latest"
jobs:
cache_images:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v6
# Set up BuildKit so we can pull the images from Docker
# https://github.com/docker/setup-buildx-action
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
buildkitd-config-inline: |
[registry."docker.io"]
mirrors = ["mirror.gcr.io"]
# Login against a GitHub Container Registry except on PR
# https://github.com/docker/login-action
- name: Log into GitHub Container Registry
if: github.event_name != 'pull_request'
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# Login against a Docker Hub except on PR
# https://github.com/docker/login-action
- name: Login to DockerHub
uses: docker/login-action@v4
if: github.event_name != 'pull_request'
with:
registry: docker.io
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
# Reuse the cache for this PR specifically
# For that, we will use the PR number as cache to hit it more constantly.
- name: Restore the images from the cache for the Pull Request
if: github.event_name == 'pull_request'
uses: actions/cache@v5
with:
path: ./docker-images
key: ${{ runner.os }}-docker-images-${{ github.event.pull_request.number }}
restore-keys: |
${{ runner.os }}-docker-images-
- name: Pull images from Docker
run: |
mkdir -p docker-images
# Read the Dockerfile and extract the common images
common_images=$(awk '/# Common images start/,/# Common images end/ { if ($1 == "FROM") print $2 }' Dockerfile)
# Loop through the images and pull them
for image in $common_images; do
(
# Extract the image name, variable part, and set the tarball location
image_name=$(echo $image | cut -d':' -f1)
variable=$(echo $image | sed -n 's/.*:${\([^}]*\)}.*/\1/p')
tarball="docker-images/$(basename "$image_name" | sed 's/:/-/g')_cached.tar"
# Pull the image if it doesn't exists its cached version
if [ ! -f "$tarball" ]; then
docker pull "$image_name:${!variable}"
docker save -o "$tarball" "$image_name:${!variable}"
fi
) &
done
wait
- name: Check images pulled from Docker
run: |
if [ -d "docker-images" ] && [ "$(ls -A docker-images)" ]; then
echo "These are the Docker tarballs to cache:"
ls -1 "docker-images"
else
echo "No tarballs were detected, failing."
exit 1
fi
# Always renew the cache if this is not a PR
- name: Renew the images in the cache
if: github.event_name != 'pull_request'
uses: actions/cache/save@v5
with:
path: ./docker-images
key: ${{ runner.os }}-docker-images-${{ github.sha }}
setup-matrix:
needs: cache_images
runs-on: ubuntu-latest
outputs:
php-version-map-json: ${{ steps.get-php-versions.outputs.php-version-map-json }}
steps:
- name: Check out code
uses: actions/checkout@v6
- name: Prepare PHP versions for the matrix
run: ./scripts/get-php-versions.sh
- name: Ensure our PHP Versions file exists.
run: |
if [ ! -f "${{ env.PHP_VERSIONS_FILE }}" ]; then
echo "PHP Versions file does not exist. Exiting."
exit 1
else
cat ${{ env.PHP_VERSIONS_FILE }}
fi
- name: Assemble PHP versions into the matrix.
id: get-php-versions
run: |
MATRIX_JSON=$(yq -o=json ${{ env.PHP_VERSIONS_FILE }} | jq -c)
echo "php-version-map-json=${MATRIX_JSON}" >> $GITHUB_OUTPUT
echo "${MATRIX_JSON}" | jq '.'
publish:
needs: setup-matrix
runs-on: ubuntu-latest
strategy:
matrix:
version: ${{ fromJson(needs.setup-matrix.outputs.php-version-map-json) }}
permissions:
contents: read
packages: write
# This is used to complete the identity challenge
# with sigstore/fulcio when running outside of PRs.
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@v6
# Install the cosign tool except on PR
# https://github.com/sigstore/cosign-installer
- name: Install cosign
if: github.event_name != 'pull_request'
uses: sigstore/cosign-installer@v4.0.0
# Set up BuildKit Docker container builder to be able to build
# multi-platform images and export cache
# https://github.com/docker/setup-buildx-action
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
with:
buildkitd-config-inline: |
[registry."docker.io"]
mirrors = ["mirror.gcr.io"]
- name: Restore cached Docker Images
if: github.event_name != 'pull_request'
uses: actions/cache/restore@v5
with:
path: ./docker-images
key: ${{ runner.os }}-docker-images-${{ github.sha }}
# If this is a PR, we will just restore the images from the PR Number.
- name: Restore cached Docker Images for the Pull Request
if: github.event_name == 'pull_request'
uses: actions/cache/restore@v5
with:
path: ./docker-images
key: ${{ runner.os }}-docker-images-${{ github.event.pull_request.number }}
# Load each cached image to Docker in parallel because we are cool.
- name: Load the Docker images into BuildKit
run: |
for tarball in docker-images/*; do
docker load -i "$tarball" &
done
wait
# Login against a Docker registry except on PR
# https://github.com/docker/login-action
- name: Log into GitHub Container Registry
if: github.event_name != 'pull_request'
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to DockerHub
uses: docker/login-action@v4
if: github.event_name != 'pull_request'
with:
registry: docker.io
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
# Check if is the current version is the latest
- name: Determine if the version is the latest
id: check_latest
run: |
VERSIONS_ARRAY=($(echo ${{ needs.setup-matrix.outputs.php-version-map-json }} | jq -r '.[]' | sort -V))
LATEST_VERSION=${VERSIONS_ARRAY[-1]}
if [ "${{ matrix.version }}" == "$LATEST_VERSION" ]; then
echo "is_latest=true" >> $GITHUB_OUTPUT
else
echo "is_latest=false" >> $GITHUB_OUTPUT
fi
# Extract metadata (tags, labels) for Docker
# https://github.com/docker/metadata-action
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@v6
with:
images: |
${{ env.IMAGE_NAME }}
ghcr.io/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=pr
type=raw,value=${{ matrix.version }}
${{ steps.check_latest.outputs.is_latest == 'true' && 'type=raw,value=latest' || '' }}
${{ steps.check_latest.outputs.is_latest == 'true' && 'type=ref,event=branch' || '' }}
flavor:
latest=false
# Build and push Docker image with Buildx (don't push on PR)
# https://github.com/docker/build-push-action
- name: Build and push Docker image
id: build-and-push
uses: docker/build-push-action@v7
with:
context: .
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
build-args: |
PHP_VERSION=${{ matrix.version }}
# Sign the resulting Docker image digest except on PRs.
# This will only write to the public Rekor transparency log when the Docker
# repository is public to avoid leaking data. If you would like to publish
# transparency data even for private images, pass --force to cosign below.
# https://github.com/sigstore/cosign
- name: Sign the published Docker image
if: ${{ github.event_name != 'pull_request' }}
env:
# https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-an-intermediate-environment-variable
TAGS: ${{ steps.meta.outputs.tags }}
DIGEST: ${{ steps.build-and-push.outputs.digest }}
# This step uses the identity token to provision an ephemeral certificate
# against the sigstore community Fulcio instance.
run: echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST}