Add Vertica dialect and preserve native SQL semantics #341
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: | |
| branches: [main] | |
| tags: ['v*'] | |
| pull_request: | |
| branches: [main] | |
| permissions: | |
| contents: read | |
| jobs: | |
| quality: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: dtolnay/rust-toolchain@stable | |
| with: | |
| components: rustfmt, clippy | |
| - uses: Swatinem/rust-cache@v2 | |
| - name: Setup Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: '3.12' | |
| - uses: pnpm/setup@v3 | |
| with: | |
| version: 12.4.2 | |
| install: false | |
| - uses: actions/setup-node@v6 | |
| with: | |
| node-version: 24 | |
| cache: pnpm | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Check formatting | |
| run: make fmt-check | |
| - name: Lint Rust wrappers and catalogs | |
| run: make lint-rust | |
| - name: Lint TypeScript SDK | |
| run: make lint-sdk | |
| - name: Check project consistency | |
| run: make check-consistency | |
| # All four suites run for PRs, main pushes, and release tags alike. | |
| rust-test-suite: | |
| name: rust-test (${{ matrix.suite }}) | |
| needs: quality | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| max-parallel: 4 | |
| matrix: | |
| suite: [core, release-fixtures, bindings, feature-gates] | |
| env: | |
| POLYGLOT_API_CONTRACT: ${{ github.workspace }}/docs/api-capabilities.json | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: Swatinem/rust-cache@v2 | |
| with: | |
| key: rust-test-${{ matrix.suite }} | |
| - name: Setup Python | |
| if: matrix.suite == 'core' || matrix.suite == 'release-fixtures' | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: '3.12' | |
| - name: Install uv | |
| if: matrix.suite == 'core' || matrix.suite == 'release-fixtures' | |
| uses: astral-sh/setup-uv@v7 | |
| - name: Extract core fixtures | |
| if: matrix.suite == 'core' | |
| run: make extract-fixtures | |
| - name: Extract release-test fixtures | |
| if: matrix.suite == 'release-fixtures' | |
| run: make extract-all-fixtures | |
| - name: Run Rust suite | |
| run: make test-rust-ci-${{ matrix.suite }} | |
| # Not named ffi-*: this is an internal same-run artifact, not a release archive. | |
| - name: Upload FFI library for Go integration tests | |
| if: matrix.suite == 'bindings' | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: rust-ci-ffi-linux-x86_64 | |
| path: target/ffi_release/libpolyglot_sql_ffi.so | |
| if-no-files-found: error | |
| retention-days: 7 | |
| # Preserve the required check name and all existing downstream needs: rust-test. | |
| rust-test: | |
| if: always() | |
| needs: [quality, rust-test-suite] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Require every Rust suite to pass | |
| env: | |
| QUALITY_RESULT: ${{ needs.quality.result }} | |
| SUITES_RESULT: ${{ needs.rust-test-suite.result }} | |
| run: | | |
| if [[ "$QUALITY_RESULT" != success || "$SUITES_RESULT" != success ]]; then | |
| echo "::error::Rust verification did not pass (quality=$QUALITY_RESULT, suites=$SUITES_RESULT)" | |
| exit 1 | |
| fi | |
| python-fast-check: | |
| runs-on: ubuntu-latest | |
| env: | |
| POLYGLOT_API_CONTRACT: ${{ github.workspace }}/docs/api-capabilities.json | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: dtolnay/rust-toolchain@stable | |
| - name: Setup Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: '3.14' | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v7 | |
| - uses: pnpm/setup@v3 | |
| with: | |
| version: 12.4.2 | |
| install: false | |
| - uses: actions/setup-node@v6 | |
| with: | |
| node-version: 24 | |
| cache: pnpm | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Python bindings tests | |
| run: make test-python | |
| - name: Python bindings typecheck | |
| run: make typecheck-python | |
| - name: Build Python API documentation | |
| run: make python-docs-build | |
| go-sdk: | |
| needs: rust-test | |
| runs-on: ubuntu-latest | |
| env: | |
| POLYGLOT_API_CONTRACT: ${{ github.workspace }}/docs/api-capabilities.json | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: actions/setup-go@v6 | |
| with: | |
| go-version: '1.25.x' | |
| cache-dependency-path: packages/go/go.sum | |
| - name: Go SDK unit tests | |
| run: cd packages/go && go test ./... | |
| - name: Verify Go SDK version matches release tag | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| run: cd packages/go && POLYGLOT_GO_EXPECTED_VERSION="${GITHUB_REF_NAME#v}" go test ./... | |
| - name: Download tested FFI build | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: rust-ci-ffi-linux-x86_64 | |
| path: target/ffi_release/ | |
| - name: Go SDK integration tests | |
| run: cd packages/go && POLYGLOT_SQL_FFI_PATH="../../target/ffi_release/libpolyglot_sql_ffi.so" go test ./... | |
| sdk-build: | |
| needs: rust-test | |
| runs-on: ubuntu-latest | |
| env: | |
| POLYGLOT_API_CONTRACT: ${{ github.workspace }}/docs/api-capabilities.json | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: wasm32-unknown-unknown | |
| - uses: Swatinem/rust-cache@v2 | |
| - name: Install wasm-pack | |
| run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh | |
| - uses: pnpm/setup@v3 | |
| with: | |
| version: 12.4.2 | |
| install: false | |
| - uses: actions/setup-node@v6 | |
| with: | |
| node-version: 24 | |
| cache: pnpm | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Clean WASM crate artifacts | |
| run: cargo clean -p polyglot-sql-wasm | |
| - name: Build WASM | |
| run: cd packages/sdk && pnpm run build:wasm | |
| - name: Generate TypeScript bindings | |
| run: make generate-bindings | |
| - name: Build SDK | |
| run: cd packages/sdk && pnpm run build | |
| - name: Build TypeScript API documentation | |
| run: make documentation-build | |
| - name: Verify SDK/WASM version matches release tag | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| run: | | |
| expected_version="${GITHUB_REF_NAME#v}" | |
| cd packages/sdk | |
| actual_version="$(node -e "import('./dist/index.node.js').then((m) => process.stdout.write(m.getVersion()))")" | |
| if [ "$actual_version" != "$expected_version" ]; then | |
| echo "Version mismatch: tag=$expected_version sdk/wasm=$actual_version" | |
| exit 1 | |
| fi | |
| - name: Test SDK bundler integration | |
| run: cd packages/sdk && pnpm run test:bundlers | |
| - name: Typecheck SDK | |
| run: cd packages/sdk && pnpm typecheck | |
| - name: Test SDK with coverage | |
| run: cd packages/sdk && pnpm run test:coverage | |
| - name: Publish SDK coverage summary | |
| if: ${{ always() && hashFiles('packages/sdk/coverage/coverage-summary.json') != '' }} | |
| run: cd packages/sdk && pnpm run coverage:summary >> "$GITHUB_STEP_SUMMARY" | |
| - name: Upload SDK coverage report | |
| if: always() | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: sdk-coverage | |
| path: packages/sdk/coverage/ | |
| if-no-files-found: warn | |
| retention-days: 14 | |
| - name: Upload WASM artifact | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: wasm | |
| path: packages/sdk/wasm/ | |
| - name: Upload SDK dist artifact | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: dist | |
| path: packages/sdk/dist/ | |
| - name: Upload SDK generated bindings artifact | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: sdk-generated-bindings | |
| path: packages/sdk/src/generated/ | |
| python-wheels-linux: | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| needs: [rust-test, python-fast-check] | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| target: [x86_64, aarch64] | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Build Python wheels (Linux ${{ matrix.target }}) | |
| uses: PyO3/maturin-action@v1 | |
| with: | |
| target: ${{ matrix.target }} | |
| manylinux: '2014' | |
| args: --profile python_release --out dist --find-interpreter --manifest-path crates/polyglot-sql-python/Cargo.toml | |
| sccache: true | |
| - name: Smoke test built wheel (Linux x86_64) | |
| if: matrix.target == 'x86_64' | |
| run: | | |
| python -m pip install --upgrade pip | |
| python -m pip install --no-index --find-links dist "polyglot-sql==${GITHUB_REF_NAME#v}" | |
| python -c "import polyglot_sql; assert polyglot_sql.transpile('SELECT 1', read='postgres', write='postgres') == ['SELECT 1']" | |
| - name: Upload wheel artifacts (Linux ${{ matrix.target }}) | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: python-wheels-linux-${{ matrix.target }} | |
| path: dist | |
| python-wheels-macos: | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| needs: [rust-test, python-fast-check] | |
| runs-on: ${{ matrix.runner }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - target: x86_64-apple-darwin | |
| runner: macos-15-intel | |
| - target: aarch64-apple-darwin | |
| runner: macos-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Build Python wheels (macOS ${{ matrix.target }}) | |
| uses: PyO3/maturin-action@v1 | |
| with: | |
| target: ${{ matrix.target }} | |
| args: --profile python_release --out dist --find-interpreter --manifest-path crates/polyglot-sql-python/Cargo.toml | |
| sccache: true | |
| - name: Smoke test built wheel (macOS) | |
| run: | | |
| python -m pip install --upgrade pip | |
| python -m pip install --no-index --find-links dist "polyglot-sql==${GITHUB_REF_NAME#v}" | |
| python -c "import polyglot_sql; assert polyglot_sql.parse_one('SELECT 1', dialect='postgres')" | |
| - name: Upload wheel artifacts (macOS ${{ matrix.target }}) | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: python-wheels-macos-${{ matrix.target }} | |
| path: dist | |
| python-wheels-windows: | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| needs: [rust-test, python-fast-check] | |
| runs-on: windows-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Build Python wheels (Windows x86_64) | |
| uses: PyO3/maturin-action@v1 | |
| env: | |
| SCCACHE_IGNORE_SERVER_IO_ERROR: "1" | |
| with: | |
| target: x86_64-pc-windows-msvc | |
| args: --profile python_release --out dist --find-interpreter --manifest-path crates/polyglot-sql-python/Cargo.toml | |
| sccache: true | |
| - name: Smoke test built wheel (Windows) | |
| shell: pwsh | |
| run: | | |
| python -m pip install --upgrade pip | |
| python -m pip install --no-index --find-links dist "polyglot-sql==$($env:GITHUB_REF_NAME.Substring(1))" | |
| python -c "import polyglot_sql; assert polyglot_sql.dialects()" | |
| - name: Upload wheel artifacts (Windows x86_64) | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: python-wheels-windows-x86_64 | |
| path: dist | |
| python-sdist: | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| needs: [rust-test, python-fast-check] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Build Python source distribution | |
| uses: PyO3/maturin-action@v1 | |
| with: | |
| command: sdist | |
| args: --out dist --manifest-path crates/polyglot-sql-python/Cargo.toml | |
| - name: Upload sdist artifact | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: python-wheels-sdist | |
| path: dist | |
| publish-pypi: | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| needs: [python-wheels-linux, python-wheels-macos, python-wheels-windows, python-sdist] | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| id-token: write | |
| environment: | |
| name: pypi | |
| url: https://pypi.org/p/polyglot-sql | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Download Python distribution artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| pattern: python-wheels-* | |
| merge-multiple: true | |
| path: dist | |
| - name: Verify version consistency (tag, workspace, artifacts) | |
| run: | | |
| expected_version="${GITHUB_REF_NAME#v}" | |
| workspace_version="$(awk ' | |
| $0 ~ /^\[workspace\.package\]/ { in_ws=1; next } | |
| in_ws && $0 ~ /^version[[:space:]]*=/ { | |
| line=$0; | |
| gsub(/"/, "", line); | |
| sub(/^.*=[[:space:]]*/, "", line); | |
| print line; | |
| exit; | |
| } | |
| ' Cargo.toml)" | |
| if [ "$workspace_version" != "$expected_version" ]; then | |
| echo "Workspace version mismatch: expected=$expected_version actual=$workspace_version" | |
| exit 1 | |
| fi | |
| python - <<'PY' | |
| import glob | |
| import os | |
| import re | |
| import sys | |
| expected = os.environ["GITHUB_REF_NAME"][1:] | |
| files = glob.glob("dist/*") | |
| if not files: | |
| print("No dist artifacts found") | |
| sys.exit(1) | |
| wheel_re = re.compile(r"polyglot_sql-([^-]+)-.+\.whl$") | |
| sdist_re = re.compile(r"polyglot_sql-([0-9A-Za-z.+_]+)\.tar\.gz$") | |
| bad = [] | |
| for path in files: | |
| name = os.path.basename(path) | |
| if name.endswith(".whl"): | |
| m = wheel_re.fullmatch(name) | |
| elif name.endswith(".tar.gz"): | |
| m = sdist_re.fullmatch(name) | |
| else: | |
| continue | |
| if not m or m.group(1) != expected: | |
| bad.append(name) | |
| if bad: | |
| print("Version mismatch in artifacts:", bad) | |
| sys.exit(1) | |
| print(f"Artifacts match expected version {expected}") | |
| PY | |
| - name: Smoke install from built artifacts (Linux) | |
| run: | | |
| expected_version="${GITHUB_REF_NAME#v}" | |
| python -m pip install --upgrade pip | |
| python -m pip install --no-index --find-links dist "polyglot-sql==${expected_version}" | |
| python - <<'PY' | |
| import os | |
| import polyglot_sql | |
| expected = os.environ["GITHUB_REF_NAME"][1:] | |
| assert polyglot_sql.__version__ == expected, (polyglot_sql.__version__, expected) | |
| assert polyglot_sql.transpile("SELECT 1", read="postgres", write="postgres") == ["SELECT 1"] | |
| PY | |
| - name: Publish Python package to PyPI | |
| uses: pypa/gh-action-pypi-publish@release/v1 | |
| publish-crate: | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| needs: sdk-build | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: dtolnay/rust-toolchain@stable | |
| - name: Publish dependency crates to crates.io | |
| run: | | |
| set -euo pipefail | |
| version="${GITHUB_REF_NAME#v}" | |
| crates=( | |
| "polyglot-sql-ast-derive" | |
| "polyglot-sql-function-catalogs" | |
| ) | |
| for crate in "${crates[@]}"; do | |
| if ./scripts/check-crate-version.sh "$crate" "$version"; then | |
| echo "${crate} ${version} already present on crates.io" | |
| else | |
| cargo publish -p "$crate" | |
| fi | |
| done | |
| env: | |
| CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} | |
| - name: Wait for dependency crates index availability | |
| run: | | |
| set -euo pipefail | |
| version="${GITHUB_REF_NAME#v}" | |
| crates=( | |
| "polyglot-sql-ast-derive" | |
| "polyglot-sql-function-catalogs" | |
| ) | |
| for crate in "${crates[@]}"; do | |
| available=false | |
| for attempt in $(seq 1 30); do | |
| if ./scripts/check-crate-version.sh "$crate" "$version"; then | |
| echo "${crate} ${version} is available on crates.io" | |
| available=true | |
| break | |
| fi | |
| echo "Waiting for ${crate} ${version} to appear on crates.io (attempt ${attempt}/30)" | |
| sleep 10 | |
| done | |
| if [[ "$available" != true ]]; then | |
| echo "Timed out waiting for ${crate} ${version} to appear on crates.io" | |
| exit 1 | |
| fi | |
| done | |
| - name: Publish main crate to crates.io | |
| run: | | |
| set -euo pipefail | |
| crate="polyglot-sql" | |
| version="${GITHUB_REF_NAME#v}" | |
| if ./scripts/check-crate-version.sh "$crate" "$version"; then | |
| echo "${crate} ${version} already present on crates.io" | |
| else | |
| cargo publish -p "$crate" | |
| fi | |
| env: | |
| CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} | |
| publish-npm: | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| needs: sdk-build | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: pnpm/setup@v3 | |
| with: | |
| version: 12.4.2 | |
| install: false | |
| - uses: actions/setup-node@v6 | |
| with: | |
| node-version: 24 | |
| cache: pnpm | |
| registry-url: https://registry.npmjs.org | |
| - name: Download WASM artifact | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: wasm | |
| path: packages/sdk/wasm/ | |
| - name: Download SDK dist artifact | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: dist | |
| path: packages/sdk/dist/ | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Publish to npm | |
| run: cd packages/sdk && pnpm publish --access public --no-git-checks --ignore-scripts | |
| env: | |
| NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| ffi-build-artifacts: | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| needs: rust-test | |
| name: Build FFI (${{ matrix.archive_name }}) | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: ubuntu-latest | |
| target: x86_64-unknown-linux-gnu | |
| archive_name: linux-x86_64 | |
| archive_ext: tar.gz | |
| shared_lib: libpolyglot_sql_ffi.so | |
| static_lib: libpolyglot_sql_ffi.a | |
| use_cross: false | |
| target_dir: target | |
| - os: ubuntu-latest | |
| target: aarch64-unknown-linux-gnu | |
| archive_name: linux-aarch64 | |
| archive_ext: tar.gz | |
| shared_lib: libpolyglot_sql_ffi.so | |
| static_lib: libpolyglot_sql_ffi.a | |
| use_cross: true | |
| target_dir: target-cross | |
| - os: macos-15-intel | |
| target: x86_64-apple-darwin | |
| archive_name: macos-x86_64 | |
| archive_ext: tar.gz | |
| shared_lib: libpolyglot_sql_ffi.dylib | |
| static_lib: libpolyglot_sql_ffi.a | |
| use_cross: false | |
| target_dir: target | |
| - os: macos-latest | |
| target: aarch64-apple-darwin | |
| archive_name: macos-aarch64 | |
| archive_ext: tar.gz | |
| shared_lib: libpolyglot_sql_ffi.dylib | |
| static_lib: libpolyglot_sql_ffi.a | |
| use_cross: false | |
| target_dir: target | |
| - os: windows-latest | |
| target: x86_64-pc-windows-msvc | |
| archive_name: windows-x86_64 | |
| archive_ext: zip | |
| shared_lib: polyglot_sql_ffi.dll | |
| static_lib: polyglot_sql_ffi.lib | |
| use_cross: false | |
| target_dir: target | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: ${{ matrix.target }} | |
| - uses: Swatinem/rust-cache@v2 | |
| if: ${{ !matrix.use_cross }} | |
| - name: Install cross (linux aarch64) | |
| if: matrix.use_cross | |
| run: cargo install cross --git https://github.com/cross-rs/cross | |
| - name: Build FFI artifacts with cross | |
| if: matrix.use_cross | |
| env: | |
| CARGO_TARGET_DIR: ${{ matrix.target_dir }} | |
| run: cross build -p polyglot-sql-ffi --profile ffi_release --target ${{ matrix.target }} | |
| - name: Build FFI artifacts with cargo | |
| if: ${{ !matrix.use_cross }} | |
| env: | |
| CARGO_TARGET_DIR: ${{ matrix.target_dir }} | |
| run: cargo build -p polyglot-sql-ffi --profile ffi_release --target ${{ matrix.target }} | |
| - name: Package archive (unix) | |
| if: runner.os != 'Windows' | |
| run: | | |
| dir="polyglot-sql-ffi-${{ matrix.archive_name }}" | |
| mkdir -p "$dir" | |
| cp crates/polyglot-sql-ffi/polyglot_sql.h "$dir/" | |
| cp "${{ matrix.target_dir }}/${{ matrix.target }}/ffi_release/${{ matrix.shared_lib }}" "$dir/" | |
| cp "${{ matrix.target_dir }}/${{ matrix.target }}/ffi_release/${{ matrix.static_lib }}" "$dir/" | |
| cp LICENSE "$dir/" | |
| tar -czf "${dir}.tar.gz" "$dir" | |
| - name: Package archive (windows) | |
| if: runner.os == 'Windows' | |
| shell: pwsh | |
| run: | | |
| $dir = "polyglot-sql-ffi-${{ matrix.archive_name }}" | |
| New-Item -ItemType Directory -Path $dir -Force | Out-Null | |
| Copy-Item "crates/polyglot-sql-ffi/polyglot_sql.h" "$dir/" | |
| Copy-Item "${{ matrix.target_dir }}/${{ matrix.target }}/ffi_release/${{ matrix.shared_lib }}" "$dir/" | |
| Copy-Item "${{ matrix.target_dir }}/${{ matrix.target }}/ffi_release/${{ matrix.static_lib }}" "$dir/" | |
| Copy-Item "LICENSE" "$dir/" | |
| Compress-Archive -Path $dir -DestinationPath "$dir.zip" -Force | |
| - name: Upload archive artifact | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: ffi-${{ matrix.archive_name }} | |
| path: polyglot-sql-ffi-${{ matrix.archive_name }}.${{ matrix.archive_ext }} | |
| publish-ffi-assets: | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| needs: [ffi-build-artifacts, go-sdk-release-artifact] | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Download all FFI archives | |
| uses: actions/download-artifact@v8 | |
| with: | |
| pattern: ffi-* | |
| path: dist | |
| merge-multiple: true | |
| - name: Generate checksums | |
| run: | | |
| cd dist | |
| shopt -s nullglob | |
| files=(*.tar.gz *.zip) | |
| if [ ${#files[@]} -eq 0 ]; then | |
| echo "No FFI archives found" | |
| exit 1 | |
| fi | |
| sha256sum "${files[@]}" > checksums.sha256 | |
| - name: Attach assets to GitHub release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| files: | | |
| dist/*.tar.gz | |
| dist/*.zip | |
| dist/checksums.sha256 | |
| go-sdk-release-artifact: | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| needs: [ffi-build-artifacts] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: actions/setup-go@v6 | |
| with: | |
| go-version: '1.25.x' | |
| cache-dependency-path: packages/go/go.sum | |
| - name: Download Linux x86_64 FFI archive | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: ffi-linux-x86_64 | |
| path: dist | |
| - name: Test Go SDK against release-built FFI artifact | |
| run: | | |
| tar -xzf dist/polyglot-sql-ffi-linux-x86_64.tar.gz -C dist | |
| cd packages/go | |
| POLYGLOT_SQL_FFI_PATH="../../dist/polyglot-sql-ffi-linux-x86_64/libpolyglot_sql_ffi.so" go test ./... | |
| tag-go-module: | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| needs: [go-sdk-release-artifact] | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| fetch-depth: 0 | |
| - name: Create matching Go module tag | |
| run: | | |
| set -euo pipefail | |
| tag="packages/go/${GITHUB_REF_NAME}" | |
| if git ls-remote --exit-code --tags origin "refs/tags/${tag}" >/dev/null 2>&1; then | |
| echo "${tag} already exists" | |
| exit 0 | |
| fi | |
| git tag "${tag}" HEAD | |
| git push origin "refs/tags/${tag}" | |
| deploy-docs: | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| needs: [publish-crate, publish-npm] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: pnpm/setup@v3 | |
| with: | |
| version: 12.4.2 | |
| install: false | |
| - uses: actions/setup-node@v6 | |
| with: | |
| node-version: 24 | |
| cache: pnpm | |
| - name: Download WASM artifact | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: wasm | |
| path: packages/sdk/wasm/ | |
| - name: Download SDK generated bindings artifact | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: sdk-generated-bindings | |
| path: packages/sdk/src/generated/ | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Build documentation | |
| run: cd packages/documentation && pnpm run build | |
| - name: Verify docs version matches release tag | |
| run: | | |
| expected_version="${GITHUB_REF_NAME#v}" | |
| if ! grep -Fq "v${expected_version}" packages/documentation/dist/modules.html; then | |
| echo "Documentation version mismatch: expected v${expected_version}" | |
| exit 1 | |
| fi | |
| - name: Validate Cloudflare credentials | |
| env: | |
| CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | |
| run: | | |
| test -n "$CLOUDFLARE_API_TOKEN" || { echo "Missing CLOUDFLARE_API_TOKEN"; exit 1; } | |
| test -n "$CLOUDFLARE_ACCOUNT_ID" || { echo "Missing CLOUDFLARE_ACCOUNT_ID"; exit 1; } | |
| - name: Deploy to Cloudflare Pages | |
| uses: cloudflare/wrangler-action@v3 | |
| with: | |
| apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | |
| workingDirectory: packages/documentation | |
| command: pages deploy dist --project-name=polyglot-sql-api --branch main | |
| deploy-python-docs: | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| needs: [publish-pypi] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Setup Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: '3.14' | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v7 | |
| - name: Build Python API documentation | |
| run: | | |
| cd crates/polyglot-sql-python | |
| uv run --with mkdocs mkdocs build --strict --clean --config-file mkdocs.yml --site-dir ../../packages/python-docs/dist | |
| - name: Verify generated documentation | |
| run: | | |
| test -f packages/python-docs/dist/index.html || { echo "Missing packages/python-docs/dist/index.html"; exit 1; } | |
| - name: Validate Cloudflare credentials | |
| env: | |
| CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | |
| run: | | |
| test -n "$CLOUDFLARE_API_TOKEN" || { echo "Missing CLOUDFLARE_API_TOKEN"; exit 1; } | |
| test -n "$CLOUDFLARE_ACCOUNT_ID" || { echo "Missing CLOUDFLARE_ACCOUNT_ID"; exit 1; } | |
| - name: Deploy to Cloudflare Pages | |
| uses: cloudflare/wrangler-action@v3 | |
| with: | |
| apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | |
| workingDirectory: packages/python-docs | |
| command: pages deploy dist --project-name=polyglot-sql-python-api --branch main | |
| deploy-playground: | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| needs: [publish-crate, publish-npm] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: pnpm/setup@v3 | |
| with: | |
| version: 12.4.2 | |
| install: false | |
| - uses: actions/setup-node@v6 | |
| with: | |
| node-version: 24 | |
| cache: pnpm | |
| - name: Download WASM artifact | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: wasm | |
| path: packages/sdk/wasm/ | |
| - name: Download SDK dist artifact | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: dist | |
| path: packages/sdk/dist/ | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Build Playground | |
| run: cd packages/playground && pnpm run build | |
| - name: Verify playground SDK/WASM version matches release tag | |
| run: | | |
| expected_version="${GITHUB_REF_NAME#v}" | |
| actual_version="$(node -e "const fs=require('node:fs'); const p=JSON.parse(fs.readFileSync('packages/sdk/wasm/package.json','utf8')); process.stdout.write(p.version);")" | |
| if [ "$actual_version" != "$expected_version" ]; then | |
| echo "Playground SDK/WASM version mismatch: expected=$expected_version actual=$actual_version" | |
| exit 1 | |
| fi | |
| - name: Validate Cloudflare credentials | |
| env: | |
| CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | |
| run: | | |
| test -n "$CLOUDFLARE_API_TOKEN" || { echo "Missing CLOUDFLARE_API_TOKEN"; exit 1; } | |
| test -n "$CLOUDFLARE_ACCOUNT_ID" || { echo "Missing CLOUDFLARE_ACCOUNT_ID"; exit 1; } | |
| - name: Deploy to Cloudflare Pages | |
| uses: cloudflare/wrangler-action@v3 | |
| with: | |
| apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | |
| workingDirectory: packages/playground | |
| command: pages deploy dist --project-name=polyglot-sql-playground --branch main |