Initial PanDB release #1
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] | |
| pull_request: | |
| branches: [main] | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| RUSTFLAGS: -C debuginfo=line-tables-only | |
| jobs: | |
| frontend: | |
| needs: changes | |
| if: needs.changes.outputs.frontend == 'true' | |
| runs-on: ubuntu-22.04 | |
| env: | |
| # The workspace intentionally contains platform-specific CLI/MCP packages for every release target. | |
| NPM_CONFIG_LOGLEVEL: error | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@v6 | |
| with: | |
| version: 10.27.0 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: 22.13.0 | |
| cache: pnpm | |
| - name: Install frontend dependencies | |
| run: pnpm --filter dbx... install --frozen-lockfile | |
| - name: Frontend check | |
| run: pnpm check | |
| github-scripts: | |
| needs: changes | |
| if: needs.changes.outputs.github_scripts == 'true' | |
| runs-on: ubuntu-22.04 | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: 22.13.0 | |
| - name: GitHub script tests | |
| run: node --test .github/scripts/*.test.mjs | |
| packages: | |
| needs: changes | |
| if: needs.changes.outputs.packages == 'true' | |
| runs-on: ubuntu-22.04 | |
| env: | |
| # Unsupported-platform package warnings are expected while validating cross-platform package metadata. | |
| NPM_CONFIG_LOGLEVEL: error | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@v6 | |
| with: | |
| version: 10.27.0 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: 22.13.0 | |
| cache: pnpm | |
| - name: Install system dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libssl-dev libsecret-1-dev | |
| - name: Install frontend dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Setup Rust | |
| uses: dtolnay/rust-toolchain@1.97.1 | |
| - name: Node package tests | |
| run: pnpm test:packages | |
| - name: Node package publish dry run | |
| run: pnpm publish:dry-run | |
| windows-win7-bundle: | |
| needs: changes | |
| if: needs.changes.outputs.windows_win7_bundle == 'true' | |
| runs-on: windows-2022 | |
| timeout-minutes: 90 | |
| env: | |
| CARGO_INCREMENTAL: "0" | |
| RUSTFLAGS: -C debuginfo=line-tables-only -C target-feature=+crt-static | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@v6 | |
| with: | |
| version: 10.27.0 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: 22.13.0 | |
| cache: pnpm | |
| - name: Install frontend dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Setup Rust for standard Windows | |
| uses: dtolnay/rust-toolchain@1.97.1 | |
| - name: Check standard Windows dependency path | |
| run: cargo check --locked --package dbx --no-default-features --target x86_64-pc-windows-msvc | |
| - name: Setup Rust for Windows 7 | |
| uses: dtolnay/rust-toolchain@nightly | |
| with: | |
| toolchain: nightly-2026-07-22 | |
| components: rust-src | |
| - name: Prepare Win7-compatible WebView2 loader | |
| shell: pwsh | |
| run: ./.github/scripts/prepare-webview2-win7-loader.ps1 | |
| - name: Prepare WebView2 109 fixed runtime | |
| shell: pwsh | |
| run: ./.github/scripts/prepare-webview2-win7-runtime.ps1 | |
| - name: Probe WebView2 109 fixed runtime | |
| shell: pwsh | |
| run: ./.github/scripts/assert-webview2-win7-runtime.ps1 | |
| - name: Build frontend | |
| run: pnpm build | |
| - name: Build DBX for Windows 7 | |
| shell: pwsh | |
| run: | | |
| $env:TAURI_CONFIG = Get-Content src-tauri/tauri.webview2-win7-fixed.conf.json -Raw | |
| cargo build --locked --package dbx --release --features custom-protocol --target x86_64-win7-windows-msvc -Z build-std=std,panic_abort | |
| - name: Audit Windows 7 PE imports | |
| shell: pwsh | |
| run: ./.github/scripts/assert-win7-pe-compat.ps1 -BinaryPath target/x86_64-win7-windows-msvc/release/dbx.exe | |
| - name: Bundle Windows 7 fixed-runtime installer | |
| shell: pwsh | |
| run: | | |
| $bundleDir = "target/x86_64-win7-windows-msvc/release/bundle/nsis" | |
| pnpm tauri bundle --bundles nsis --target x86_64-win7-windows-msvc --config src-tauri/tauri.webview2-win7-fixed.conf.json | |
| $installer = Get-ChildItem $bundleDir -Filter "*.exe" | | |
| Sort-Object LastWriteTimeUtc -Descending | | |
| Select-Object -First 1 | |
| if (!$installer) { | |
| Write-Error "Missing Windows 7 fixed-runtime installer in ${bundleDir}" | |
| exit 1 | |
| } | |
| Get-FileHash -LiteralPath $installer.FullName -Algorithm SHA256 | |
| - name: Audit Windows 7 installer contents | |
| shell: pwsh | |
| run: | | |
| $installer = Get-ChildItem "target/x86_64-win7-windows-msvc/release/bundle/nsis" -Filter "*.exe" | | |
| Sort-Object LastWriteTimeUtc -Descending | | |
| Select-Object -First 1 | |
| ./.github/scripts/assert-win7-installer-content.ps1 -InstallerPath $installer.FullName | |
| - name: Upload Windows 7 test installer | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: DBX-win7-fixed-runtime-test | |
| path: target/x86_64-win7-windows-msvc/release/bundle/nsis/*.exe | |
| if-no-files-found: error | |
| retention-days: 7 | |
| duckdb-windows-driver: | |
| needs: changes | |
| if: needs.changes.outputs.duckdb_windows == 'true' | |
| runs-on: windows-2022 | |
| timeout-minutes: 60 | |
| env: | |
| CARGO_INCREMENTAL: "0" | |
| CARGO_TARGET_DIR: ${{ github.workspace }}/target/duckdb-driver | |
| RUSTFLAGS: -C debuginfo=line-tables-only -C target-feature=+crt-static | |
| RUSTC_WRAPPER: sccache | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Setup Rust for Windows 7 | |
| uses: dtolnay/rust-toolchain@nightly | |
| with: | |
| toolchain: nightly-2026-07-22 | |
| components: rust-src | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.13" | |
| - uses: mozilla-actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10 | |
| with: | |
| version: "v0.10.0" | |
| - name: Build DuckDB Windows driver | |
| shell: bash | |
| run: | | |
| pushd agents/drivers/duckdb | |
| cargo build \ | |
| --locked \ | |
| --release \ | |
| --bin dbx-duckdb-driver \ | |
| --target x86_64-win7-windows-msvc \ | |
| -Z build-std=std,panic_abort | |
| popd | |
| - name: Validate DuckDB Windows driver | |
| shell: bash | |
| run: | | |
| DRIVER="target/duckdb-driver/x86_64-win7-windows-msvc/release/dbx-duckdb-driver.exe" | |
| python agents/scripts/validate_windows_pe_dependencies.py "$DRIVER" | |
| "$DRIVER" < /dev/null | |
| rust-fmt-clippy: | |
| needs: changes | |
| if: needs.changes.outputs.rust == 'true' | |
| runs-on: ubuntu-22.04 | |
| env: | |
| # sccache cannot reuse Cargo incremental artifacts, so avoid generating them in CI. | |
| CARGO_INCREMENTAL: "0" | |
| RUSTC_WRAPPER: sccache | |
| # The fast lane skips only system font discovery while retaining the other default capabilities. | |
| RUST_FEATURE_MODE: ${{ github.event_name == 'pull_request' && needs.changes.outputs.rust_full != 'true' && 'fast' || 'full' }} | |
| RUST_FAST_FEATURES: dbx/duckdb-sidecar,dbx/mq-admin,dbx/sqlite-sqlcipher,dbx-core/duckdb-sidecar,dbx-core/mq-admin,dbx-core/sqlite-sqlcipher,dbx-web/duckdb-sidecar,dbx-web/mq-admin,dbx-web/sqlite-sqlcipher | |
| RUST_FULL_FEATURES: dbx/duckdb-sidecar,dbx/mq-admin,dbx/sqlite-sqlcipher,dbx/system-fonts,dbx-core/duckdb-sidecar,dbx-core/mq-admin,dbx-core/sqlite-sqlcipher,dbx-core/system-fonts,dbx-web/duckdb-sidecar,dbx-web/mq-admin,dbx-web/sqlite-sqlcipher,dbx-web/system-fonts | |
| # Fork PRs cannot read repository secrets, so retain the GHA backend for them. | |
| SCCACHE_GHA_ENABLED: ${{ secrets.SCCACHE_S3_BUCKET == '' && 'true' || 'false' }} | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Install system dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libssl-dev libsecret-1-dev | |
| - name: Setup Rust | |
| uses: dtolnay/rust-toolchain@1.97.1 | |
| with: | |
| components: clippy, rustfmt | |
| - name: Setup sccache | |
| uses: mozilla-actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10 | |
| with: | |
| version: "v0.10.0" | |
| - name: Configure S3 sccache | |
| if: env.SCCACHE_GHA_ENABLED != 'true' | |
| shell: bash | |
| env: | |
| CACHE_BUCKET: ${{ secrets.SCCACHE_S3_BUCKET }} | |
| CACHE_ENDPOINT: ${{ secrets.SCCACHE_S3_ENDPOINT }} | |
| CACHE_REGION: ${{ secrets.SCCACHE_S3_REGION }} | |
| CACHE_KEY_PREFIX: ${{ secrets.SCCACHE_S3_KEY_PREFIX }} | |
| CACHE_ACCESS_KEY_ID: ${{ secrets.SCCACHE_S3_ACCESS_KEY_ID }} | |
| CACHE_SECRET_ACCESS_KEY: ${{ secrets.SCCACHE_S3_SECRET_ACCESS_KEY }} | |
| run: | | |
| { | |
| echo "SCCACHE_BUCKET=${CACHE_BUCKET}" | |
| echo "SCCACHE_ENDPOINT=${CACHE_ENDPOINT}" | |
| echo "SCCACHE_REGION=${CACHE_REGION}" | |
| echo "SCCACHE_S3_KEY_PREFIX=${CACHE_KEY_PREFIX}" | |
| echo "SCCACHE_S3_USE_SSL=true" | |
| echo "AWS_ACCESS_KEY_ID=${CACHE_ACCESS_KEY_ID}" | |
| echo "AWS_SECRET_ACCESS_KEY=${CACHE_SECRET_ACCESS_KEY}" | |
| } >> "$GITHUB_ENV" | |
| - name: Rust cache | |
| uses: swatinem/rust-cache@v2 | |
| with: | |
| workspaces: "./ -> target" | |
| shared-key: ci-rust-fmt-clippy-x86_64-unknown-linux-gnu | |
| # Preserve completed dependency builds when a later lint step fails. | |
| cache-on-failure: true | |
| # PR caches are large and branch-scoped; restore them from main without saving per-PR copies. | |
| save-if: ${{ github.ref == 'refs/heads/main' }} | |
| - name: Cargo fmt check | |
| run: cargo fmt --check | |
| - name: Cargo clippy | |
| run: | | |
| if [ "$RUST_FEATURE_MODE" = "fast" ]; then | |
| cargo clippy --workspace --locked --all-targets --no-default-features --features "$RUST_FAST_FEATURES" -- -D warnings | |
| else | |
| cargo clippy --workspace --locked --all-targets --no-default-features --features "$RUST_FULL_FEATURES" -- -D warnings | |
| fi | |
| - name: Show sccache stats | |
| if: always() | |
| continue-on-error: true | |
| run: ${SCCACHE_PATH} --show-stats | |
| rust-test: | |
| needs: changes | |
| if: needs.changes.outputs.rust == 'true' | |
| runs-on: ubuntu-22.04 | |
| env: | |
| # sccache cannot reuse Cargo incremental artifacts, so avoid generating them in CI. | |
| CARGO_INCREMENTAL: "0" | |
| RUSTC_WRAPPER: sccache | |
| # The fast lane skips only system font discovery while retaining the other default capabilities. | |
| RUST_FEATURE_MODE: ${{ github.event_name == 'pull_request' && needs.changes.outputs.rust_full != 'true' && 'fast' || 'full' }} | |
| RUST_FAST_FEATURES: dbx/duckdb-sidecar,dbx/mq-admin,dbx/sqlite-sqlcipher,dbx-core/duckdb-sidecar,dbx-core/mq-admin,dbx-core/sqlite-sqlcipher,dbx-web/duckdb-sidecar,dbx-web/mq-admin,dbx-web/sqlite-sqlcipher | |
| RUST_FULL_FEATURES: dbx/duckdb-sidecar,dbx/mq-admin,dbx/sqlite-sqlcipher,dbx/system-fonts,dbx-core/duckdb-sidecar,dbx-core/mq-admin,dbx-core/sqlite-sqlcipher,dbx-core/system-fonts,dbx-web/duckdb-sidecar,dbx-web/mq-admin,dbx-web/sqlite-sqlcipher,dbx-web/system-fonts | |
| # Fork PRs cannot read repository secrets, so retain the GHA backend for them. | |
| SCCACHE_GHA_ENABLED: ${{ secrets.SCCACHE_S3_BUCKET == '' && 'true' || 'false' }} | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Install system dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libssl-dev libsecret-1-dev | |
| - name: Setup Rust | |
| uses: dtolnay/rust-toolchain@1.97.1 | |
| - name: Setup sccache | |
| uses: mozilla-actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10 | |
| with: | |
| version: "v0.10.0" | |
| - name: Configure S3 sccache | |
| if: env.SCCACHE_GHA_ENABLED != 'true' | |
| shell: bash | |
| env: | |
| CACHE_BUCKET: ${{ secrets.SCCACHE_S3_BUCKET }} | |
| CACHE_ENDPOINT: ${{ secrets.SCCACHE_S3_ENDPOINT }} | |
| CACHE_REGION: ${{ secrets.SCCACHE_S3_REGION }} | |
| CACHE_KEY_PREFIX: ${{ secrets.SCCACHE_S3_KEY_PREFIX }} | |
| CACHE_ACCESS_KEY_ID: ${{ secrets.SCCACHE_S3_ACCESS_KEY_ID }} | |
| CACHE_SECRET_ACCESS_KEY: ${{ secrets.SCCACHE_S3_SECRET_ACCESS_KEY }} | |
| run: | | |
| { | |
| echo "SCCACHE_BUCKET=${CACHE_BUCKET}" | |
| echo "SCCACHE_ENDPOINT=${CACHE_ENDPOINT}" | |
| echo "SCCACHE_REGION=${CACHE_REGION}" | |
| echo "SCCACHE_S3_KEY_PREFIX=${CACHE_KEY_PREFIX}" | |
| echo "SCCACHE_S3_USE_SSL=true" | |
| echo "AWS_ACCESS_KEY_ID=${CACHE_ACCESS_KEY_ID}" | |
| echo "AWS_SECRET_ACCESS_KEY=${CACHE_SECRET_ACCESS_KEY}" | |
| } >> "$GITHUB_ENV" | |
| - name: Rust cache | |
| uses: swatinem/rust-cache@v2 | |
| with: | |
| workspaces: "./ -> target" | |
| shared-key: ci-rust-test-v2-x86_64-unknown-linux-gnu | |
| # Test linking dominates this job and sccache cannot cache those crate types. | |
| cache-workspace-crates: true | |
| # Preserve completed dependency builds when a later test step fails. | |
| cache-on-failure: true | |
| # PR caches are large and branch-scoped; restore them from main without saving per-PR copies. | |
| save-if: ${{ github.ref == 'refs/heads/main' }} | |
| - name: Cargo test | |
| run: | | |
| if [ "$RUST_FEATURE_MODE" = "fast" ]; then | |
| cargo test --workspace --locked --no-default-features --features "$RUST_FAST_FEATURES" | |
| else | |
| cargo test --workspace --locked --no-default-features --features "$RUST_FULL_FEATURES" | |
| fi | |
| - name: Show sccache stats | |
| if: always() | |
| continue-on-error: true | |
| run: ${SCCACHE_PATH} --show-stats | |
| rust: | |
| needs: [changes, rust-fmt-clippy, rust-test] | |
| if: always() && needs.changes.outputs.rust == 'true' | |
| runs-on: ubuntu-22.04 | |
| steps: | |
| - name: Check Rust jobs | |
| run: | | |
| if [ "${{ needs.rust-fmt-clippy.result }}" != "success" ]; then | |
| echo "rust-fmt-clippy result: ${{ needs.rust-fmt-clippy.result }}" | |
| exit 1 | |
| fi | |
| if [ "${{ needs.rust-test.result }}" != "success" ]; then | |
| echo "rust-test result: ${{ needs.rust-test.result }}" | |
| exit 1 | |
| fi | |
| jdbc: | |
| needs: changes | |
| if: needs.changes.outputs.jdbc == 'true' | |
| runs-on: ubuntu-22.04 | |
| steps: | |
| - uses: actions/checkout@v5 | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup Java | |
| uses: actions/setup-java@v5 | |
| with: | |
| distribution: temurin | |
| java-version: "21" | |
| cache: gradle | |
| - name: JDBC plugin version guard | |
| env: | |
| BASE_SHA: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event.before }} | |
| run: | | |
| if [ -z "$BASE_SHA" ] || echo "$BASE_SHA" | grep -Eq '^0+$'; then | |
| BASE_SHA="HEAD~1" | |
| fi | |
| node .github/scripts/check-jdbc-plugin-version.mjs "$BASE_SHA" HEAD | |
| - name: JDBC plugin package check | |
| run: ./plugins/jdbc/package.sh | |
| nix-packaging: | |
| needs: changes | |
| if: needs.changes.outputs.nix == 'true' | |
| runs-on: ubuntu-22.04 | |
| continue-on-error: true | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Install Nix | |
| uses: DeterminateSystems/nix-installer-action@ef8a148080ab6020fd15196c2084a2eea5ff2d25 # v22 | |
| - name: Validate Nix dependency closures | |
| run: nix build .#dbx-pnpm-deps .#dbx-cargo-deps --no-link --print-build-logs | |
| changes: | |
| runs-on: ubuntu-22.04 | |
| outputs: | |
| frontend: ${{ steps.filter.outputs.frontend }} | |
| packages: ${{ steps.filter.outputs.packages }} | |
| rust: ${{ steps.filter.outputs.rust }} | |
| rust_full: ${{ steps.rust-mode.outputs.full }} | |
| jdbc: ${{ steps.filter.outputs.jdbc }} | |
| agents: ${{ steps.filter.outputs.agents }} | |
| duckdb_windows: ${{ steps.filter.outputs.duckdb_windows }} | |
| nix: ${{ steps.filter.outputs.nix }} | |
| windows_win7_bundle: ${{ steps.filter.outputs.windows_win7_bundle }} | |
| github_scripts: ${{ steps.filter.outputs.github_scripts }} | |
| steps: | |
| - uses: actions/checkout@v5 | |
| with: | |
| fetch-depth: 0 | |
| - name: Detect changed areas | |
| uses: dorny/paths-filter@v4 | |
| id: filter | |
| with: | |
| filters: | | |
| frontend: | |
| - 'apps/desktop/**' | |
| - 'docs/**' | |
| - 'packages/**' | |
| - 'pnpm-lock.yaml' | |
| - 'package.json' | |
| - '.oxfmtrc.json' | |
| - 'scripts/run-check.mjs' | |
| - '.github/workflows/ci.yml' | |
| packages: | |
| - 'packages/cli/**' | |
| - 'packages/mcp-server/**' | |
| - 'crates/dbx-cli/**' | |
| - 'crates/dbx-mcp/**' | |
| - 'scripts/verify-package-install.mjs' | |
| - 'package.json' | |
| - 'pnpm-lock.yaml' | |
| - 'Cargo.toml' | |
| - 'Cargo.lock' | |
| - '.github/workflows/ci.yml' | |
| rust: | |
| - 'crates/**' | |
| - 'src-tauri/**' | |
| - 'vendor/**' | |
| - 'Cargo.toml' | |
| - 'Cargo.lock' | |
| - 'rust-toolchain*' | |
| - '.github/workflows/ci.yml' | |
| jdbc: | |
| - 'plugins/jdbc/**' | |
| agents: | |
| - 'agents/**' | |
| - 'crates/dbx-core/Cargo.toml' | |
| - 'Cargo.toml' | |
| - 'Cargo.lock' | |
| - '.github/scripts/bump-agent-versions.mjs' | |
| - '.github/scripts/bump-agent-versions.test.mjs' | |
| - '.github/workflows/agents-release.yml' | |
| - '.github/workflows/ci.yml' | |
| duckdb_windows: | |
| - 'agents/drivers/duckdb/**' | |
| - 'agents/scripts/validate_windows_pe_dependencies.py' | |
| - '.github/workflows/agents-release.yml' | |
| - '.github/workflows/ci.yml' | |
| nix: | |
| # These advisory checks validate the pnpm and Cargo dependency closures. | |
| - 'package.json' | |
| - 'packages/**/package.json' | |
| - 'pnpm-lock.yaml' | |
| - 'pnpm-workspace.yaml' | |
| - 'Cargo.toml' | |
| - 'Cargo.lock' | |
| - 'crates/**/Cargo.toml' | |
| - 'src-tauri/Cargo.toml' | |
| - 'flake.nix' | |
| - 'flake.lock' | |
| - '.github/workflows/ci.yml' | |
| - '.github/workflows/update-nix-pnpm-hash.yml' | |
| windows_win7_bundle: | |
| - '.github/scripts/assert-win7-pe-compat.ps1' | |
| - '.github/scripts/assert-win7-installer-content.ps1' | |
| - '.github/scripts/assert-webview2-win7-runtime.ps1' | |
| - '.github/scripts/prepare-webview2-win7-loader.ps1' | |
| - '.github/scripts/prepare-webview2-win7-runtime.ps1' | |
| - '.github/workflows/ci.yml' | |
| - '.github/workflows/release.yml' | |
| - 'src-tauri/tauri.webview2-win7-fixed.conf.json' | |
| - 'src-tauri/build.rs' | |
| - 'src-tauri/Cargo.toml' | |
| - 'src-tauri/windows/nsis/**' | |
| - 'src-tauri/src/commands/update.rs' | |
| - 'crates/dbx-core/Cargo.toml' | |
| - 'crates/dbx-core/src/db/postgres.rs' | |
| - 'crates/dbx-core/src/update.rs' | |
| - 'Cargo.toml' | |
| - 'Cargo.lock' | |
| - 'vendor/ctor/**' | |
| - 'vendor/dirs-sys/**' | |
| - 'vendor/pageant/**' | |
| - 'vendor/wry/**' | |
| github_scripts: | |
| - '.github/scripts/**' | |
| - '.github/workflows/ci.yml' | |
| - 'apps/desktop/src/types/database.ts' | |
| - 'crates/dbx-core/assets/database-drivers.manifest.json' | |
| - name: Select Rust feature coverage | |
| id: rust-mode | |
| shell: bash | |
| env: | |
| BASE_SHA: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event.before }} | |
| RUST_CHANGED: ${{ steps.filter.outputs.rust }} | |
| run: | | |
| full=false | |
| if [ "$RUST_CHANGED" = "true" ] && [ "${{ github.event_name }}" = "push" ]; then | |
| full=true | |
| elif [ "$RUST_CHANGED" = "true" ]; then | |
| if [ -z "$BASE_SHA" ] || echo "$BASE_SHA" | grep -Eq '^0+$'; then | |
| BASE_SHA="HEAD~1" | |
| fi | |
| while IFS= read -r file; do | |
| case "$file" in | |
| Cargo.toml|Cargo.lock|rust-toolchain*|.github/workflows/ci.yml|*/Cargo.toml|vendor/*) | |
| full=true | |
| break | |
| ;; | |
| esac | |
| done < <(git diff --name-only "$BASE_SHA" HEAD -- Cargo.toml Cargo.lock 'rust-toolchain*' crates src-tauri vendor .github/workflows/ci.yml) | |
| fi | |
| echo "full=$full" >> "$GITHUB_OUTPUT" | |
| agents: | |
| needs: changes | |
| if: needs.changes.outputs.agents == 'true' | |
| runs-on: ubuntu-22.04 | |
| defaults: | |
| run: | |
| working-directory: agents | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Setup Java | |
| uses: actions/setup-java@v5 | |
| with: | |
| distribution: temurin | |
| java-version: | | |
| 8 | |
| 21 | |
| - name: Setup Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: "1.24.x" | |
| - name: Setup Rust | |
| uses: dtolnay/rust-toolchain@1.97.1 | |
| - name: Setup Gradle | |
| uses: gradle/actions/setup-gradle@v4 | |
| - name: Install packaging tools | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y zstd | |
| - name: Agent script tests | |
| run: | | |
| python3 -m unittest discover -s scripts -p '*_test.py' | |
| node --test ../.github/scripts/bump-agent-versions.test.mjs | |
| - name: DuckDB driver tests | |
| run: cargo test --manifest-path drivers/duckdb/Cargo.toml --locked | |
| - name: TDengine driver tests | |
| run: cargo test --manifest-path drivers/tdengine/Cargo.toml --locked | |
| - name: Agent validation | |
| run: python3 scripts/validate_agents.py | |
| - name: Oracle native agent tests | |
| run: go test ./... | |
| working-directory: agents/drivers/oracle-go | |
| - name: Xugu native agent tests | |
| run: GONOSUMDB=gitee.com/XuguDB/go-xugu-driver go test ./... | |
| working-directory: agents/drivers/xugu | |
| - name: RabbitMQ native agent tests | |
| run: go test ./... | |
| working-directory: agents/drivers/rabbitmq | |
| - name: Cassandra native agent tests | |
| run: go test ./... | |
| working-directory: agents/drivers/cassandra-go | |
| - name: Vastbase native agent tests | |
| run: go test ./... | |
| working-directory: agents/drivers/vastbase-go | |
| - name: Neo4j native agent tests | |
| run: go test ./... | |
| working-directory: agents/drivers/neo4j-go | |
| - name: Oracle native agent build | |
| run: CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -trimpath -ldflags="-s -w" -o /tmp/dbx-agent-oracle-linux-x64 . | |
| working-directory: agents/drivers/oracle-go | |
| - name: Xugu native agent build | |
| run: GONOSUMDB=gitee.com/XuguDB/go-xugu-driver CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -trimpath -ldflags="-s -w" -o /tmp/dbx-agent-xugu-linux-x64 . | |
| working-directory: agents/drivers/xugu | |
| - name: RabbitMQ native agent build | |
| run: CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -trimpath -ldflags="-s -w" -o /tmp/dbx-agent-rabbitmq-linux-x64 . | |
| working-directory: agents/drivers/rabbitmq | |
| - name: Cassandra native agent build | |
| run: CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -trimpath -ldflags="-s -w" -o /tmp/dbx-agent-cassandra-linux-x64 . | |
| working-directory: agents/drivers/cassandra-go | |
| - name: Vastbase native agent build | |
| run: CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -trimpath -ldflags="-s -w" -o /tmp/dbx-agent-vastbase-linux-x64 . | |
| working-directory: agents/drivers/vastbase-go | |
| - name: Neo4j native agent build | |
| run: CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -trimpath -ldflags="-s -w" -o /tmp/dbx-agent-neo4j-linux-x64 . | |
| working-directory: agents/drivers/neo4j-go | |
| - name: TDengine native agent build | |
| run: cargo build --manifest-path drivers/tdengine/Cargo.toml --locked --release --bin dbx-tdengine-driver | |
| - name: TDengine native agent integration tests | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| while IFS='|' read -r version image; do | |
| name="dbx-tdengine-${version//./-}" | |
| docker rm -fv "$name" >/dev/null 2>&1 || true | |
| docker run -d --name "$name" \ | |
| --memory 4g \ | |
| --ulimit nofile=65535:65535 \ | |
| -p 6030:6030 \ | |
| -p 6041:6041 \ | |
| "$image" | |
| cleanup() { | |
| docker rm -fv "$name" >/dev/null 2>&1 || true | |
| } | |
| trap cleanup EXIT | |
| ready=false | |
| dnodes="" | |
| for _ in $(seq 1 90); do | |
| dnodes="$(docker exec "$name" taos -s 'SHOW DNODES' 2>/dev/null || true)" | |
| if grep -Eq '\|[[:space:]]*ready[[:space:]]*\|' <<<"$dnodes"; then | |
| ready=true | |
| break | |
| fi | |
| sleep 2 | |
| done | |
| if [ "$ready" != "true" ]; then | |
| printf '%s\n' "$dnodes" | |
| docker logs "$name" | |
| exit 1 | |
| fi | |
| TDENGINE_INTEGRATION=1 \ | |
| TDENGINE_TEST_HOST=127.0.0.1 \ | |
| TDENGINE_TEST_PORT=6041 \ | |
| cargo test --manifest-path drivers/tdengine/Cargo.toml --locked --test live -- --nocapture | |
| cleanup | |
| trap - EXIT | |
| done <<'EOF' | |
| 2.4.0.14|tdengine/tdengine:2.4.0.14 | |
| 2.6.0.34|tdengine/tdengine:2.6.0.34 | |
| 3.0.7.1|tdengine/tdengine:3.0.7.1 | |
| 3.3.6.13|tdengine/tdengine:3.3.6.13 | |
| 3.4.2.2|tdengine/tsdb:3.4.2.2 | |
| EOF | |
| - name: Cassandra native agent integration tests | |
| shell: bash | |
| working-directory: agents/drivers/cassandra-go | |
| run: | | |
| set -euo pipefail | |
| for version in 3.11.19 5.0.6; do | |
| name="dbx-cassandra-${version//./-}" | |
| docker rm -fv "$name" >/dev/null 2>&1 || true | |
| docker run -d --name "$name" \ | |
| -e CASSANDRA_CLUSTER_NAME="DBX Cassandra CI $version" \ | |
| -e CASSANDRA_DC=dc1 \ | |
| -e CASSANDRA_RACK=rack1 \ | |
| -e CASSANDRA_ENDPOINT_SNITCH=GossipingPropertyFileSnitch \ | |
| -e CASSANDRA_NUM_TOKENS=16 \ | |
| -e MAX_HEAP_SIZE=512M \ | |
| -e HEAP_NEWSIZE=100M \ | |
| -p 9042:9042 \ | |
| "cassandra:$version" | |
| cleanup() { | |
| docker rm -fv "$name" >/dev/null 2>&1 || true | |
| } | |
| trap cleanup EXIT | |
| ready=false | |
| for _ in $(seq 1 100); do | |
| if docker exec "$name" cqlsh -e 'SELECT release_version FROM system.local' >/dev/null 2>&1; then | |
| ready=true | |
| break | |
| fi | |
| sleep 3 | |
| done | |
| if [ "$ready" != "true" ]; then | |
| docker logs "$name" | |
| exit 1 | |
| fi | |
| CASSANDRA_TEST_HOST=127.0.0.1 \ | |
| CASSANDRA_TEST_PORT=9042 \ | |
| go test -run '^TestCassandraIntegration$' -count=1 ./... | |
| cleanup | |
| trap - EXIT | |
| done | |
| - name: RabbitMQ native agent integration tests | |
| shell: bash | |
| working-directory: agents/drivers/rabbitmq | |
| run: | | |
| set -euo pipefail | |
| for version in 3.13 4.3; do | |
| name="dbx-rabbitmq-${version//./-}" | |
| cookie="dbx-ci-${GITHUB_RUN_ID:-local}-${version//./-}" | |
| # RabbitMQ is disposable in CI. Keep its data on a fresh tmpfs | |
| # owned by the image's rabbitmq user so .erlang.cookie is readable. | |
| docker rm -fv "$name" >/dev/null 2>&1 || true | |
| docker run -d --name "$name" \ | |
| --user 999:999 \ | |
| --tmpfs /var/lib/rabbitmq:rw,exec,uid=999,gid=999,mode=700 \ | |
| -e RABBITMQ_DEFAULT_USER=dbx \ | |
| -e RABBITMQ_DEFAULT_PASS=dbx-password \ | |
| -e RABBITMQ_ERLANG_COOKIE="$cookie" \ | |
| -p 5672:5672 -p 15672:15672 \ | |
| "rabbitmq:${version}-management" | |
| cleanup() { | |
| docker rm -fv "$name" >/dev/null 2>&1 || true | |
| } | |
| trap cleanup EXIT | |
| ready=false | |
| for _ in $(seq 1 60); do | |
| if docker exec "$name" rabbitmq-diagnostics -q check_running >/dev/null 2>&1 \ | |
| && curl --fail --silent --noproxy '*' --user dbx:dbx-password \ | |
| http://127.0.0.1:15672/api/overview >/dev/null; then | |
| ready=true | |
| break | |
| fi | |
| sleep 2 | |
| done | |
| if [ "$ready" != "true" ]; then | |
| docker inspect "$name" --format 'image={{.Config.Image}} user={{.Config.User}} status={{.State.Status}} exit={{.State.ExitCode}}' || true | |
| docker logs "$name" | |
| exit 1 | |
| fi | |
| RABBITMQ_INTEGRATION=1 \ | |
| RABBITMQ_USERNAME=dbx \ | |
| RABBITMQ_PASSWORD=dbx-password \ | |
| go test -run '^TestRabbitMQIntegration$' -count=1 ./... | |
| cleanup | |
| trap - EXIT | |
| done | |
| - name: Java agent tests and packages | |
| run: ./gradlew test shadowJar --continue | |
| - name: Agent jar validation | |
| run: python3 scripts/validate_agent_jars.py |