Publish prebuilt CI images to the Gitea container registry
CI Images / Build CI image (PHP 8.2) (pull_request) Successful in 1m14s
CI Images / Build CI image (PHP 8.1) (pull_request) Successful in 1m26s
CI Images / Build CI image (PHP 8.3) (pull_request) Successful in 2m3s
CI Images / Build CI image (PHP 8.5) (pull_request) Successful in 2m9s
CI / Tests (PHP 8.2) (pull_request) Successful in 1m7s
CI / No Debug Code (pull_request) Successful in 2s
CI / Tests (PHP 8.3) (pull_request) Successful in 3m8s
CI / Tests (PHP 8.1) (pull_request) Successful in 5m55s
CI / Tests (PHP 8.5) (pull_request) Successful in 6m21s
CI / Coding Standards & Static Analysis (pull_request) Successful in 18m26s
CI / Build Plugin Zip (pull_request) Skipped
CI Images / Build CI image (PHP 8.2) (pull_request) Successful in 1m14s
CI Images / Build CI image (PHP 8.1) (pull_request) Successful in 1m26s
CI Images / Build CI image (PHP 8.3) (pull_request) Successful in 2m3s
CI Images / Build CI image (PHP 8.5) (pull_request) Successful in 2m9s
CI / Tests (PHP 8.2) (pull_request) Successful in 1m7s
CI / No Debug Code (pull_request) Successful in 2s
CI / Tests (PHP 8.3) (pull_request) Successful in 3m8s
CI / Tests (PHP 8.1) (pull_request) Successful in 5m55s
CI / Tests (PHP 8.5) (pull_request) Successful in 6m21s
CI / Coding Standards & Static Analysis (pull_request) Successful in 18m26s
CI / Build Plugin Zip (pull_request) Skipped
setup-php installs PHP 8.3+ from apt on these arm64 runners: a ~145s floor against ~35s for 8.1/8.2, with a tail that twice ran past the step timeout and failed the run (#178). Caching the .debs softened it without removing the apt step, and 8.5 has the same problem. Add a per-version CI image built on php:<version>-cli-alpine and a workflow that publishes it to git.unsupervised.ca/unsupervised/ci-php:<version>. The org is public, so the packages pull anonymously. The image carries bash and nodejs because act_runner runs JavaScript actions inside the job container, GNU coreutils/grep/sed because the workflow scripts use `tac` and `grep --include`, and curl/jq/git/zip for release.yml and bin/build-zip.sh. Composer 2 and the intl and zip extensions round it out. Nothing consumes the images yet — ci.yml and release.yml switch over in a follow-up, because a job cannot run in an image that has not been published. Part of #187 Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01D9acV1mHktGAb1uyvNmrR2
This commit is contained in:
+70
@@ -0,0 +1,70 @@
|
||||
# CI images
|
||||
|
||||
CI and release jobs do not install PHP. They run inside prebuilt images
|
||||
published to the Gitea container registry:
|
||||
|
||||
```
|
||||
git.unsupervised.ca/unsupervised/ci-php:8.1
|
||||
git.unsupervised.ca/unsupervised/ci-php:8.2
|
||||
git.unsupervised.ca/unsupervised/ci-php:8.3
|
||||
git.unsupervised.ca/unsupervised/ci-php:8.5
|
||||
```
|
||||
|
||||
The `Unsupervised` org is public, so the packages pull anonymously — jobs need
|
||||
no registry credentials to use them.
|
||||
|
||||
## Why
|
||||
|
||||
`shivammathur/setup-php` installs PHP 8.3+ from apt/the ondrej PPA on these
|
||||
arm64 runners. That was a ~145s floor against ~35s for 8.1 and 8.2, with a
|
||||
tail that twice ran past the step timeout and failed the run outright
|
||||
(#178). Caching the `.deb`s helped, but the apt step itself remained, and PHP
|
||||
8.5 has the same shape of problem. Pulling a ~120MB image from a registry
|
||||
inside the cluster replaces the whole thing (#187).
|
||||
|
||||
## What is in the image
|
||||
|
||||
`.gitea/ci/Dockerfile` builds on `php:<version>-cli-alpine` and adds:
|
||||
|
||||
- **`bash` and `nodejs`** — act_runner runs JavaScript actions
|
||||
(`actions/checkout`, `actions/cache`, `actions/upload-artifact`) *inside*
|
||||
the job container and shells `run:` steps through bash. Without these, the
|
||||
first step of every job fails.
|
||||
- **`coreutils`, `gawk`, `grep`, `sed`** — GNU versions, because the workflow
|
||||
scripts use `tac` and `grep --include`, which busybox does not provide.
|
||||
- **`curl`, `jq`, `git`, `zip`, `unzip`** — used by `release.yml` and
|
||||
`bin/build-zip.sh`.
|
||||
- **`intl` and `zip` PHP extensions**, plus Composer 2. `mbstring` is already
|
||||
compiled into the official images.
|
||||
|
||||
## Publishing
|
||||
|
||||
`.gitea/workflows/ci-images.yml` builds and pushes them. It runs when the
|
||||
Dockerfile changes on `main`, weekly (so PHP patch releases and Alpine
|
||||
security updates land on their own), and on `workflow_dispatch`. On a pull
|
||||
request it builds without pushing, so a broken Dockerfile is caught before it
|
||||
reaches `main`.
|
||||
|
||||
## Adding or dropping a PHP version
|
||||
|
||||
1. Add the version to the `php` matrix in `.gitea/workflows/ci-images.yml`.
|
||||
2. Merge to `main`, or dispatch the workflow, and wait for the tag to appear.
|
||||
3. Add the version to the `test` matrix in `.gitea/workflows/ci.yml`.
|
||||
|
||||
Steps 2 and 3 cannot be one commit: a job cannot run in an image that has not
|
||||
been published yet.
|
||||
|
||||
## Architecture
|
||||
|
||||
The images are built natively on whichever runner picks the job, so they carry
|
||||
that runner's architecture only. Every runner in the pool is arm64 today. If
|
||||
one of a different architecture ever joins, it will overwrite these tags with
|
||||
its own arch and the rest will fail to pull — at which point the build needs
|
||||
`docker buildx` and a multi-arch manifest.
|
||||
|
||||
## If a push is refused
|
||||
|
||||
The build authenticates with `secrets.GITHUB_TOKEN`, the Actions task token.
|
||||
If the registry ever refuses it, create a personal access token with
|
||||
`package:write`, store it as the `REGISTRY_TOKEN` secret, and optionally set
|
||||
the `REGISTRY_USER` variable — the workflow prefers both when present.
|
||||
Reference in New Issue
Block a user