diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..94b7f9e --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,103 @@ +name: Build images + +on: + push: + branches: [main] + paths: + - "Dockerfile*" + - "build.sh" + - "common/**" + - "pecl/**" + - "php5.3/**" + - ".github/workflows/build.yml" + pull_request: + paths: + - "Dockerfile*" + - "build.sh" + - "common/**" + - "pecl/**" + - "php5.3/**" + - ".github/workflows/build.yml" + workflow_dispatch: + inputs: + versions: + description: "Versions to build, space separated (empty = all)" + required: false + default: "" + push: + description: "Push images to the registry" + type: boolean + default: false + no_cache: + description: "Build without layer cache (use after security fixes)" + type: boolean + default: false + +permissions: + contents: read + +concurrency: + group: build-${{ github.ref }} + cancel-in-progress: true + +jobs: + versions: + runs-on: ubuntu-24.04 + outputs: + matrix: ${{ steps.list.outputs.matrix }} + steps: + - uses: actions/checkout@v4 + - id: list + env: + VERSIONS: ${{ inputs.versions }} + run: | + if [ -n "${VERSIONS// }" ]; then + list=$(printf '%s\n' $VERSIONS) + else + list=$(./build.sh --list) + fi + echo "matrix=$(printf '%s\n' "$list" | jq -R . | jq -cs .)" >> "$GITHUB_OUTPUT" + + build: + needs: versions + runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: + version: ${{ fromJSON(needs.versions.outputs.matrix) }} + name: PHP ${{ matrix.version }} + env: + # Image name with the registry host, e.g. registry.example.com/php. + # Without a host it is Docker Hub (narel/php). + REGISTRY: ${{ vars.REGISTRY || 'narel/php' }} + PUSH: ${{ github.event_name == 'workflow_dispatch' && inputs.push && '1' || '' }} + NO_CACHE: ${{ inputs.no_cache && '1' || '' }} + steps: + - uses: actions/checkout@v4 + + # The default BuildKit hangs on apt from the jessie/wheezy era, so the + # legacy 5.x images use an older BuildKit (see README, "Building"). + - name: Set up old BuildKit for PHP 5.2 - 5.5 + if: contains(fromJSON('["5.5","5.4","5.3","5.2"]'), matrix.version) + run: | + docker buildx create --name oldbuilder --driver docker-container \ + --driver-opt image=moby/buildkit:v0.12.5 + echo "BUILDER=oldbuilder" >> "$GITHUB_ENV" + echo "PLATFORM=linux/amd64" >> "$GITHUB_ENV" + + # REGISTRY_HOST empty = Docker Hub. For your own registry set it to + # the host, e.g. registry.example.com or registry.example.com:5000. + - name: Log in to the registry + if: env.PUSH == '1' + uses: docker/login-action@v3 + with: + registry: ${{ vars.REGISTRY_HOST }} + username: ${{ secrets.REGISTRY_USERNAME }} + password: ${{ secrets.REGISTRY_PASSWORD }} + + - name: Build + run: ./build.sh "${{ matrix.version }}" + + - name: Smoke test + run: | + docker run --rm --entrypoint php "${REGISTRY}:${{ matrix.version }}" -v diff --git a/README.md b/README.md index 9e8857e..b997bc3 100644 --- a/README.md +++ b/README.md @@ -157,6 +157,30 @@ The full set of 13 images takes about 9 GB, plus a layer cache that grows to several GB. `docker builder prune -f` frees the cache only and **does not touch images**. `docker system prune` can delete finished images. +### GitHub Actions + +`.github/workflows/build.yml` builds every version in a separate job, in +parallel. It runs on pushes to `main` and on pull requests that touch the +Dockerfiles, `build.sh`, `common/`, `pecl/` or `php5.3/`. Only build, no push. + +To build and push by hand: **Actions → Build images → Run workflow**. Inputs: + +- `versions`: space separated, for example `8.5 7.4` (empty = all) +- `push`: push to the registry (see below) +- `no_cache`: build without layer cache, after security fixes + +Pushing is configured in **Settings → Secrets and variables → Actions**: + +| Name | Kind | Example | Meaning | +|------|------|---------|---------| +| `REGISTRY` | variable | `registry.example.com/php` | image name, with the registry host; default `narel/php` (Docker Hub) | +| `REGISTRY_HOST` | variable | `registry.example.com` | host to log in to; empty = Docker Hub | +| `REGISTRY_USERNAME` | secret | `ci-bot` | registry user | +| `REGISTRY_PASSWORD` | secret | | password or access token | + +The registry must be reachable from GitHub-hosted runners, over HTTPS with a +publicly trusted certificate. + --- ## Running diff --git a/build.sh b/build.sh index acd7cb8..c4c1ac2 100755 --- a/build.sh +++ b/build.sh @@ -9,6 +9,7 @@ # NO_PULL=1 ./build.sh 8.2 # do not refresh the base image # NO_CACHE=1 ./build.sh 8.5 # no layer cache - use after security fixes # BUILDER=oldbuilder ./build.sh 5.5 # build with the given buildx builder +# ./build.sh --list # print the available versions and exit # # --pull refreshes only the base image. If it has not changed, the apt-get # layer comes from the cache and new packages from the repository do NOT @@ -129,6 +130,11 @@ build_one() { fi } +if [ "${1:-}" = "--list" ]; then + all_versions + exit 0 +fi + if [ "$#" -gt 0 ]; then targets=("$@") else