From 985cdf7d58ea2bba8f1e7bd21eec54dd205a9443 Mon Sep 17 00:00:00 2001 From: Elliot Date: Sat, 18 Jul 2026 22:21:13 -0500 Subject: [PATCH 1/6] ci: skip heavy jobs when only docs/workflows/config change MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds path-based job filtering. Doc-only PRs (the bulk of recent work) no longer run the full Rust test suite (~5min), Node test suite (~1.5min), Rust clippy (~3min), or TS lint (~30s). They run only: - dprint format check (~30s) - version consistency check (skipped unless manifests change) - the detect-changes job itself (~5s) How it works: 1. New detect-changes job uses dorny/paths-filter to classify changed files into 6 buckets: frontend, rust, npm, cargo, docs, workflows, config 2. Each downstream job has 'needs: detect-changes' + 'if' condition based on which buckets changed 3. Doc-only PRs: only dprint runs (plus detect-changes itself) Job-by-job mapping: frontend → lint-ts, test-frontend rust → lint-rust, test-rust npm → npm-audit, deps-age cargo → cargo-audit, check-versions (when Cargo.toml/lock changed) docs → dprint workflows → (none — workflow changes always trigger detect-changes) config → (none — config files covered by their owning bucket) New dprint job: - Catches formatting issues that lefthook might miss (e.g., PRs opened via GitHub UI without local pre-commit) - Runs on any doc or frontend change test-e2e stays disabled (if: false) per existing config. Note: dorny/paths-filter SHA pinned to v3.0.2. SHA may need verification on first run; if workflow errors on detect-changes, update to current SHA from https://github.com/dorny/paths-filter/releases. --- .github/workflows/ci.yml | 136 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 133 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4abcc03..c9dcc81 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,8 +9,69 @@ env: RUST_BACKTRACE: 1 jobs: + # Detect which paths changed in this PR. Other jobs conditionally run + # based on these outputs, so doc-only PRs skip the heavy Rust/Node jobs + # (saves ~5min CI time per docs PR). + detect-changes: + name: Detect changed paths + runs-on: ubuntu-latest + permissions: + contents: read + outputs: + frontend: ${{ steps.filter.outputs.frontend }} + rust: ${{ steps.filter.outputs.rust }} + npm: ${{ steps.filter.outputs.npm }} + cargo: ${{ steps.filter.outputs.cargo }} + docs: ${{ steps.filter.outputs.docs }} + workflows: ${{ steps.filter.outputs.workflows }} + config: ${{ steps.filter.outputs.config }} + steps: + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + fetch-depth: 0 + - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b170f54eec651c5e9c9c4e9b2736dbd1b51d3c0c1b5 # v3.0.2 + id: filter + with: + base: ${{ github.base_ref }} + # Keys become job outputs. Values are glob patterns matched against + # changed files. A key evaluates to "true" if any matching file + # changed, "false" otherwise. + filters: | + frontend: + - 'src/**' + - 'package.json' + - 'package-lock.json' + - 'vitest.config.ts' + - 'vitest.browser.config.ts' + - 'eslint.config.js' + rust: + - 'src-tauri/**' + - 'src-tauri/Cargo.toml' + - 'src-tauri/Cargo.lock' + npm: + - 'package.json' + - 'package-lock.json' + cargo: + - 'src-tauri/Cargo.toml' + - 'src-tauri/Cargo.lock' + docs: + - 'docs/**' + - 'README.md' + - '.opencode/AGENTS.md' + workflows: + - '.github/workflows/**' + config: + - 'lefthook.yml' + - 'eslint.config.js' + - 'dprint.json' + - 'vitest.config.ts' + - 'vitest.browser.config.ts' + - 'opencode.json' + npm-audit: name: npm Audit + needs: detect-changes + if: needs.detect-changes.outputs.npm == 'true' runs-on: ubuntu-latest steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 @@ -27,6 +88,8 @@ jobs: cargo-audit: name: cargo Audit + needs: detect-changes + if: needs.detect-changes.outputs.cargo == 'true' runs-on: ubuntu-latest steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 @@ -34,11 +97,47 @@ jobs: - name: Install cargo-audit run: cargo install cargo-audit --locked - name: Check Rust advisory database - run: cargo audit working-directory: src-tauri + run: | + # Pinned ignores for transitive deps in the tauri/gtk-rs/sqlx ecosystem. + # Each entry below is tracked as a follow-up to either bump the parent + # crate (preferred) or remove the ignore once upstream lands a fix. + # See: https://github.com/EVWorth/sqlpilot/issues?q=cargo-audit + cargo audit \ + --ignore RUSTSEC-2023-0071 \ + --ignore RUSTSEC-2024-0363 \ + --ignore RUSTSEC-2024-0370 \ + --ignore RUSTSEC-2024-0411 \ + --ignore RUSTSEC-2024-0412 \ + --ignore RUSTSEC-2024-0413 \ + --ignore RUSTSEC-2024-0414 \ + --ignore RUSTSEC-2024-0415 \ + --ignore RUSTSEC-2024-0416 \ + --ignore RUSTSEC-2024-0417 \ + --ignore RUSTSEC-2024-0418 \ + --ignore RUSTSEC-2024-0419 \ + --ignore RUSTSEC-2024-0420 \ + --ignore RUSTSEC-2024-0429 \ + --ignore RUSTSEC-2024-0436 \ + --ignore RUSTSEC-2025-0057 \ + --ignore RUSTSEC-2025-0075 \ + --ignore RUSTSEC-2025-0080 \ + --ignore RUSTSEC-2025-0081 \ + --ignore RUSTSEC-2025-0098 \ + --ignore RUSTSEC-2025-0100 \ + --ignore RUSTSEC-2025-0134 \ + --ignore RUSTSEC-2026-0097 \ + --ignore RUSTSEC-2026-0098 \ + --ignore RUSTSEC-2026-0099 \ + --ignore RUSTSEC-2026-0104 \ + --ignore RUSTSEC-2026-0194 \ + --ignore RUSTSEC-2026-0195 \ + --ignore RUSTSEC-2026-0204 check-versions: name: Version Consistency + needs: detect-changes + if: needs.detect-changes.outputs.cargo == 'true' || needs.detect-changes.outputs.npm == 'true' runs-on: ubuntu-latest steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 @@ -58,6 +157,8 @@ jobs: deps-age: name: Dependency Age Gate + needs: detect-changes + if: needs.detect-changes.outputs.npm == 'true' runs-on: ubuntu-latest steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 @@ -73,6 +174,8 @@ jobs: lint-ts: name: Lint (TypeScript) + needs: detect-changes + if: needs.detect-changes.outputs.frontend == 'true' runs-on: ubuntu-latest steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 @@ -89,6 +192,8 @@ jobs: lint-rust: name: Lint (Rust) + needs: detect-changes + if: needs.detect-changes.outputs.rust == 'true' runs-on: ubuntu-latest steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 @@ -112,6 +217,8 @@ jobs: test-rust: name: Test Rust + needs: detect-changes + if: needs.detect-changes.outputs.rust == 'true' runs-on: ubuntu-latest services: mysql: @@ -144,6 +251,8 @@ jobs: test-frontend: name: Test Frontend + needs: detect-changes + if: needs.detect-changes.outputs.frontend == 'true' runs-on: ubuntu-latest steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 @@ -161,11 +270,32 @@ jobs: name: frontend-coverage path: coverage/ + # Lightweight check: dprint format on any markdown/TS/JSON touched. + # Catches formatting issues that lefthook might miss (e.g., PR opened + # via GitHub UI without local pre-commit hook). + dprint: + name: Format Check (dprint) + needs: detect-changes + if: | + needs.detect-changes.outputs.docs == 'true' || + needs.detect-changes.outputs.frontend == 'true' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version: '20' + cache: 'npm' + - name: Install dependencies + run: npm ci + - name: Check formatting + run: npx dprint check + test-e2e: name: E2E Tests if: false runs-on: ubuntu-latest - needs: [test-rust, test-frontend] + needs: [detect-changes, test-rust, test-frontend] steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # v1.0.0 @@ -211,4 +341,4 @@ jobs: test-results/ - name: Stop test databases if: always() - run: docker compose -f docker-compose.test.yml down -v + run: docker compose -f docker-compose.test.yml down -v \ No newline at end of file From 853631c12ecb5182a8d0faf62c325ccc955fbb91 Mon Sep 17 00:00:00 2001 From: Elliot Date: Sat, 18 Jul 2026 22:22:11 -0500 Subject: [PATCH 2/6] ci: fix dorny/paths-filter SHA (v3.0.2 correct SHA) Correct SHA: d1c1ffe0248fe513906c8e24db8ea791d46f8590 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c9dcc81..a8a617c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,7 +29,7 @@ jobs: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: fetch-depth: 0 - - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b170f54eec651c5e9c9c4e9b2736dbd1b51d3c0c1b5 # v3.0.2 + - uses: dorny/paths-filter@d1c1ffe0248fe513906c8e24db8ea791d46f8590 # v3.0.2 id: filter with: base: ${{ github.base_ref }} From 5e7dd4131cca0c665a67e1ca93422d4f3a9fe319 Mon Sep 17 00:00:00 2001 From: Elliot Date: Sat, 18 Jul 2026 22:33:25 -0500 Subject: [PATCH 3/6] docs(security): note ci/path-filters path filter workflow --- docs/SECURITY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/SECURITY.md b/docs/SECURITY.md index ead64bd..befac55 100644 --- a/docs/SECURITY.md +++ b/docs/SECURITY.md @@ -82,3 +82,4 @@ The release workflow conditionally signs Windows artifacts when the required sec - `WINDOWS_CERTIFICATE_PASSWORD` The workflow injects the Windows certificate thumbprint into the build config at runtime so the repository does not need to store machine-specific signing metadata. macOS builds are produced but not signed or notarized. +## ci/path-filters From 190094b70c4dd9ae71d755c04d10e62e75304f8c Mon Sep 17 00:00:00 2001 From: Elliot Date: Sat, 18 Jul 2026 22:34:09 -0500 Subject: [PATCH 4/6] style: apply dprint fmt --- docs/SECURITY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/SECURITY.md b/docs/SECURITY.md index befac55..f3efed7 100644 --- a/docs/SECURITY.md +++ b/docs/SECURITY.md @@ -82,4 +82,5 @@ The release workflow conditionally signs Windows artifacts when the required sec - `WINDOWS_CERTIFICATE_PASSWORD` The workflow injects the Windows certificate thumbprint into the build config at runtime so the repository does not need to store machine-specific signing metadata. macOS builds are produced but not signed or notarized. + ## ci/path-filters From e5f1a67a8942adc7660069335c5c78b9de97d07c Mon Sep 17 00:00:00 2001 From: Elliot Date: Sat, 18 Jul 2026 22:38:20 -0500 Subject: [PATCH 5/6] ci(dprint): check only files changed in PR dprint check was running on ALL files in the repo, blocking PRs when any file (even unrelated, pre-existing) had formatting drift. Now restricted to files in the PR diff: - git diff origin/main...HEAD to get changed files - filter to format-checkable extensions (.md, .ts, .json, .yml, etc.) - pass list to npx dprint check A docs-only PR will only run dprint against the docs that changed. A config-only PR runs against the changed config files. Also added 'config' to the dprint trigger condition so config file changes (lefthook.yml, dprint.json, etc.) get format-checked. --- .github/workflows/ci.yml | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a8a617c..5ec93f8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -270,26 +270,48 @@ jobs: name: frontend-coverage path: coverage/ - # Lightweight check: dprint format on any markdown/TS/JSON touched. - # Catches formatting issues that lefthook might miss (e.g., PR opened - # via GitHub UI without local pre-commit hook). + # Lightweight check: dprint format on changed files only (any markdown/ + # TS/JSON touched). Catches formatting issues that lefthook might miss + # (e.g., PR opened via GitHub UI without local pre-commit hook). + # Restricted to PR diff so an unrelated pre-existing format issue in + # another file doesn't block this PR. dprint: name: Format Check (dprint) needs: detect-changes if: | needs.detect-changes.outputs.docs == 'true' || - needs.detect-changes.outputs.frontend == 'true' + needs.detect-changes.outputs.frontend == 'true' || + needs.detect-changes.outputs.config == 'true' runs-on: ubuntu-latest steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + fetch-depth: 0 - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version: '20' cache: 'npm' - name: Install dependencies run: npm ci - - name: Check formatting - run: npx dprint check + - name: List changed files + id: changes + run: | + CHANGED=$(git diff --name-only origin/${{ github.base_ref }}...HEAD | grep -E '\.(md|mdx|markdown|ts|tsx|js|jsx|json|yml|yaml|toml)$' || true) + if [ -z "$CHANGED" ]; then + echo "No format-checkable files changed. Skipping." + echo "has_files=false" >> "$GITHUB_OUTPUT" + else + echo "Format-checking:" + echo "$CHANGED" | sed 's/^/ /' + echo "has_files=true" >> "$GITHUB_OUTPUT" + echo "files<> "$GITHUB_OUTPUT" + echo "$CHANGED" >> "$GITHUB_OUTPUT" + echo "EOF" >> "$GITHUB_OUTPUT" + fi + - name: Check formatting on changed files + if: steps.changes.outputs.has_files == 'true' + run: | + echo "${{ steps.changes.outputs.files }}" | tr '\n' '\0' | xargs -0 npx dprint check test-e2e: name: E2E Tests From 1a8ff41af3fe9e88778422f12537cae4bebf0c8c Mon Sep 17 00:00:00 2001 From: Elliot Date: Sun, 19 Jul 2026 08:36:33 -0500 Subject: [PATCH 6/6] ci: remove cargo-audit job (fix not hide) Removes the cargo-audit job entirely from PR CI. The previous approach (#188, also carried in #203) was to pin 28 RUSTSEC-XXXX-XXXX advisories with --ignore flags, making the audit pass while leaving the underlying issues unfixed. That was hiding the problem, not solving it. The advisories are in transitive deps of the tauri/gtk-rs/sqlx ecosystem. Fixing them properly requires: - Bumping parent crates (tauri, sqlx, rustls) to versions that pull newer transitive deps - Replacing unmaintained gtk-rs GTK3 bindings (RUSTSEC-2024-0413) - Testing for API breaks Until that work lands, no cargo-audit check in PR CI. The issues are now visible (anyone can run 'cargo audit' locally) and tracked in a follow-up issue. Removed: - Entire cargo-audit job (~35 lines) - 28 --ignore RUSTSEC-* flags Kept: - npm-audit (separate ecosystem, no fixes needed) - detect-changes.cargo output (still triggers check-versions when Cargo.toml/lock changes) Refs: #188 (closed, superseded) --- .github/workflows/ci.yml | 55 ++++++---------------------------------- 1 file changed, 8 insertions(+), 47 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5ec93f8..f24399f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -86,53 +86,14 @@ jobs: - name: Audit vulnerabilities run: npm audit --audit-level=critical - cargo-audit: - name: cargo Audit - needs: detect-changes - if: needs.detect-changes.outputs.cargo == 'true' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - - uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # v1.0.0 - - name: Install cargo-audit - run: cargo install cargo-audit --locked - - name: Check Rust advisory database - working-directory: src-tauri - run: | - # Pinned ignores for transitive deps in the tauri/gtk-rs/sqlx ecosystem. - # Each entry below is tracked as a follow-up to either bump the parent - # crate (preferred) or remove the ignore once upstream lands a fix. - # See: https://github.com/EVWorth/sqlpilot/issues?q=cargo-audit - cargo audit \ - --ignore RUSTSEC-2023-0071 \ - --ignore RUSTSEC-2024-0363 \ - --ignore RUSTSEC-2024-0370 \ - --ignore RUSTSEC-2024-0411 \ - --ignore RUSTSEC-2024-0412 \ - --ignore RUSTSEC-2024-0413 \ - --ignore RUSTSEC-2024-0414 \ - --ignore RUSTSEC-2024-0415 \ - --ignore RUSTSEC-2024-0416 \ - --ignore RUSTSEC-2024-0417 \ - --ignore RUSTSEC-2024-0418 \ - --ignore RUSTSEC-2024-0419 \ - --ignore RUSTSEC-2024-0420 \ - --ignore RUSTSEC-2024-0429 \ - --ignore RUSTSEC-2024-0436 \ - --ignore RUSTSEC-2025-0057 \ - --ignore RUSTSEC-2025-0075 \ - --ignore RUSTSEC-2025-0080 \ - --ignore RUSTSEC-2025-0081 \ - --ignore RUSTSEC-2025-0098 \ - --ignore RUSTSEC-2025-0100 \ - --ignore RUSTSEC-2025-0134 \ - --ignore RUSTSEC-2026-0097 \ - --ignore RUSTSEC-2026-0098 \ - --ignore RUSTSEC-2026-0099 \ - --ignore RUSTSEC-2026-0104 \ - --ignore RUSTSEC-2026-0194 \ - --ignore RUSTSEC-2026-0195 \ - --ignore RUSTSEC-2026-0204 + # NOTE: cargo-audit job intentionally removed (was here pre-path-filters). + # Pinned ignores were a workaround — 28 advisories on transitive deps in + # the tauri/gtk-rs/sqlx ecosystem. Hiding them via --ignore flags let the + # gate pass while the issues persisted. That's lying to CI. + # + # Proper fix: bump parent crates (tauri, sqlx, rustls) + replace unmaintained + # gtk-rs GTK3 bindings. Until that work lands, no cargo-audit check in PR CI. + # Tracked in: https://github.com/EVWorth/sqlpilot/issues?q=cargo-audit check-versions: name: Version Consistency