From 3c615a03c2a820647c4c24d951c2edee2161abf0 Mon Sep 17 00:00:00 2001 From: Ophir LOJKINE Date: Tue, 2 Jun 2026 17:27:41 +0200 Subject: [PATCH 01/16] Improve CI Docker cache reuse --- .github/workflows/ci.yml | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e173d927..0932e865 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,6 +14,15 @@ on: pull_request: branches: - "main" + paths-ignore: + - "docs/**" + - "README.md" + - ".github/workflows/release.yml" + - ".github/workflows/official-site.yml" + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} env: CARGO_TERM_COLOR: always @@ -175,13 +184,10 @@ jobs: labels: ${{ steps.meta.outputs.labels }} push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta.outputs.tags }} - cache-from: type=registry,ref=${{ env.REGISTRY_IMAGE }}:main${{ steps.suffix.outputs.suffix }} - # don't save cache on prs - cache-to: > - ${{ github.event_name != 'pull_request' - && format('type=registry,ref={0}:main{1},compression=zstd,mode=max', env.REGISTRY_IMAGE, steps.suffix.outputs.suffix) - || '' - }} + cache-from: | + type=gha,scope=sqlpage${{ steps.suffix.outputs.suffix }} + type=registry,ref=${{ env.REGISTRY_IMAGE }}:main${{ steps.suffix.outputs.suffix }} + cache-to: type=gha,scope=sqlpage${{ steps.suffix.outputs.suffix }},mode=max - name: Export digest if: github.event_name != 'pull_request' run: | @@ -228,7 +234,10 @@ jobs: ${{ steps.meta.outputs.tags }} ${{ env.REGISTRY_IMAGE }}:main outputs: type=docker,dest=${{ runner.temp }}/sqlpage.tar - cache-from: type=registry,ref=${{ env.REGISTRY_IMAGE }}:main-linux-amd64 + cache-from: | + type=gha,scope=sqlpage-linux-amd64 + type=registry,ref=${{ env.REGISTRY_IMAGE }}:main-linux-amd64 + cache-to: type=gha,scope=sqlpage-linux-amd64,mode=max - name: Upload SQLPage image uses: actions/upload-artifact@v7 with: @@ -247,8 +256,10 @@ jobs: labels: ${{ steps.meta.outputs.labels }} push: true tags: ${{ steps.meta.outputs.tags }} - cache-from: type=registry,ref=${{ env.REGISTRY_IMAGE }}:main-linux-amd64 - cache-to: type=registry,ref=${{ env.REGISTRY_IMAGE }}:main-linux-amd64,compression=zstd,mode=max + cache-from: | + type=gha,scope=sqlpage-linux-amd64 + type=registry,ref=${{ env.REGISTRY_IMAGE }}:main-linux-amd64 + cache-to: type=gha,scope=sqlpage-linux-amd64,mode=max - name: Export digest if: github.event_name != 'pull_request' run: | From 27becf2c4d855247f7ac3129bd5d480977243e38 Mon Sep 17 00:00:00 2001 From: Ophir LOJKINE Date: Tue, 2 Jun 2026 17:54:13 +0200 Subject: [PATCH 02/16] Ignore git metadata in Docker builds --- .dockerignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.dockerignore b/.dockerignore index be375585..5d17eabe 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,4 +1,5 @@ /target +.git/ sqlpage.db docs/ README.md @@ -11,4 +12,4 @@ configuration.md examples/ mssql/ tests/ -.idea/ \ No newline at end of file +.idea/ From dac2c5264bee72fc287877fcfe15e49c319d99dd Mon Sep 17 00:00:00 2001 From: Ophir LOJKINE Date: Tue, 2 Jun 2026 18:14:24 +0200 Subject: [PATCH 03/16] Use BuildKit cache mounts for Cargo Docker builds --- Dockerfile | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 443d4538..3ac0677f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,3 +1,5 @@ +# syntax=docker/dockerfile:1 + FROM --platform=$BUILDPLATFORM rust:1.95-slim AS builder WORKDIR /usr/src/sqlpage @@ -12,10 +14,16 @@ RUN cargo init . RUN /usr/local/bin/setup-cross-compilation.sh "$TARGETARCH" "$BUILDARCH" COPY Cargo.toml Cargo.lock ./ -RUN /usr/local/bin/build-dependencies.sh +RUN --mount=type=cache,target=/usr/local/cargo/registry,sharing=locked \ + --mount=type=cache,target=/usr/local/cargo/git,sharing=locked \ + --mount=type=cache,target=/usr/src/sqlpage/target \ + /usr/local/bin/build-dependencies.sh COPY . . -RUN /usr/local/bin/build-project.sh +RUN --mount=type=cache,target=/usr/local/cargo/registry,sharing=locked \ + --mount=type=cache,target=/usr/local/cargo/git,sharing=locked \ + --mount=type=cache,target=/usr/src/sqlpage/target \ + /usr/local/bin/build-project.sh # Default minimal image (busybox-based) FROM busybox:glibc AS minimal From 3a9372150ed30437c0b7872907a3e03ce1c38f5d Mon Sep 17 00:00:00 2001 From: Ophir LOJKINE Date: Tue, 2 Jun 2026 21:39:55 +0200 Subject: [PATCH 04/16] Make Docker dependency layer match real build inputs --- Dockerfile | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/Dockerfile b/Dockerfile index 3ac0677f..07ac38b9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,3 @@ -# syntax=docker/dockerfile:1 - FROM --platform=$BUILDPLATFORM rust:1.95-slim AS builder WORKDIR /usr/src/sqlpage @@ -13,17 +11,12 @@ RUN cargo init . RUN /usr/local/bin/setup-cross-compilation.sh "$TARGETARCH" "$BUILDARCH" -COPY Cargo.toml Cargo.lock ./ -RUN --mount=type=cache,target=/usr/local/cargo/registry,sharing=locked \ - --mount=type=cache,target=/usr/local/cargo/git,sharing=locked \ - --mount=type=cache,target=/usr/src/sqlpage/target \ - /usr/local/bin/build-dependencies.sh +COPY Cargo.toml Cargo.lock build.rs ./ +COPY sqlpage/ sqlpage/ +RUN /usr/local/bin/build-dependencies.sh COPY . . -RUN --mount=type=cache,target=/usr/local/cargo/registry,sharing=locked \ - --mount=type=cache,target=/usr/local/cargo/git,sharing=locked \ - --mount=type=cache,target=/usr/src/sqlpage/target \ - /usr/local/bin/build-project.sh +RUN /usr/local/bin/build-project.sh # Default minimal image (busybox-based) FROM busybox:glibc AS minimal From d6f10c36d204bb469ed12f77c277a144fc559a0a Mon Sep 17 00:00:00 2001 From: Ophir LOJKINE Date: Tue, 2 Jun 2026 21:52:40 +0200 Subject: [PATCH 05/16] Revert "Make Docker dependency layer match real build inputs" This reverts commit 3a9372150ed30437c0b7872907a3e03ce1c38f5d. --- Dockerfile | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 07ac38b9..3ac0677f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,3 +1,5 @@ +# syntax=docker/dockerfile:1 + FROM --platform=$BUILDPLATFORM rust:1.95-slim AS builder WORKDIR /usr/src/sqlpage @@ -11,12 +13,17 @@ RUN cargo init . RUN /usr/local/bin/setup-cross-compilation.sh "$TARGETARCH" "$BUILDARCH" -COPY Cargo.toml Cargo.lock build.rs ./ -COPY sqlpage/ sqlpage/ -RUN /usr/local/bin/build-dependencies.sh +COPY Cargo.toml Cargo.lock ./ +RUN --mount=type=cache,target=/usr/local/cargo/registry,sharing=locked \ + --mount=type=cache,target=/usr/local/cargo/git,sharing=locked \ + --mount=type=cache,target=/usr/src/sqlpage/target \ + /usr/local/bin/build-dependencies.sh COPY . . -RUN /usr/local/bin/build-project.sh +RUN --mount=type=cache,target=/usr/local/cargo/registry,sharing=locked \ + --mount=type=cache,target=/usr/local/cargo/git,sharing=locked \ + --mount=type=cache,target=/usr/src/sqlpage/target \ + /usr/local/bin/build-project.sh # Default minimal image (busybox-based) FROM busybox:glibc AS minimal From 71d66897acc3eb1fcd9202dc2adcd60ffea14f9d Mon Sep 17 00:00:00 2001 From: Ophir LOJKINE Date: Tue, 2 Jun 2026 22:19:43 +0200 Subject: [PATCH 06/16] Revert "Use BuildKit cache mounts for Cargo Docker builds" This reverts commit dac2c5264bee72fc287877fcfe15e49c319d99dd. --- Dockerfile | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/Dockerfile b/Dockerfile index 3ac0677f..443d4538 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,3 @@ -# syntax=docker/dockerfile:1 - FROM --platform=$BUILDPLATFORM rust:1.95-slim AS builder WORKDIR /usr/src/sqlpage @@ -14,16 +12,10 @@ RUN cargo init . RUN /usr/local/bin/setup-cross-compilation.sh "$TARGETARCH" "$BUILDARCH" COPY Cargo.toml Cargo.lock ./ -RUN --mount=type=cache,target=/usr/local/cargo/registry,sharing=locked \ - --mount=type=cache,target=/usr/local/cargo/git,sharing=locked \ - --mount=type=cache,target=/usr/src/sqlpage/target \ - /usr/local/bin/build-dependencies.sh +RUN /usr/local/bin/build-dependencies.sh COPY . . -RUN --mount=type=cache,target=/usr/local/cargo/registry,sharing=locked \ - --mount=type=cache,target=/usr/local/cargo/git,sharing=locked \ - --mount=type=cache,target=/usr/src/sqlpage/target \ - /usr/local/bin/build-project.sh +RUN /usr/local/bin/build-project.sh # Default minimal image (busybox-based) FROM busybox:glibc AS minimal From 925dbf33124ee25733187d6e275f5ac0b47c74e8 Mon Sep 17 00:00:00 2001 From: Ophir LOJKINE Date: Wed, 3 Jun 2026 10:11:07 +0200 Subject: [PATCH 07/16] Test CI incremental Rust caches --- .github/workflows/ci.yml | 14 ++++++++++++++ Dockerfile | 3 ++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0932e865..912277af 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -117,10 +117,24 @@ jobs: uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 env: NODE_OPTIONS: --no-deprecation + - name: Set up Windows incremental cache + uses: actions/cache@v5 + with: + path: | + target/debug/.fingerprint/sqlpage-* + target/debug/build/sqlpage-* + target/debug/deps/sqlpage* + target/debug/incremental + target/debug/sqlpage.exe + target/debug/sqlpage.pdb + key: windows-incremental-${{ github.event.pull_request.number || github.ref_name }}-${{ github.sha }} + restore-keys: | + windows-incremental-${{ github.event.pull_request.number || github.ref_name }}- - name: Check port usage run: netstat -bano - run: cargo test env: + CARGO_INCREMENTAL: 1 RUST_BACKTRACE: 1 - name: Upload Windows binary uses: actions/upload-artifact@v7 diff --git a/Dockerfile b/Dockerfile index 443d4538..07ac38b9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,7 +11,8 @@ RUN cargo init . RUN /usr/local/bin/setup-cross-compilation.sh "$TARGETARCH" "$BUILDARCH" -COPY Cargo.toml Cargo.lock ./ +COPY Cargo.toml Cargo.lock build.rs ./ +COPY sqlpage/ sqlpage/ RUN /usr/local/bin/build-dependencies.sh COPY . . From 6cb59d976944257f5f9fc0bfdd86d334e2b9899b Mon Sep 17 00:00:00 2001 From: Ophir LOJKINE Date: Wed, 3 Jun 2026 10:30:33 +0200 Subject: [PATCH 08/16] Remove slow Windows port diagnostic --- .github/workflows/ci.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 912277af..d26bb86d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -130,8 +130,6 @@ jobs: key: windows-incremental-${{ github.event.pull_request.number || github.ref_name }}-${{ github.sha }} restore-keys: | windows-incremental-${{ github.event.pull_request.number || github.ref_name }}- - - name: Check port usage - run: netstat -bano - run: cargo test env: CARGO_INCREMENTAL: 1 From f9e1dab921e130d614a1fdeb783122247adc916f Mon Sep 17 00:00:00 2001 From: Ophir LOJKINE Date: Wed, 3 Jun 2026 10:37:28 +0200 Subject: [PATCH 09/16] Narrow Windows incremental cache --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d26bb86d..1a0b8904 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -123,10 +123,10 @@ jobs: path: | target/debug/.fingerprint/sqlpage-* target/debug/build/sqlpage-* - target/debug/deps/sqlpage* - target/debug/incremental - target/debug/sqlpage.exe - target/debug/sqlpage.pdb + target/debug/deps/libsqlpage-*.rlib + target/debug/deps/libsqlpage-*.rmeta + target/debug/deps/sqlpage-*.d + target/debug/incremental/sqlpage-* key: windows-incremental-${{ github.event.pull_request.number || github.ref_name }}-${{ github.sha }} restore-keys: | windows-incremental-${{ github.event.pull_request.number || github.ref_name }}- From 1de29f2e7c1cc1ac7f08d2c0193a0a66cb73dca3 Mon Sep 17 00:00:00 2001 From: Ophir LOJKINE Date: Wed, 3 Jun 2026 15:31:27 +0200 Subject: [PATCH 10/16] Reuse Linux test artifacts in CI --- .github/workflows/ci.yml | 96 +++++++++++++++++++++++++++++--- .github/workflows/playwright.yml | 46 --------------- 2 files changed, 88 insertions(+), 54 deletions(-) delete mode 100644 .github/workflows/playwright.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1a0b8904..475f321b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -46,6 +46,26 @@ jobs: - run: cargo fmt --all -- --check - run: cargo clippy --all-targets --all-features -- -D warnings - run: cargo test --features odbc-static + # The database matrix below runs the same Rust test harnesses against + # different DATABASE_URL values. Package the Linux test executables once + # here so those jobs do not recompile SQLPage or its dependencies. + - name: Package Linux Rust test binaries + run: | + set -euo pipefail + rm -rf target/sqlpage-test-binaries + mkdir -p target/sqlpage-test-binaries + cargo test --features odbc-static --no-run --message-format=json \ + | jq -r 'select(.profile.test == true and .executable != null) | .executable' \ + | while IFS= read -r test_binary; do + cp -- "$test_binary" target/sqlpage-test-binaries/ + done + test -n "$(find target/sqlpage-test-binaries -maxdepth 1 -type f -print -quit)" + tar -C target/sqlpage-test-binaries -czf target/sqlpage-linux-test-binaries.tar.gz . + - name: Upload Linux Rust test binaries + uses: actions/upload-artifact@v7 + with: + name: sqlpage-linux-test-binaries + path: "target/sqlpage-linux-test-binaries.tar.gz" - name: Upload Linux binary uses: actions/upload-artifact@v7 with: @@ -54,6 +74,7 @@ jobs: test: runs-on: ubuntu-latest + needs: compile_and_lint strategy: matrix: include: @@ -75,13 +96,18 @@ jobs: db_url: "Driver=Oracle 21 ODBC driver;Dbq=//127.0.0.1:1521/FREEPDB1;Uid=root;Pwd=Password123!" steps: - uses: actions/checkout@v6 - - name: Set up cargo cache - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 - env: - NODE_OPTIONS: --no-deprecation + # Reuse the exact Linux test harnesses produced by compile_and_lint. + # This keeps the DB matrix focused on database behavior instead of + # compiling the same Rust crate five more times. + - name: Download Linux Rust test binaries + uses: actions/download-artifact@v8 with: - shared-key: rust-sqlpage-proj-test - save-if: false + name: sqlpage-linux-test-binaries + path: target + - name: Extract Linux Rust test binaries + run: | + mkdir -p target/sqlpage-test-binaries + tar -xzf target/sqlpage-linux-test-binaries.tar.gz -C target/sqlpage-test-binaries - name: Install PostgreSQL ODBC driver if: matrix.setup_odbc run: sudo apt-get install -y odbc-postgresql @@ -95,7 +121,7 @@ jobs: sudo alien -i oracle-instantclient-odbc-21.21.0.0.0-1.el8.x86_64.rpm sudo ln -s /usr/lib/x86_64-linux-gnu/libaio.so.1t64 /usr/lib/libaio.so.1 sudo /usr/lib/oracle/21/client64/bin/odbc_update_ini.sh / /usr/lib/oracle/21/client64/lib - echo "LD_LIBRARY_PATH=/usr/lib/oracle/21/client64/lib:$LD_LIBRARY_PATH" >> $GITHUB_ENV + echo "LD_LIBRARY_PATH=/usr/lib/oracle/21/client64/lib:$LD_LIBRARY_PATH" >> "$GITHUB_ENV" - name: Start database container run: docker compose up --wait ${{ matrix.container }} - name: Show container logs @@ -103,7 +129,19 @@ jobs: run: docker compose logs ${{ matrix.container }} - name: Run tests against ${{ matrix.database }} timeout-minutes: 5 - run: cargo test --features odbc-static + run: | + set -euo pipefail + shopt -s nullglob + test_binaries=(target/sqlpage-test-binaries/*) + if ((${#test_binaries[@]} == 0)); then + echo "No test binaries were found in target/sqlpage-test-binaries" >&2 + exit 1 + fi + for test_binary in "${test_binaries[@]}"; do + echo "::group::$(basename "$test_binary")" + "$test_binary" + echo "::endgroup::" + done env: DATABASE_URL: ${{ matrix.db_url }} MALLOC_CHECK_: 3 @@ -140,6 +178,48 @@ jobs: name: sqlpage-windows-debug path: "target/debug/sqlpage.exe" + playwright: + runs-on: ubuntu-latest + timeout-minutes: 10 + needs: compile_and_lint + defaults: + run: + working-directory: ./tests/end-to-end + steps: + - uses: actions/checkout@v6 + - uses: actions/setup-node@v6 + with: + node-version: lts/* + cache: 'npm' + cache-dependency-path: ./tests/end-to-end/package-lock.json + - run: sudo apt-get update && sudo apt-get install -y unixodbc-dev + - run: npm ci && npx playwright install --with-deps chromium + # The browser tests exercise the official site, but they do not need a + # separate Rust build. Reuse the binary compiled and tested above. + - name: Download Linux binary + uses: actions/download-artifact@v8 + with: + name: sqlpage-linux-debug + path: ${{ runner.temp }}/sqlpage-bin + - name: Start official site and wait for it to be ready + timeout-minutes: 1 + run: | + chmod +x "${{ runner.temp }}/sqlpage-bin/sqlpage" + "${{ runner.temp }}/sqlpage-bin/sqlpage" 2>/tmp/stderrlog & + tail -f /tmp/stderrlog | grep -q "started successfully" + working-directory: ./examples/official-site + - name: Run Playwright tests + run: npx playwright test + - name: show server logs + if: failure() + run: cat /tmp/stderrlog + - uses: actions/upload-artifact@v7 + if: always() + with: + name: playwright-report + path: ./tests/end-to-end/playwright-report/ + retention-days: 30 + docker_build: runs-on: ubuntu-latest strategy: diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml deleted file mode 100644 index 5b7cd3b9..00000000 --- a/.github/workflows/playwright.yml +++ /dev/null @@ -1,46 +0,0 @@ -name: End to end Tests -on: - push: - branches: [ main, master ] - pull_request: - branches: [ main, master ] -jobs: - test: - timeout-minutes: 10 - defaults: - run: - working-directory: ./tests/end-to-end - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - - name: Set up cargo cache - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 - env: - NODE_OPTIONS: --no-deprecation - - uses: actions/setup-node@v6 - with: - node-version: lts/* - cache: 'npm' - cache-dependency-path: ./tests/end-to-end/package-lock.json - - run: sudo apt-get update && sudo apt-get install -y unixodbc-dev - - run: npm ci && npx playwright install --with-deps chromium - - name: build sqlpage - run: cargo build - working-directory: ./examples/official-site - - name: start official site and wait for it to be ready - timeout-minutes: 1 - run: | - cargo run 2>/tmp/stderrlog & - tail -f /tmp/stderrlog | grep -q "started successfully" - working-directory: ./examples/official-site - - name: Run Playwright tests - run: npx playwright test - - name: show server logs - if: failure() - run: cat /tmp/stderrlog - - uses: actions/upload-artifact@v7 - if: always() - with: - name: playwright-report - path: ./tests/end-to-end/playwright-report/ - retention-days: 30 From e28f519f3733d339ec68e8b32330f6b706438905 Mon Sep 17 00:00:00 2001 From: Ophir LOJKINE Date: Wed, 3 Jun 2026 15:36:53 +0200 Subject: [PATCH 11/16] Avoid duplicate Linux test execution in CI --- .github/workflows/ci.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 475f321b..57b7b4a9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -45,7 +45,6 @@ jobs: save-if: ${{ github.ref == 'refs/heads/main' }} - run: cargo fmt --all -- --check - run: cargo clippy --all-targets --all-features -- -D warnings - - run: cargo test --features odbc-static # The database matrix below runs the same Rust test harnesses against # different DATABASE_URL values. Package the Linux test executables once # here so those jobs do not recompile SQLPage or its dependencies. @@ -61,6 +60,8 @@ jobs: done test -n "$(find target/sqlpage-test-binaries -maxdepth 1 -type f -print -quit)" tar -C target/sqlpage-test-binaries -czf target/sqlpage-linux-test-binaries.tar.gz . + - name: Build Linux binary + run: cargo build --features odbc-static - name: Upload Linux Rust test binaries uses: actions/upload-artifact@v7 with: @@ -78,6 +79,9 @@ jobs: strategy: matrix: include: + - database: sqlite + container: "" + db_url: "sqlite::memory:" - database: postgres container: postgres db_url: "postgres://root:Password123!@127.0.0.1/sqlpage" @@ -123,9 +127,10 @@ jobs: sudo /usr/lib/oracle/21/client64/bin/odbc_update_ini.sh / /usr/lib/oracle/21/client64/lib echo "LD_LIBRARY_PATH=/usr/lib/oracle/21/client64/lib:$LD_LIBRARY_PATH" >> "$GITHUB_ENV" - name: Start database container + if: matrix.container != '' run: docker compose up --wait ${{ matrix.container }} - name: Show container logs - if: failure() + if: failure() && matrix.container != '' run: docker compose logs ${{ matrix.container }} - name: Run tests against ${{ matrix.database }} timeout-minutes: 5 From 8c65657769d7fe28cd51d8f706a17bc9c3d899ac Mon Sep 17 00:00:00 2001 From: Ophir LOJKINE Date: Wed, 3 Jun 2026 16:16:58 +0200 Subject: [PATCH 12/16] Isolate Docker cache scopes by recipe --- .github/workflows/ci.yml | 43 ++++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 57b7b4a9..9b776781 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -255,6 +255,19 @@ jobs: suffix="${suffix}-${{ matrix.variant }}" fi echo "suffix=${suffix}" >> "$GITHUB_OUTPUT" + - id: cache-scope + name: Docker cache scope + run: | + ref_scope="main" + if [[ "${{ github.event_name }}" == "pull_request" ]]; then + ref_scope="pr-${{ github.event.pull_request.number }}" + fi + + recipe_hash="${{ hashFiles('Dockerfile', 'Cargo.toml', 'Cargo.lock', 'build.rs', 'scripts/**', 'sqlpage/**') }}" + { + echo "current=sqlpage-${ref_scope}${{ steps.suffix.outputs.suffix }}-${recipe_hash}" + echo "main=sqlpage-main${{ steps.suffix.outputs.suffix }}-${recipe_hash}" + } >> "$GITHUB_OUTPUT" - name: Docker meta id: meta uses: docker/metadata-action@v6 @@ -282,9 +295,10 @@ jobs: push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta.outputs.tags }} cache-from: | - type=gha,scope=sqlpage${{ steps.suffix.outputs.suffix }} + type=gha,scope=${{ steps.cache-scope.outputs.current }} + type=gha,scope=${{ steps.cache-scope.outputs.main }} type=registry,ref=${{ env.REGISTRY_IMAGE }}:main${{ steps.suffix.outputs.suffix }} - cache-to: type=gha,scope=sqlpage${{ steps.suffix.outputs.suffix }},mode=max + cache-to: type=gha,scope=${{ steps.cache-scope.outputs.current }},mode=max - name: Export digest if: github.event_name != 'pull_request' run: | @@ -314,6 +328,20 @@ jobs: flavor: suffix=-linux-amd64 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v4 + - id: cache-scope + name: Docker cache scope + run: | + ref_scope="main" + if [[ "${{ github.event_name }}" == "pull_request" ]]; then + ref_scope="pr-${{ github.event.pull_request.number }}" + fi + + recipe_hash="${{ hashFiles('Dockerfile', 'Cargo.toml', 'Cargo.lock', 'build.rs', 'scripts/**', 'sqlpage/**') }}" + { + echo "artifact=sqlpage-${ref_scope}-linux-amd64-hurl-${recipe_hash}" + echo "current=sqlpage-${ref_scope}-linux-amd64-${recipe_hash}" + echo "main=sqlpage-main-linux-amd64-${recipe_hash}" + } >> "$GITHUB_OUTPUT" - name: Login to Docker Hub if: github.event_name != 'pull_request' uses: docker/login-action@v4 @@ -332,9 +360,11 @@ jobs: ${{ env.REGISTRY_IMAGE }}:main outputs: type=docker,dest=${{ runner.temp }}/sqlpage.tar cache-from: | - type=gha,scope=sqlpage-linux-amd64 + type=gha,scope=${{ steps.cache-scope.outputs.artifact }} + type=gha,scope=${{ steps.cache-scope.outputs.current }} + type=gha,scope=${{ steps.cache-scope.outputs.main }} type=registry,ref=${{ env.REGISTRY_IMAGE }}:main-linux-amd64 - cache-to: type=gha,scope=sqlpage-linux-amd64,mode=max + cache-to: type=gha,scope=${{ steps.cache-scope.outputs.artifact }},mode=max - name: Upload SQLPage image uses: actions/upload-artifact@v7 with: @@ -354,9 +384,10 @@ jobs: push: true tags: ${{ steps.meta.outputs.tags }} cache-from: | - type=gha,scope=sqlpage-linux-amd64 + type=gha,scope=${{ steps.cache-scope.outputs.current }} + type=gha,scope=${{ steps.cache-scope.outputs.main }} type=registry,ref=${{ env.REGISTRY_IMAGE }}:main-linux-amd64 - cache-to: type=gha,scope=sqlpage-linux-amd64,mode=max + cache-to: type=gha,scope=${{ steps.cache-scope.outputs.current }},mode=max - name: Export digest if: github.event_name != 'pull_request' run: | From b6792210de47e6040d9abba44b5a59851fc955e4 Mon Sep 17 00:00:00 2001 From: Ophir LOJKINE Date: Wed, 3 Jun 2026 16:31:02 +0200 Subject: [PATCH 13/16] Warm Docker dependencies for lib target --- Dockerfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 07ac38b9..5c39413b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,7 +7,9 @@ ARG CARGO_PROFILE=superoptimized ENV CARGO_PROFILE=$CARGO_PROFILE COPY scripts/ /usr/local/bin/ -RUN cargo init . +RUN cargo init --lib . && \ + printf 'pub fn dependency_warmup() {}\n' > src/lib.rs && \ + printf 'fn main() { sqlpage::dependency_warmup(); }\n' > src/main.rs RUN /usr/local/bin/setup-cross-compilation.sh "$TARGETARCH" "$BUILDARCH" From ed4b97ef1d026c31ed2a792ee2450c4acb4cfa5c Mon Sep 17 00:00:00 2001 From: Ophir LOJKINE Date: Wed, 3 Jun 2026 16:45:17 +0200 Subject: [PATCH 14/16] Warm Docker dependencies with Cargo config --- .github/workflows/ci.yml | 4 ++-- Dockerfile | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9b776781..a0e40a11 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -263,7 +263,7 @@ jobs: ref_scope="pr-${{ github.event.pull_request.number }}" fi - recipe_hash="${{ hashFiles('Dockerfile', 'Cargo.toml', 'Cargo.lock', 'build.rs', 'scripts/**', 'sqlpage/**') }}" + recipe_hash="${{ hashFiles('Dockerfile', '.cargo/**', 'Cargo.toml', 'Cargo.lock', 'build.rs', 'scripts/**', 'sqlpage/**') }}" { echo "current=sqlpage-${ref_scope}${{ steps.suffix.outputs.suffix }}-${recipe_hash}" echo "main=sqlpage-main${{ steps.suffix.outputs.suffix }}-${recipe_hash}" @@ -336,7 +336,7 @@ jobs: ref_scope="pr-${{ github.event.pull_request.number }}" fi - recipe_hash="${{ hashFiles('Dockerfile', 'Cargo.toml', 'Cargo.lock', 'build.rs', 'scripts/**', 'sqlpage/**') }}" + recipe_hash="${{ hashFiles('Dockerfile', '.cargo/**', 'Cargo.toml', 'Cargo.lock', 'build.rs', 'scripts/**', 'sqlpage/**') }}" { echo "artifact=sqlpage-${ref_scope}-linux-amd64-hurl-${recipe_hash}" echo "current=sqlpage-${ref_scope}-linux-amd64-${recipe_hash}" diff --git a/Dockerfile b/Dockerfile index 5c39413b..7684eab7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,12 +7,11 @@ ARG CARGO_PROFILE=superoptimized ENV CARGO_PROFILE=$CARGO_PROFILE COPY scripts/ /usr/local/bin/ -RUN cargo init --lib . && \ - printf 'pub fn dependency_warmup() {}\n' > src/lib.rs && \ - printf 'fn main() { sqlpage::dependency_warmup(); }\n' > src/main.rs +RUN cargo init . RUN /usr/local/bin/setup-cross-compilation.sh "$TARGETARCH" "$BUILDARCH" +COPY .cargo/ .cargo/ COPY Cargo.toml Cargo.lock build.rs ./ COPY sqlpage/ sqlpage/ RUN /usr/local/bin/build-dependencies.sh From 1958b8994a3c9418c102392452a1cc8d2db941c8 Mon Sep 17 00:00:00 2001 From: Ophir LOJKINE Date: Wed, 3 Jun 2026 23:17:48 +0200 Subject: [PATCH 15/16] Stabilize Docker metadata for cache keys --- .github/workflows/ci.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a0e40a11..e0bfae9c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -274,6 +274,8 @@ jobs: with: images: ${{ env.REGISTRY_IMAGE }} flavor: suffix=${{ steps.suffix.outputs.suffix }} + labels: | + org.opencontainers.image.created=1970-01-01T00:00:00Z - name: Set up QEMU uses: docker/setup-qemu-action@v4 - name: Set up Docker Buildx @@ -326,6 +328,8 @@ jobs: with: images: ${{ env.REGISTRY_IMAGE }} flavor: suffix=-linux-amd64 + labels: | + org.opencontainers.image.created=1970-01-01T00:00:00Z - name: Set up Docker Buildx uses: docker/setup-buildx-action@v4 - id: cache-scope From d380e0800126ee7e5c01e44d7a7720f834495696 Mon Sep 17 00:00:00 2001 From: Ophir LOJKINE Date: Wed, 3 Jun 2026 23:48:38 +0200 Subject: [PATCH 16/16] Use Git context for Docker builds --- .github/workflows/ci.yml | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e0bfae9c..be312d63 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -290,7 +290,10 @@ jobs: id: build uses: docker/build-push-action@v7 with: - context: . + # Use BuildKit's Git context instead of the mutable runner workspace. + # The dependency cache should be keyed by committed source, not by a + # per-job local context stream. + context: "{{defaultContext}}" platforms: ${{ matrix.platform }} target: ${{ matrix.variant }} labels: ${{ steps.meta.outputs.labels }} @@ -355,7 +358,10 @@ jobs: - name: Build image for Hurl examples uses: docker/build-push-action@v7 with: - context: . + # Use BuildKit's Git context instead of the mutable runner workspace. + # The dependency cache should be keyed by committed source, not by a + # per-job local context stream. + context: "{{defaultContext}}" platforms: linux/amd64 target: minimal labels: ${{ steps.meta.outputs.labels }} @@ -381,7 +387,10 @@ jobs: if: github.event_name != 'pull_request' uses: docker/build-push-action@v7 with: - context: . + # Use BuildKit's Git context instead of the mutable runner workspace. + # The dependency cache should be keyed by committed source, not by a + # per-job local context stream. + context: "{{defaultContext}}" platforms: linux/amd64 target: minimal labels: ${{ steps.meta.outputs.labels }}