diff --git a/.github/workflows/regression.yml b/.github/workflows/regression.yml index 73871aa2..c8dd04eb 100644 --- a/.github/workflows/regression.yml +++ b/.github/workflows/regression.yml @@ -11,6 +11,12 @@ concurrency: group: regression-${{ github.ref }} cancel-in-progress: true +# Least-privilege token: only reading code. Jobs that need more (e.g. GHA +# cache reads/writes from docker/build-push-action with `type=gha`) elevate +# their own permissions inline. +permissions: + contents: read + jobs: changes: name: Detect changes @@ -30,10 +36,55 @@ jobs: - "packages/engine/**" - "Dockerfile*" - regression-shards: + # Build the regression Docker image once, export it as a tarball, and upload + # as an artifact. Each matrix shard then downloads + `docker load`s it instead + # of rebuilding from cache. Measured on PR #419: the Docker build step takes + # ~4 min per shard even with GHA cache, so 11 shards = ~44 min of redundant + # build time per run. This job replaces that with a single ~4 min build plus + # ~15s of artifact download per shard. + build-image: + name: Build regression test image needs: changes if: needs.changes.outputs.code == 'true' runs-on: ubuntu-latest + timeout-minutes: 20 + permissions: + contents: read + actions: write # docker/build-push-action `type=gha` cache reads + writes + steps: + - name: Checkout + uses: actions/checkout@v4 + # No LFS needed here — Dockerfile.test only copies source + package manifests, + # not the golden baselines under packages/producer/tests/**/output. + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build test image to tarball + uses: docker/build-push-action@v6 + with: + context: . + file: Dockerfile.test + tags: hyperframes-producer:test + cache-from: type=gha,scope=regression-test-image + cache-to: type=gha,mode=max,scope=regression-test-image + outputs: type=docker,dest=/tmp/regression-test-image.tar + + - name: Report image size + run: ls -lh /tmp/regression-test-image.tar + + - name: Upload image artifact + uses: actions/upload-artifact@v4 + with: + name: regression-test-image + path: /tmp/regression-test-image.tar + retention-days: 1 + compression-level: 1 + + regression-shards: + needs: [changes, build-image] + if: needs.changes.outputs.code == 'true' + runs-on: ubuntu-latest timeout-minutes: 40 strategy: fail-fast: false @@ -79,18 +130,16 @@ jobs: fi done - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Build test Docker image (cached) - uses: docker/build-push-action@v6 + - name: Download test image artifact + uses: actions/download-artifact@v4 with: - context: . - file: Dockerfile.test - load: true - tags: hyperframes-producer:test - cache-from: type=gha,scope=regression-test-image - cache-to: type=gha,mode=max,scope=regression-test-image + name: regression-test-image + path: /tmp + + - name: Load test image + run: | + docker load -i /tmp/regression-test-image.tar + docker image ls hyperframes-producer:test - name: "Run regression shard: ${{ matrix.shard }}" run: |