# Full CLI integration against PostgreSQL 12-19; builds the extension from source.
name: CLI Integration

on:
  push:
    paths:
      - "cli/**"
      - ".github/workflows/cli-integration.yml"
      - "pg_integrity_checksums.c"
      - "pg_integrity_checksums.h"
      - "Makefile"
      - "sql/**"
      - "pg_integrity_checksums--*.sql"
  pull_request:
    paths:
      - "cli/**"
      - ".github/workflows/cli-integration.yml"
      - "pg_integrity_checksums.c"
      - "pg_integrity_checksums.h"
      - "Makefile"
      - "sql/**"
      - "pg_integrity_checksums--*.sql"
  workflow_dispatch:

permissions:
  contents: read

concurrency:
  group: cli-integration-${{ github.ref }}
  cancel-in-progress: true

jobs:
  integration:
    name: PostgreSQL ${{ matrix.pg }}
    runs-on: ubuntu-latest
    timeout-minutes: 40
    strategy:
      fail-fast: false
      matrix:
        pg: [12, 13, 14, 15, 16, 17, 18, 19]
    env:
      PG: ${{ matrix.pg }}
    steps:
      - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

      - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
        with:
          go-version-file: cli/go.mod
          cache-dependency-path: cli/go.sum

      - name: Install build dependencies
        run: |
          sudo apt-get update
          sudo apt-get install -y build-essential bison flex curl ca-certificates

      - name: Restore PostgreSQL build cache
        id: pg-cache
        uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
        with:
          path: pg${{ matrix.pg }}
          key: cli-pg-${{ matrix.pg }}-v1

      - name: Fetch PostgreSQL source
        run: |
          curl -L -o pg.tar.gz "https://github.com/postgres/postgres/archive/refs/heads/REL_${PG}_STABLE.tar.gz"
          tar -xzf pg.tar.gz

      - name: Build PostgreSQL ${{ matrix.pg }} if not cached
        if: steps.pg-cache.outputs.cache-hit != 'true'
        run: |
          PG_SRC="$PWD/postgres-REL_$PG"_STABLE
          PREFIX="$PWD/pg$PG"
          cd "$PG_SRC"
          ./configure \
            --prefix="$PREFIX" \
            --disable-nls \
            --without-icu \
            --without-readline \
            --without-zlib \
            --without-llvm
          make -j"$(nproc)"
          make install

      - name: Configure PostgreSQL environment
        run: |
          PREFIX="$PWD/pg$PG"
          echo "PG_CONFIG=$PREFIX/bin/pg_config" >> "$GITHUB_ENV"
          echo "PATH=$PREFIX/bin:$PATH" >> "$GITHUB_ENV"
      - name: Build and install extension
        run: |
          make PG_CONFIG="$PG_CONFIG" with_llvm=no
          make PG_CONFIG="$PG_CONFIG" with_llvm=no install

      - name: Start PostgreSQL
        run: |
          PGBIN="$(dirname "$PG_CONFIG")"
          PGDATA="$RUNNER_TEMP/pgdata"
          rm -rf "$PGDATA"
          "$PGBIN/initdb" -D "$PGDATA" -U postgres -A trust --no-sync
          "$PGBIN/pg_ctl" -D "$PGDATA" -l "$PGDATA/server.log" -o "-p 5433" -w start
          "$PGBIN/createdb" -h 127.0.0.1 -p 5433 -U postgres cli_test
          "$PGBIN/psql" -h 127.0.0.1 -p 5433 -U postgres -d cli_test -c "CREATE EXTENSION pg_integrity_checksums"
          echo "PGDATA=$PGDATA" >> "$GITHUB_ENV"

      - name: Run CLI integration tests
        env:
          PGHOST: 127.0.0.1
          PGPORT: 5433
          PGUSER: postgres
          PGDATABASE: cli_test
          PGICS_TEST_DSN: host=127.0.0.1 port=5433 user=postgres dbname=cli_test sslmode=disable
        run: |
          cd cli
          if [ "${{ matrix.pg }}" = "16" ]; then
            go test -count=1 -coverpkg=./... -coverprofile=coverage-integration.out ./internal/cli -run TestIntegration -v
          else
            go test -count=1 ./internal/cli -run TestIntegration -v
          fi

      - name: Upload integration coverage
        if: matrix.pg == 16
        uses: codecov/codecov-action@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7.1.1
        with:
          files: cli/coverage-integration.out
          flags: integration
          fail_ci_if_error: false

      - name: Prepare composite action smoke test
        if: matrix.pg == 16
        run: |
          PGBIN="$(dirname "$PG_CONFIG")"
          "$PGBIN/psql" -h 127.0.0.1 -p 5433 -U postgres -d cli_test             -v ON_ERROR_STOP=1 -c "CREATE TABLE IF NOT EXISTS action_smoke (id int primary key)"
          cd cli
          go build -trimpath -o /tmp/pgics-action ./cmd/pg_integrity_checksums
          /tmp/pgics-action capture --dsn "host=127.0.0.1 port=5433 user=postgres dbname=cli_test sslmode=disable"             --schema public --output /tmp/action-baseline.json --quiet

      - name: Run composite action
        if: matrix.pg == 16
        uses: ./cli
        with:
          baseline: /tmp/action-baseline.json
          dsn: host=127.0.0.1 port=5433 user=postgres dbname=cli_test sslmode=disable
          format: json
          fail_on: any

      - name: Show server log on failure
        if: failure()
        run: |
          if [ -n "$PGDATA" ]; then cat "$PGDATA/server.log" || true; fi

      - name: Stop PostgreSQL
        if: always()
        run: |
          if [ -n "$PG_CONFIG" ] && [ -n "$PGDATA" ]; then
            PGBIN="$(dirname "$PG_CONFIG")"
            "$PGBIN/pg_ctl" -D "$PGDATA" -m immediate stop || true
          fi
