CI #126
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: | |
| pull_request: | |
| types: [opened, synchronize, reopened, labeled] | |
| push: | |
| branches: [main] # Runs on main after merge | |
| schedule: | |
| - cron: '0 2 * * *' # Nightly at 2 AM UTC | |
| workflow_dispatch: | |
| inputs: | |
| pg_version: | |
| description: 'PostgreSQL version(s) to test' | |
| required: false | |
| default: '17' | |
| type: choice | |
| options: | |
| - '17' | |
| - '18' | |
| - '17, 18' | |
| env: | |
| CARGO_TERM_COLOR: always | |
| GITHUB_TOKEN: ${{ secrets.GH_PAT }} | |
| concurrency: | |
| group: ci-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| format: | |
| name: Format Check | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Rust nightly | |
| run: | | |
| rustup toolchain install nightly --profile minimal --component rustfmt | |
| rustup default nightly | |
| - name: Check formatting | |
| run: cargo fmt --all -- --check | |
| prepare: | |
| name: Prepare Matrix | |
| runs-on: ubuntu-latest | |
| outputs: | |
| pg_versions: ${{ steps.set-matrix.outputs.pg_versions }} | |
| steps: | |
| - id: set-matrix | |
| run: | | |
| if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then | |
| echo 'pg_versions=[${{ github.event.inputs.pg_version }}]' >> "$GITHUB_OUTPUT" | |
| elif [ "${{ github.event_name }}" = "pull_request" ]; then | |
| if [ "${{ contains(github.event.pull_request.labels.*.name, 'test-pg18') }}" = "true" ]; then | |
| echo 'pg_versions=[17, 18]' >> "$GITHUB_OUTPUT" | |
| else | |
| echo 'pg_versions=[17]' >> "$GITHUB_OUTPUT" | |
| fi | |
| else | |
| echo 'pg_versions=[17, 18]' >> "$GITHUB_OUTPUT" | |
| fi | |
| test: | |
| name: Clippy & Tests (PG${{ matrix.pg_version }}) | |
| runs-on: ubuntu-latest | |
| needs: [format, prepare] | |
| permissions: | |
| contents: read | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| pg_version: ${{ fromJson(needs.prepare.outputs.pg_versions) }} | |
| # PG18 failures are non-blocking while compatibility is being established | |
| continue-on-error: ${{ matrix.pg_version == 18 }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Rust nightly | |
| run: | | |
| rustup toolchain install nightly --profile minimal --component clippy | |
| rustup default nightly | |
| - name: Install system dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y \ | |
| pkg-config \ | |
| libssl-dev \ | |
| libclang-dev \ | |
| clang \ | |
| bison \ | |
| flex \ | |
| libreadline-dev \ | |
| zlib1g-dev \ | |
| libxml2-dev \ | |
| libxslt1-dev \ | |
| libicu-dev | |
| - name: Cache cargo dependencies | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| ~/.cargo/bin/cargo-pgrx | |
| target | |
| key: ${{ runner.os }}-cargo-pg${{ matrix.pg_version }}-${{ hashFiles('**/Cargo.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cargo-pg${{ matrix.pg_version }}- | |
| - name: Cache PostgreSQL build | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.pgrx/config.toml | |
| ~/.pgrx/${{ matrix.pg_version }}.* | |
| key: ${{ runner.os }}-pgrx-pg${{ matrix.pg_version }} | |
| # Always remove stale data directories to prevent flaky tests | |
| # from leftover state. The data dir is cheap to recreate (~1s). | |
| - name: Remove cached data directory | |
| run: rm -rf "$HOME/.pgrx/data-${{ matrix.pg_version }}" | |
| - name: Install cargo-pgrx | |
| run: | | |
| if ! command -v cargo-pgrx &> /dev/null || ! cargo pgrx --version | grep -q "0.16.1"; then | |
| cargo install cargo-pgrx --version 0.16.1 --locked | |
| else | |
| echo "cargo-pgrx 0.16.1 already installed, skipping" | |
| fi | |
| - name: Initialize pgrx | |
| run: | | |
| if [ ! -d "$HOME/.pgrx/${{ matrix.pg_version }}."* ]; then | |
| cargo pgrx init --pg${{ matrix.pg_version }} download | |
| else | |
| echo "PostgreSQL ${{ matrix.pg_version }} already initialized, skipping download" | |
| fi | |
| - name: Configure git credentials for private repos | |
| run: | | |
| git config --global url."https://${{ secrets.GH_PAT }}@github.com/".insteadOf "https://github.com/" | |
| - name: Verify duroxide migrations match upstream | |
| run: | | |
| # Clone duroxide-pg-opt to verify our checked-in copies match upstream. | |
| # NOTE: The branch must match the duroxide-pg-opt ref in Cargo.toml. | |
| # Update this when switching to a tag or a different branch. | |
| git clone --depth=1 --branch pinodeca/initialization \ | |
| https://${{ secrets.GH_PAT }}@github.com/microsoft/duroxide-pg-opt.git | |
| ./scripts/verify-duroxide-migrations.sh | |
| - name: Run clippy | |
| run: cargo clippy --no-default-features --features pg${{ matrix.pg_version }} -- -D warnings | |
| - name: Run unit tests | |
| run: cargo pgrx test pg${{ matrix.pg_version }} | |
| - name: Run E2E tests (shared_preload_libraries enforcement) | |
| id: e2e_no_preload | |
| run: ./scripts/test-e2e-local.sh --clean --no-preload --pg-version ${{ matrix.pg_version }} | |
| - name: Run E2E tests | |
| id: e2e_tests | |
| run: ./scripts/test-e2e-local.sh --clean --pg-version ${{ matrix.pg_version }} | |
| - name: Upload PostgreSQL logs on E2E failure | |
| if: failure() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: postgresql-logs-pg${{ matrix.pg_version }} | |
| path: | | |
| ~/.pgrx/${{ matrix.pg_version }}.log | |
| ~/.pgrx/data-${{ matrix.pg_version }}/log/*.log | |
| if-no-files-found: warn | |
| - name: Run pg_regress tests | |
| id: pg_regress | |
| run: make test-regress PG_VERSION=pg${{ matrix.pg_version }} | |
| - name: Upload pg_regress results on failure | |
| if: steps.pg_regress.outcome == 'failure' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: pg_regress-results-pg${{ matrix.pg_version }} | |
| path: | | |
| regression.out | |
| regression.diffs | |
| if-no-files-found: ignore | |
| - name: Stop PostgreSQL after pg_regress | |
| if: steps.pg_regress.outcome != 'skipped' | |
| run: ./scripts/pg-stop.sh --pg-version ${{ matrix.pg_version }} |