ci: unblock fork CI (rustfmt drift, pin sqlx-cli, skip remote-checks on forks) #4
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: Test | |
| on: | |
| pull_request: | |
| branches: | |
| - main | |
| paths-ignore: | |
| - .github/workflows/** | |
| - '!.github/workflows/test.yml' | |
| push: | |
| branches: | |
| - main | |
| workflow_dispatch: | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} | |
| env: | |
| CARGO_TERM_COLOR: always | |
| NODE_VERSION: 22 | |
| PNPM_VERSION: 10.13.1 | |
| RUST_TOOLCHAIN: nightly-2025-12-04 | |
| RUNNER_LABEL: &runner_label ubuntu-24.04 | |
| jobs: | |
| changes: | |
| runs-on: *runner_label | |
| if: github.event_name == 'pull_request' | |
| permissions: | |
| contents: read | |
| pull-requests: read | |
| outputs: | |
| frontend: ${{ steps.filter.outputs.frontend }} | |
| backend: ${{ steps.filter.outputs.backend }} | |
| backend-remote: ${{ steps.filter.outputs['backend-remote'] }} | |
| tauri: ${{ steps.filter.outputs.tauri }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: dorny/paths-filter@0bc4621a3135347011ad047f9ecf449bf72ce2bd # v3.0.0 | |
| id: filter | |
| with: | |
| filters: | | |
| frontend: | |
| - 'packages/local-web/**' | |
| - 'packages/web-core/**' | |
| - 'packages/remote-web/**' | |
| - 'packages/ui/**' | |
| - 'shared/**' | |
| - 'scripts/check-i18n.sh' | |
| - 'scripts/check-unused-i18n-keys.mjs' | |
| - 'scripts/check-legacy-frontend-paths.sh' | |
| - 'scripts/legacy-frontend-paths-allowlist.txt' | |
| - 'pnpm-lock.yaml' | |
| - 'pnpm-workspace.yaml' | |
| - 'package.json' | |
| - '.npmrc' | |
| - '.github/workflows/test.yml' | |
| - '.github/actions/**' | |
| backend: | |
| - 'crates/api-types/**' | |
| - 'crates/client-info/**' | |
| - 'crates/db/**' | |
| - 'crates/deployment/**' | |
| - 'crates/desktop-bridge/**' | |
| - 'crates/embedded-ssh/**' | |
| - 'crates/executors/**' | |
| - 'crates/git/**' | |
| - 'crates/git-host/**' | |
| - 'crates/local-deployment/**' | |
| - 'crates/mcp/**' | |
| - 'crates/preview-proxy/**' | |
| - 'crates/relay-client/**' | |
| - 'crates/relay-control/**' | |
| - 'crates/relay-hosts/**' | |
| - 'crates/relay-protocol/**' | |
| - 'crates/relay-tunnel-core/**' | |
| - 'crates/relay-types/**' | |
| - 'crates/relay-webrtc/**' | |
| - 'crates/relay-ws/**' | |
| - 'crates/remote-info/**' | |
| - 'crates/review/**' | |
| - 'crates/server/**' | |
| - 'crates/services/**' | |
| - 'crates/trusted-key-auth/**' | |
| - 'crates/utils/**' | |
| - 'crates/workspace-manager/**' | |
| - 'crates/worktree-manager/**' | |
| - 'crates/ws-bridge/**' | |
| - 'Cargo.toml' | |
| - 'Cargo.lock' | |
| - 'shared/**' | |
| - 'scripts/prepare-db.js' | |
| - 'pnpm-lock.yaml' | |
| - 'package.json' | |
| - 'rustfmt.toml' | |
| - 'rust-toolchain.toml' | |
| - '.cargo/**' | |
| - '.github/workflows/test.yml' | |
| - '.github/actions/**' | |
| backend-remote: | |
| - 'crates/remote/**' | |
| - 'crates/relay-tunnel/**' | |
| - 'crates/relay-tunnel-core/**' | |
| - 'crates/ws-bridge/**' | |
| - 'crates/api-types/**' | |
| - 'crates/relay-types/**' | |
| - 'crates/utils/**' | |
| - 'Cargo.toml' | |
| - 'Cargo.lock' | |
| - 'shared/**' | |
| - 'rustfmt.toml' | |
| - 'rust-toolchain.toml' | |
| - '.cargo/**' | |
| - 'pnpm-lock.yaml' | |
| - 'package.json' | |
| - '.github/workflows/test.yml' | |
| - '.github/actions/**' | |
| tauri: | |
| - 'crates/tauri-app/**' | |
| - 'crates/api-types/**' | |
| - 'crates/client-info/**' | |
| - 'crates/db/**' | |
| - 'crates/deployment/**' | |
| - 'crates/desktop-bridge/**' | |
| - 'crates/embedded-ssh/**' | |
| - 'crates/executors/**' | |
| - 'crates/git/**' | |
| - 'crates/git-host/**' | |
| - 'crates/local-deployment/**' | |
| - 'crates/mcp/**' | |
| - 'crates/preview-proxy/**' | |
| - 'crates/relay-client/**' | |
| - 'crates/relay-control/**' | |
| - 'crates/relay-hosts/**' | |
| - 'crates/relay-protocol/**' | |
| - 'crates/relay-tunnel-core/**' | |
| - 'crates/relay-types/**' | |
| - 'crates/relay-webrtc/**' | |
| - 'crates/relay-ws/**' | |
| - 'crates/remote-info/**' | |
| - 'crates/review/**' | |
| - 'crates/server/**' | |
| - 'crates/services/**' | |
| - 'crates/trusted-key-auth/**' | |
| - 'crates/utils/**' | |
| - 'crates/workspace-manager/**' | |
| - 'crates/worktree-manager/**' | |
| - 'crates/ws-bridge/**' | |
| - 'Cargo.toml' | |
| - 'Cargo.lock' | |
| - 'rustfmt.toml' | |
| - 'rust-toolchain.toml' | |
| - '.cargo/**' | |
| - 'package.json' | |
| - 'pnpm-lock.yaml' | |
| - 'pnpm-workspace.yaml' | |
| - '.npmrc' | |
| - '.github/workflows/test.yml' | |
| - '.github/actions/**' | |
| frontend-checks: | |
| needs: changes | |
| if: always() && (needs.changes.outputs.frontend == 'true' || needs.changes.result == 'skipped') | |
| runs-on: *runner_label | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Setup Node | |
| uses: ./.github/actions/setup-node | |
| - name: Install dependencies | |
| run: pnpm install | |
| - name: Run frontend checks | |
| env: | |
| NODE_OPTIONS: --max-old-space-size=8192 | |
| run: | | |
| npx concurrently \ | |
| --kill-others-on-fail \ | |
| --names "local:lint,local:fmt,local:build,remote:fmt,remote:build,ui:check,ui:lint,ui:fmt,core:check,core:fmt,i18n,i18n:unused,legacy" \ | |
| --timings \ | |
| "cd packages/local-web && npm run lint" \ | |
| "cd packages/local-web && npm run format:check" \ | |
| "cd packages/local-web && npm run build" \ | |
| "cd packages/remote-web && npm run format:check" \ | |
| "cd packages/remote-web && npm run build" \ | |
| "cd packages/ui && npm run check" \ | |
| "cd packages/ui && npm run lint" \ | |
| "cd packages/ui && npm run format:check" \ | |
| "cd packages/web-core && npm run check" \ | |
| "cd packages/web-core && npm run format:check" \ | |
| "GITHUB_BASE_REF=${{ github.base_ref || 'main' }} ./scripts/check-i18n.sh" \ | |
| "node scripts/check-unused-i18n-keys.mjs" \ | |
| "./scripts/check-legacy-frontend-paths.sh" | |
| backend-schema-checks: | |
| needs: changes | |
| if: always() && (needs.changes.outputs.backend == 'true' || needs.changes.result == 'skipped') | |
| runs-on: *runner_label | |
| env: | |
| SCCACHE_GHA_ENABLED: "true" | |
| RUSTC_WRAPPER: "sccache" | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Setup Rust | |
| uses: ./.github/actions/cargo-checks-common-setup | |
| with: | |
| toolchain: ${{ env.RUST_TOOLCHAIN }} | |
| cache-key: backend-schema-checks-${{ runner.os }}-${{ runner.arch }}-${{ env.RUNNER_LABEL }} | |
| setup-node: 'true' | |
| setup-sqlx-cli: 'true' | |
| - name: Check generated types | |
| run: npm run generate-types:check | |
| - name: Sqlx checks | |
| run: npm run prepare-db:check | |
| backend-remote-checks: | |
| needs: changes | |
| # Skipped on forks: this job builds crates/remote, which depends on the | |
| # private BloopAI/vibe-kanban-private `billing` crate via VK_PRIVATE_DEPLOY_KEY. | |
| # Forks can't access that, so the job can never pass there. | |
| if: >- | |
| always() | |
| && (needs.changes.outputs['backend-remote'] == 'true' || needs.changes.result == 'skipped') | |
| && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) | |
| && github.event.repository.fork == false | |
| runs-on: *runner_label | |
| env: | |
| SCCACHE_GHA_ENABLED: "true" | |
| RUSTC_WRAPPER: "sccache" | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Setup Rust | |
| uses: ./.github/actions/cargo-checks-common-setup | |
| with: | |
| toolchain: ${{ env.RUST_TOOLCHAIN }} | |
| components: rustfmt, clippy | |
| cache-key: backend-remote-checks-${{ runner.os }}-${{ runner.arch }}-${{ env.RUNNER_LABEL }} | |
| setup-node: 'true' | |
| setup-sqlx-cli: 'true' | |
| - name: Setup SSH Agent for private dependencies | |
| uses: webfactory/ssh-agent@dc588b651fe13675774614f8e6a936a468676387 # v0.9.0 | |
| with: | |
| ssh-private-key: ${{ secrets.VK_PRIVATE_DEPLOY_KEY }} | |
| - name: Check remote Cargo.lock is consistent | |
| run: | | |
| cargo metadata --locked --format-version 1 --manifest-path crates/remote/Cargo.toml > /dev/null | |
| cargo metadata --locked --format-version 1 --manifest-path crates/relay-tunnel/Cargo.toml > /dev/null | |
| - name: Check formatting | |
| run: | | |
| cargo fmt --all --manifest-path crates/remote/Cargo.toml -- --check | |
| cargo fmt --all --manifest-path crates/relay-tunnel/Cargo.toml -- --check | |
| - name: Run Clippy | |
| run: | | |
| cargo clippy --all-targets --manifest-path crates/remote/Cargo.toml -- -D warnings | |
| cargo clippy --all-targets --manifest-path crates/relay-tunnel/Cargo.toml -- -D warnings | |
| - name: Check generated types | |
| run: npm run remote:generate-types:check | |
| - name: Sqlx checks | |
| run: npm run remote:prepare-db:check | |
| backend-clippy: | |
| needs: changes | |
| if: always() && (needs.changes.outputs.backend == 'true' || needs.changes.result == 'skipped') | |
| runs-on: *runner_label | |
| env: | |
| SCCACHE_GHA_ENABLED: "true" | |
| RUSTC_WRAPPER: "sccache" | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Setup Rust | |
| uses: ./.github/actions/cargo-checks-common-setup | |
| with: | |
| toolchain: ${{ env.RUST_TOOLCHAIN }} | |
| components: rustfmt, clippy | |
| cache-key: backend-clippy-${{ runner.os }}-${{ runner.arch }}-${{ env.RUNNER_LABEL }} | |
| - name: Run Clippy and fmt checks | |
| run: | | |
| set -x | |
| cargo fmt --all -- --check & pid_fmt=$! | |
| cargo clippy --workspace --all-targets --exclude vibe-kanban-tauri -- -D warnings | |
| wait $pid_fmt | |
| backend-test: | |
| needs: changes | |
| if: always() && (needs.changes.outputs.backend == 'true' || needs.changes.result == 'skipped') | |
| runs-on: *runner_label | |
| env: | |
| SCCACHE_GHA_ENABLED: "true" | |
| RUSTC_WRAPPER: "sccache" | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Setup Rust | |
| uses: ./.github/actions/cargo-checks-common-setup | |
| with: | |
| toolchain: ${{ env.RUST_TOOLCHAIN }} | |
| cache-key: backend-test-${{ runner.os }}-${{ runner.arch }}-${{ env.RUNNER_LABEL }} | |
| - name: Install cargo-nextest | |
| uses: taiki-e/cache-cargo-install-action@34ce5120836e5f9f1508d8713d7fdea0e8facd6f # v3.0.1 | |
| with: | |
| tool: cargo-nextest | |
| git: https://github.com/nextest-rs/nextest | |
| rev: 6e4a9d6f2c4964f30ff54a8cd5466f8869267daa # cargo-nextest-0.9.132 | |
| - name: Run Cargo tests | |
| run: cargo nextest run --workspace --exclude vibe-kanban-tauri | |
| tauri-checks: | |
| needs: changes | |
| if: always() && (needs.changes.outputs.tauri == 'true' || needs.changes.result == 'skipped') | |
| runs-on: *runner_label | |
| env: | |
| SCCACHE_GHA_ENABLED: "true" | |
| RUSTC_WRAPPER: "sccache" | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Setup Rust | |
| uses: ./.github/actions/cargo-checks-common-setup | |
| with: | |
| toolchain: ${{ env.RUST_TOOLCHAIN }} | |
| components: rustfmt, clippy | |
| cache-key: tauri-checks-${{ runner.os }}-${{ runner.arch }}-${{ env.RUNNER_LABEL }} | |
| - name: Install Linux dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y libwebkit2gtk-4.1-dev build-essential \ | |
| libssl-dev libayatana-appindicator3-dev librsvg2-dev \ | |
| libxdo-dev file pkg-config xdg-utils | |
| - name: Run Tauri fmt, clippy, and compile checks | |
| run: | | |
| cargo fmt --all --manifest-path crates/tauri-app/Cargo.toml -- --check | |
| cargo clippy --all-targets --manifest-path crates/tauri-app/Cargo.toml -- -D warnings | |
| cargo check -p vibe-kanban-tauri |