From d8c1830c71fb08696e4dfc56595c0d445ef6f5d0 Mon Sep 17 00:00:00 2001 From: myrmidex Date: Mon, 17 Aug 2026 23:13:43 +0200 Subject: [PATCH] 46 - Tag CI image by composer.lock hash and build it in CI --- .forgejo/workflows/ci.yml | 42 +++++++++++++++++++++++++++++--- .forgejo/workflows/images.yml | 46 ----------------------------------- docker/build/Dockerfile.ci | 16 ++++++------ 3 files changed, 47 insertions(+), 57 deletions(-) delete mode 100644 .forgejo/workflows/images.yml diff --git a/.forgejo/workflows/ci.yml b/.forgejo/workflows/ci.yml index 6046793..a38115d 100644 --- a/.forgejo/workflows/ci.yml +++ b/.forgejo/workflows/ci.yml @@ -7,10 +7,46 @@ on: branches: [main, 'release/*'] jobs: - ci: + ci-image: runs-on: docker container: - image: forge.lvl0.xyz/lvl0/dishplanner-ci:php8.3-4 + image: catthehacker/ubuntu:act-latest + outputs: + tag: ${{ steps.meta.outputs.tag }} + steps: + - uses: https://data.forgejo.org/actions/checkout@v4 + + - name: Set up Docker Buildx + uses: https://data.forgejo.org/docker/setup-buildx-action@v3 + + - name: Login to Forgejo Registry + uses: https://data.forgejo.org/docker/login-action@v3 + with: + registry: forge.lvl0.xyz + username: ${{ github.actor }} + password: ${{ secrets.REGISTRY_TOKEN }} + + - name: Compute image tag from lockfile + id: meta + run: | + HASH="$(sha256sum composer.lock | cut -c1-12)" + echo "tag=php8.3-${HASH}" >> "$GITHUB_OUTPUT" + + - name: Build and push CI image + uses: https://data.forgejo.org/docker/build-push-action@v5 + with: + context: . + file: docker/build/Dockerfile.ci + push: true + tags: forge.lvl0.xyz/lvl0/dishplanner-ci:${{ steps.meta.outputs.tag }} + cache-from: type=registry,ref=forge.lvl0.xyz/lvl0/dishplanner-ci:buildcache + cache-to: type=registry,ref=forge.lvl0.xyz/lvl0/dishplanner-ci:buildcache,mode=max + + ci: + needs: ci-image + runs-on: docker + container: + image: forge.lvl0.xyz/lvl0/dishplanner-ci:${{ needs.ci-image.outputs.tag }} steps: - uses: https://data.forgejo.org/actions/checkout@v4 @@ -20,7 +56,7 @@ jobs: - name: Restore dependencies run: | cp -a /opt/deps/vendor ./vendor - composer install --no-interaction --no-progress --prefer-source + composer install --no-interaction --no-progress - name: Lint run: vendor/bin/pint --test diff --git a/.forgejo/workflows/images.yml b/.forgejo/workflows/images.yml deleted file mode 100644 index 0ebc9e5..0000000 --- a/.forgejo/workflows/images.yml +++ /dev/null @@ -1,46 +0,0 @@ -name: Build and Push Base Images - -on: - push: - branches: [main] - paths: - - 'docker/build/**' - - 'composer.json' - - 'composer.lock' - - '.forgejo/workflows/images.yml' - workflow_dispatch: - -jobs: - images: - runs-on: docker - container: - image: catthehacker/ubuntu:act-latest - strategy: - matrix: - include: - - name: dishplanner-ci - file: docker/build/Dockerfile.ci - version: php8.3-4 - steps: - - uses: https://data.forgejo.org/actions/checkout@v4 - - - name: Set up Docker Buildx - uses: https://data.forgejo.org/docker/setup-buildx-action@v3 - - - name: Login to Forgejo Registry - uses: https://data.forgejo.org/docker/login-action@v3 - with: - registry: forge.lvl0.xyz - username: ${{ github.actor }} - password: ${{ secrets.REGISTRY_TOKEN }} - - - name: Build and push - uses: https://data.forgejo.org/docker/build-push-action@v5 - with: - context: . - file: ${{ matrix.file }} - push: true - tags: | - forge.lvl0.xyz/lvl0/${{ matrix.name }}:${{ matrix.version }} - forge.lvl0.xyz/lvl0/${{ matrix.name }}:latest - forge.lvl0.xyz/lvl0/${{ matrix.name }}:${{ github.sha }} diff --git a/docker/build/Dockerfile.ci b/docker/build/Dockerfile.ci index f3270c8..753e52b 100644 --- a/docker/build/Dockerfile.ci +++ b/docker/build/Dockerfile.ci @@ -2,9 +2,9 @@ # Tests run against SQLite in memory (see .env.testing), so no database client # or cache extension is needed. # -# Published as dishplanner-ci:php8.3-. Bump the revision in the tag -# (.forgejo/workflows/images.yml) and in .forgejo/workflows/ci.yml whenever -# this file changes (runners cache mutable tags and will not re-pull them). +# Published as dishplanner-ci:php8.3-. The CI workflow +# builds and tags this image from the current lockfile, so a dependency change +# automatically yields a fresh, uniquely-tagged image (no manual revision bump). # # Debian-based rather than Alpine to avoid the DNS resolution timeouts against # codeload.github.com that the Alpine base hit during composer install. @@ -32,13 +32,13 @@ COPY --from=composer:2 /usr/bin/composer /usr/bin/composer # Bake the project's PHP dependencies (dev included) into the image so CI # restores them with a local copy instead of paying a per-run composer install -# over the network. Build this image on a network that isn't -# codeload-rate-limited (e.g. locally) — the Forgejo runner hits codeload 429 -# under --prefer-dist. +# over the network. --prefer-source clones via git instead of fetching dist +# archives, avoiding the codeload.github.com rate limits the runner hits under +# --prefer-dist. # # --no-scripts skips `php artisan package:discover` (the app isn't present # here). CI runs `composer install` after restoring vendor, which regenerates -# bootstrap/cache and tops up any lockfile drift between main and release/*. +# bootstrap/cache. WORKDIR /opt/deps COPY composer.json composer.lock ./ -RUN composer install --no-interaction --no-progress --prefer-dist --no-scripts +RUN composer install --no-interaction --no-progress --prefer-source --no-scripts