CI / Coding Standards & Static Analysis (pull_request) Successful in 37s
CI / Tests (PHP 8.1) (pull_request) Successful in 21s
CI / Tests (PHP 8.2) (pull_request) Successful in 20s
CI / Tests (PHP 8.3) (pull_request) Successful in 19s
CI / Tests (PHP 8.5) (pull_request) Successful in 19s
CI / No Debug Code (pull_request) Successful in 2s
CI / Build Plugin Zip (pull_request) Skipped
Replaces setup-php with `container:` in every job that needs PHP. The images published by ci-images.yml already carry PHP, Composer, the intl and zip extensions and the CLI tools the workflow scripts shell out to, so nothing installs PHP at job time any more. That removes the apt path #178 was about: a ~145s floor on 8.3 against ~35s on 8.1/8.2, with a tail that twice ran past the step timeout and failed the run. All three copies of the `Keep downloaded .debs` / `Cache apt packages` workaround go with it. no-debug and bump-version stay on the runner image — neither needs PHP, and no-debug wants the runner's GNU `grep --include`. The Composer cache moves to /composer/cache, which is COMPOSER_HOME in the image, and release.yml gains the cache step it never had. Also corrects the image size in docs/ci.md to the 67MB measured from the published manifest; the ~120MB in the original was an estimate. Closes #187 Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01D9acV1mHktGAb1uyvNmrR2
75 lines
3.1 KiB
Markdown
75 lines
3.1 KiB
Markdown
# 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 67MB 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`, `tar`** — GNU versions, because the
|
|
workflow scripts use `tac` and `grep --include`, which busybox does not
|
|
provide. GNU `tar` matters most: `actions/cache` shells out to
|
|
`tar --posix -P`, and busybox rejects those flags, so every cache step fails
|
|
without it. `zstd` is what `actions/cache` reaches for over gzip when it is
|
|
installed.
|
|
- **`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.
|