One image per PHP version, published to git.unsupervised.ca/unsupervised/ci-php:<php-version>, so PHP projects can run their jobs with `container:` instead of installing PHP per job. Built on php:<version>-cli-alpine with Composer 2, the intl and zip extensions, and the GNU CLI tools workflow scripts expect. bash and nodejs are present because act_runner runs JavaScript actions inside the job container; GNU tar because actions/cache shells out to `tar --posix -P`, which busybox rejects. Covers 8.1 through 8.5. Pushing needs the REGISTRY_TOKEN organisation secret — Gitea's Actions task token cannot write packages (go-gitea/gitea#23642). Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01D9acV1mHktGAb1uyvNmrR2
95 lines
3.2 KiB
YAML
95 lines
3.2 KiB
YAML
name: Publish
|
|
|
|
# Builds one image per PHP version and pushes it to the Gitea container
|
|
# registry as git.unsupervised.ca/unsupervised/ci-php:<php-version>.
|
|
#
|
|
# Runs when the image definition changes on main, weekly so PHP patch
|
|
# releases and Alpine security updates land on their own, and on demand.
|
|
# Pull requests build every version without pushing, so a broken Dockerfile
|
|
# is caught before it can move a published tag.
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- main
|
|
paths:
|
|
- 'Dockerfile'
|
|
- '.gitea/workflows/publish.yml'
|
|
pull_request:
|
|
paths:
|
|
- 'Dockerfile'
|
|
- '.gitea/workflows/publish.yml'
|
|
schedule:
|
|
- cron: '17 4 * * 1'
|
|
workflow_dispatch:
|
|
|
|
env:
|
|
REGISTRY: git.unsupervised.ca
|
|
IMAGE: unsupervised/ci-php
|
|
|
|
jobs:
|
|
build:
|
|
name: PHP ${{ matrix.php }}
|
|
runs-on: ubuntu-latest
|
|
strategy:
|
|
# One version failing should not hide whether the others built.
|
|
fail-fast: false
|
|
matrix:
|
|
php:
|
|
- '8.1'
|
|
- '8.2'
|
|
- '8.3'
|
|
- '8.4'
|
|
- '8.5'
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
# Images are built natively, so each carries the architecture of the
|
|
# runner that built it. Every runner in the pool is arm64. A runner of
|
|
# a different architecture joining would overwrite these tags with its
|
|
# own arch and break the rest, at which point this needs buildx and a
|
|
# multi-arch manifest.
|
|
- name: Check Docker is available
|
|
run: |
|
|
if ! docker info >/dev/null 2>&1; then
|
|
echo "No usable Docker daemon in the job container." >&2
|
|
echo "act_runner needs container.docker_host set, or left empty to autodetect." >&2
|
|
exit 1
|
|
fi
|
|
docker version --format 'client {{.Client.Version}} / server {{.Server.Version}} / arch {{.Server.Arch}}'
|
|
|
|
# REGISTRY_TOKEN is an organisation secret: a personal access token
|
|
# with the package scope, Read and Write. Gitea's Actions task token is
|
|
# rejected by the container registry (go-gitea/gitea#23642), so this
|
|
# cannot fall back to secrets.GITHUB_TOKEN. The login user must own the
|
|
# token; set the REGISTRY_USER variable if it is not github.actor.
|
|
- name: Log in to the container registry
|
|
if: github.event_name != 'pull_request'
|
|
run: |
|
|
if [ -z "${{ secrets.REGISTRY_TOKEN }}" ]; then
|
|
echo "REGISTRY_TOKEN is not set. See README.md — the Actions task token cannot push packages." >&2
|
|
exit 1
|
|
fi
|
|
echo "${{ secrets.REGISTRY_TOKEN }}" \
|
|
| docker login "${REGISTRY}" -u "${{ vars.REGISTRY_USER || github.actor }}" --password-stdin
|
|
|
|
- name: Build
|
|
run: |
|
|
docker build \
|
|
--pull \
|
|
--build-arg "PHP_VERSION=${{ matrix.php }}" \
|
|
--tag "${REGISTRY}/${IMAGE}:${{ matrix.php }}" \
|
|
--file Dockerfile \
|
|
.
|
|
|
|
- name: Push
|
|
if: github.event_name != 'pull_request'
|
|
run: |
|
|
image="${REGISTRY}/${IMAGE}:${{ matrix.php }}"
|
|
docker push "${image}"
|
|
echo "Published ${image}"
|
|
|
|
- name: Log out
|
|
if: always() && github.event_name != 'pull_request'
|
|
run: docker logout "${REGISTRY}" || true
|