Improve CI Docker cache reuse #2467
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| tags: | |
| - "v*" # Push events to matching v*, i.e. v1.0, v20.15.10 | |
| branches: | |
| - "main" | |
| paths-ignore: | |
| - "docs/**" | |
| - "README.md" | |
| - ".github/workflows/release.yml" | |
| - ".github/workflows/official-site.yml" | |
| 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 | |
| REGISTRY_USERNAME: lovasoa | |
| REGISTRY_IMAGE: lovasoa/sqlpage | |
| jobs: | |
| compile_and_lint: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - run: npm ci | |
| - run: npm test | |
| - name: Set up cargo cache | |
| uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 | |
| env: | |
| NODE_OPTIONS: --no-deprecation | |
| with: | |
| shared-key: rust-sqlpage-proj-test | |
| 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 | |
| - name: Upload Linux binary | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: sqlpage-linux-debug | |
| path: "target/debug/sqlpage" | |
| test: | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| include: | |
| - database: postgres | |
| container: postgres | |
| db_url: "postgres://root:Password123!@127.0.0.1/sqlpage" | |
| - database: mysql | |
| container: mysql | |
| db_url: "mysql://root:Password123!@127.0.0.1/sqlpage" | |
| - database: mssql | |
| container: mssql | |
| db_url: "mssql://root:Password123!@127.0.0.1/sqlpage" | |
| - database: odbc | |
| container: postgres | |
| db_url: "Driver=PostgreSQL Unicode;Server=127.0.0.1;Port=5432;Database=sqlpage;UID=root;PWD=Password123!" | |
| setup_odbc: true | |
| - database: oracle | |
| container: oracle | |
| 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 | |
| with: | |
| shared-key: rust-sqlpage-proj-test | |
| save-if: false | |
| - name: Install PostgreSQL ODBC driver | |
| if: matrix.setup_odbc | |
| run: sudo apt-get install -y odbc-postgresql | |
| - name: Install Oracle ODBC driver | |
| if: matrix.database == 'oracle' | |
| run: | | |
| sudo apt-get install -y alien libaio1t64 libodbcinst2 unixodbc | |
| sudo rpm --import https://yum.oracle.com/RPM-GPG-KEY-oracle-ol8 | |
| wget https://yum.oracle.com/repo/OracleLinux/OL8/oracle/instantclient21/x86_64/getPackage/oracle-instantclient-{basic,odbc}-21.21.0.0.0-1.el8.x86_64.rpm | |
| sudo alien -i oracle-instantclient-basic-21.21.0.0.0-1.el8.x86_64.rpm | |
| 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 | |
| - name: Start database container | |
| run: docker compose up --wait ${{ matrix.container }} | |
| - name: Show container logs | |
| if: failure() | |
| run: docker compose logs ${{ matrix.container }} | |
| - name: Run tests against ${{ matrix.database }} | |
| timeout-minutes: 5 | |
| run: cargo test --features odbc-static | |
| env: | |
| DATABASE_URL: ${{ matrix.db_url }} | |
| MALLOC_CHECK_: 3 | |
| MALLOC_PERTURB_: 10 | |
| windows_test: | |
| runs-on: windows-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Set up cargo cache | |
| 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/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 }}- | |
| - run: cargo test | |
| env: | |
| CARGO_INCREMENTAL: 1 | |
| RUST_BACKTRACE: 1 | |
| - name: Upload Windows binary | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: sqlpage-windows-debug | |
| path: "target/debug/sqlpage.exe" | |
| docker_build: | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| platform: | |
| - linux/amd64 | |
| - linux/arm/v7 | |
| - linux/arm64 | |
| variant: | |
| - minimal | |
| - duckdb | |
| exclude: | |
| # DuckDB ODBC is not available for armv7 | |
| - platform: linux/arm/v7 | |
| variant: duckdb | |
| # This build is shared with the Hurl example jobs. | |
| - platform: linux/amd64 | |
| variant: minimal | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - id: suffix | |
| name: Cache name suffix | |
| run: | | |
| suffix="-$(tr '/' '-' <<< "${{ matrix.platform }}")" | |
| if [[ "${{ matrix.variant }}" != "minimal" ]]; then | |
| suffix="${suffix}-${{ matrix.variant }}" | |
| fi | |
| echo "suffix=${suffix}" >> "$GITHUB_OUTPUT" | |
| - name: Docker meta | |
| id: meta | |
| uses: docker/metadata-action@v6 | |
| with: | |
| images: ${{ env.REGISTRY_IMAGE }} | |
| flavor: suffix=${{ steps.suffix.outputs.suffix }} | |
| - name: Set up QEMU | |
| uses: docker/setup-qemu-action@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v4 | |
| - name: Login to Docker Hub | |
| if: github.event_name != 'pull_request' | |
| uses: docker/login-action@v4 | |
| with: | |
| username: ${{ env.REGISTRY_USERNAME }} | |
| password: ${{ secrets.DOCKERHUB_TOKEN }} | |
| - name: Build and push by digest | |
| id: build | |
| uses: docker/build-push-action@v7 | |
| with: | |
| context: . | |
| platforms: ${{ matrix.platform }} | |
| target: ${{ matrix.variant }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| push: ${{ github.event_name != 'pull_request' }} | |
| tags: ${{ steps.meta.outputs.tags }} | |
| 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: | | |
| mkdir -p /tmp/digests | |
| digest="${{ steps.build.outputs.digest }}" | |
| touch "/tmp/digests/${digest#sha256:}" | |
| - name: Upload digest | |
| uses: actions/upload-artifact@v7 | |
| if: github.event_name != 'pull_request' | |
| with: | |
| name: digests-${{ matrix.variant }}${{ steps.suffix.outputs.suffix }} | |
| path: /tmp/digests/* | |
| if-no-files-found: error | |
| retention-days: 1 | |
| docker_build_amd64_minimal: | |
| name: docker_build (linux/amd64, minimal) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - name: Docker meta | |
| id: meta | |
| uses: docker/metadata-action@v6 | |
| with: | |
| images: ${{ env.REGISTRY_IMAGE }} | |
| flavor: suffix=-linux-amd64 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v4 | |
| - name: Login to Docker Hub | |
| if: github.event_name != 'pull_request' | |
| uses: docker/login-action@v4 | |
| with: | |
| username: ${{ env.REGISTRY_USERNAME }} | |
| password: ${{ secrets.DOCKERHUB_TOKEN }} | |
| - name: Build image for Hurl examples | |
| uses: docker/build-push-action@v7 | |
| with: | |
| context: . | |
| platforms: linux/amd64 | |
| target: minimal | |
| labels: ${{ steps.meta.outputs.labels }} | |
| tags: | | |
| ${{ steps.meta.outputs.tags }} | |
| ${{ env.REGISTRY_IMAGE }}:main | |
| outputs: type=docker,dest=${{ runner.temp }}/sqlpage.tar | |
| 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: | |
| name: sqlpage-linux-amd64-minimal-image | |
| path: ${{ runner.temp }}/sqlpage.tar | |
| if-no-files-found: error | |
| retention-days: 1 | |
| - name: Build and push by digest | |
| id: build | |
| if: github.event_name != 'pull_request' | |
| uses: docker/build-push-action@v7 | |
| with: | |
| context: . | |
| platforms: linux/amd64 | |
| target: minimal | |
| labels: ${{ steps.meta.outputs.labels }} | |
| push: true | |
| tags: ${{ steps.meta.outputs.tags }} | |
| 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: | | |
| mkdir -p /tmp/digests | |
| digest="${{ steps.build.outputs.digest }}" | |
| touch "/tmp/digests/${digest#sha256:}" | |
| - name: Upload digest | |
| uses: actions/upload-artifact@v7 | |
| if: github.event_name != 'pull_request' | |
| with: | |
| name: digests-minimal-linux-amd64 | |
| path: /tmp/digests/* | |
| if-no-files-found: error | |
| retention-days: 1 | |
| hurl_examples: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| examples: ${{ steps.examples.outputs.examples }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - id: examples | |
| run: | | |
| examples="$(find examples -mindepth 2 -maxdepth 2 -name test.hurl -print | sed 's#/test.hurl$##' | sort | jq -R -s -c 'split("\n")[:-1]')" | |
| echo "examples=$examples" >> "$GITHUB_OUTPUT" | |
| hurl: | |
| name: hurl (${{ matrix.example }}) | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| needs: | |
| - docker_build_amd64_minimal | |
| - hurl_examples | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| example: ${{ fromJSON(needs.hurl_examples.outputs.examples) }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Install Hurl | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| version=8.0.0 | |
| archive="hurl-${version}-x86_64-unknown-linux-gnu.tar.gz" | |
| gh release download "$version" --repo Orange-OpenSource/hurl --pattern "$archive" --dir /tmp | |
| tar xzf "/tmp/$archive" -C /tmp | |
| echo "/tmp/hurl-${version}-x86_64-unknown-linux-gnu/bin" >> "$GITHUB_PATH" | |
| - name: Download SQLPage image | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: sqlpage-linux-amd64-minimal-image | |
| path: ${{ runner.temp }}/sqlpage-image | |
| - name: Load SQLPage image | |
| run: | | |
| docker load --input "${{ runner.temp }}/sqlpage-image/sqlpage.tar" | |
| docker tag "${{ env.REGISTRY_IMAGE }}:main" "${{ env.REGISTRY_IMAGE }}:latest" | |
| - name: Run example Hurl test | |
| run: scripts/test-examples-hurl.sh "${{ matrix.example }}" | |
| docker_push: | |
| runs-on: ubuntu-latest | |
| if: github.event_name != 'pull_request' | |
| needs: | |
| - docker_build_amd64_minimal | |
| - docker_build | |
| strategy: | |
| matrix: | |
| variant: | |
| - minimal | |
| - duckdb | |
| steps: | |
| - name: Download digests | |
| uses: actions/download-artifact@v8 | |
| env: | |
| NODE_OPTIONS: --no-deprecation | |
| with: | |
| pattern: digests-${{ matrix.variant }}* | |
| merge-multiple: true | |
| path: /tmp/digests | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v4 | |
| - name: Docker meta | |
| id: meta | |
| uses: docker/metadata-action@v6 | |
| with: | |
| images: ${{ env.REGISTRY_IMAGE }} | |
| flavor: suffix=${{ matrix.variant != 'minimal' && format('-{0}', matrix.variant) || '' }} | |
| - name: Login to Docker Hub | |
| uses: docker/login-action@v4 | |
| with: | |
| username: ${{ env.REGISTRY_USERNAME }} | |
| password: ${{ secrets.DOCKERHUB_TOKEN }} | |
| - name: Create manifest list and push | |
| working-directory: /tmp/digests | |
| run: | | |
| docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ | |
| $(printf '${{ env.REGISTRY_IMAGE }}@sha256:%s ' *) | |
| - name: Inspect image | |
| run: | | |
| docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ steps.meta.outputs.version }} |