Files
thatguygriffandClaude Opus 5 2016cfbe20
Publish / PHP 8.1 (push) Successful in 6s
Publish / PHP 8.3 (push) Successful in 5s
Publish / PHP 8.5 (push) Successful in 6s
Publish / PHP 8.2 (push) Successful in 56s
Publish / PHP 8.4 (push) Successful in 1m17s
Shared PHP CI images for Gitea Actions
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
2026-08-24 22:37:25 -03:00

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