fix(desktop): dedupe Windows MCP project paths #385
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: PR Quality | |
| on: | |
| pull_request: | |
| types: [opened, synchronize, reopened, ready_for_review, labeled, unlabeled] | |
| permissions: | |
| contents: read | |
| pull-requests: read | |
| concurrency: | |
| group: pr-quality-${{ github.event.pull_request.number }} | |
| cancel-in-progress: true | |
| jobs: | |
| scope-plan: | |
| name: scope-plan | |
| runs-on: ubuntu-latest | |
| outputs: | |
| areas: ${{ steps.policy.outputs.areas }} | |
| area_labels: ${{ steps.policy.outputs.area_labels }} | |
| blocked: ${{ steps.policy.outputs.blocked }} | |
| blocking_reasons: ${{ steps.policy.outputs.blocking_reasons }} | |
| desktop_checks: ${{ steps.policy.outputs.desktop_checks }} | |
| server_checks: ${{ steps.policy.outputs.server_checks }} | |
| adapter_checks: ${{ steps.policy.outputs.adapter_checks }} | |
| desktop_native_checks: ${{ steps.policy.outputs.desktop_native_checks }} | |
| provider_contract_checks: ${{ steps.policy.outputs.provider_contract_checks }} | |
| chat_contract_checks: ${{ steps.policy.outputs.chat_contract_checks }} | |
| persistence_checks: ${{ steps.policy.outputs.persistence_checks }} | |
| policy_checks: ${{ steps.policy.outputs.policy_checks }} | |
| docs_checks: ${{ steps.policy.outputs.docs_checks }} | |
| coverage_checks: ${{ steps.policy.outputs.coverage_checks }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| - name: Setup Bun | |
| uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version-file: package.json | |
| - name: Collect changed files | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| PR_NUMBER: ${{ github.event.pull_request.number }} | |
| REPOSITORY: ${{ github.repository }} | |
| run: | | |
| gh api "repos/${REPOSITORY}/pulls/${PR_NUMBER}/files" --paginate --jq '.[].filename' > changed-files.txt | |
| jq -r '.pull_request.labels[].name' "$GITHUB_EVENT_PATH" > labels.txt | |
| - name: Build deterministic scope plan | |
| id: policy | |
| run: bun run scripts/pr/change-policy.ts --files changed-files.txt --labels-file labels.txt --plan-only | |
| policy-enforcement: | |
| name: policy-enforcement | |
| needs: scope-plan | |
| if: ${{ always() && needs.scope-plan.result == 'success' }} | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout policy sources | |
| if: needs.scope-plan.outputs.policy_checks == 'true' | |
| uses: actions/checkout@v4 | |
| with: | |
| persist-credentials: false | |
| - name: Setup Bun | |
| if: needs.scope-plan.outputs.policy_checks == 'true' | |
| uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version-file: package.json | |
| - name: Install root dependencies | |
| if: needs.scope-plan.outputs.policy_checks == 'true' | |
| run: bun install --frozen-lockfile | |
| - name: Run policy regression tests | |
| if: needs.scope-plan.outputs.policy_checks == 'true' | |
| run: bun run check:policy | |
| - name: Enforce change policy | |
| env: | |
| BLOCKED: ${{ needs.scope-plan.outputs.blocked }} | |
| BLOCKING_REASONS: ${{ needs.scope-plan.outputs.blocking_reasons }} | |
| run: | | |
| if [ "$BLOCKED" = "true" ]; then | |
| echo "::error::${BLOCKING_REASONS:-Change policy blocked this pull request}" | |
| exit 1 | |
| fi | |
| echo "Change policy passed" | |
| desktop-checks: | |
| name: desktop-checks | |
| needs: scope-plan | |
| if: needs.scope-plan.outputs.desktop_checks == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| persist-credentials: false | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version-file: package.json | |
| - name: Install root dependencies | |
| run: bun install --frozen-lockfile | |
| - name: Install desktop dependencies | |
| working-directory: desktop | |
| run: bun install --frozen-lockfile | |
| - name: Run desktop checks | |
| run: bun run check:desktop | |
| server-checks: | |
| name: server-checks | |
| needs: scope-plan | |
| if: needs.scope-plan.outputs.server_checks == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| persist-credentials: false | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version-file: package.json | |
| - name: Install root dependencies | |
| run: bun install --frozen-lockfile | |
| - name: Run root runtime checks | |
| run: bun run check:server | |
| provider-contract-checks: | |
| name: provider-contract-checks | |
| needs: scope-plan | |
| if: needs.scope-plan.outputs.provider_contract_checks == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| persist-credentials: false | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version-file: package.json | |
| - name: Install root dependencies | |
| run: bun install --frozen-lockfile | |
| - name: Run offline provider contracts | |
| run: bun run check:provider-contract | |
| chat-contract-checks: | |
| name: chat-contract-checks | |
| needs: scope-plan | |
| if: needs.scope-plan.outputs.chat_contract_checks == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| persist-credentials: false | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version-file: package.json | |
| - name: Install root dependencies | |
| run: bun install --frozen-lockfile | |
| - name: Install desktop dependencies | |
| working-directory: desktop | |
| run: bun install --frozen-lockfile | |
| - name: Run desktop-server chat contracts | |
| run: bun run check:chat-contract | |
| adapter-checks: | |
| name: adapter-checks | |
| needs: scope-plan | |
| if: needs.scope-plan.outputs.adapter_checks == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| persist-credentials: false | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version-file: package.json | |
| - name: Install adapter dependencies | |
| working-directory: adapters | |
| run: bun install --frozen-lockfile | |
| - name: Run adapter checks | |
| run: bun run check:adapters | |
| desktop-native-checks: | |
| name: desktop-native-checks | |
| needs: scope-plan | |
| if: needs.scope-plan.outputs.desktop_native_checks == 'true' | |
| runs-on: ubuntu-22.04 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| persist-credentials: false | |
| - name: Install Linux dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y \ | |
| build-essential curl wget file \ | |
| libxdo-dev libssl-dev patchelf \ | |
| libfuse2 | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version-file: package.json | |
| - name: Install root dependencies | |
| run: bun install --frozen-lockfile | |
| - name: Install desktop dependencies | |
| working-directory: desktop | |
| run: bun install --frozen-lockfile | |
| - name: Run desktop native checks | |
| run: bun run check:native | |
| persistence-checks: | |
| name: persistence-checks | |
| needs: scope-plan | |
| if: needs.scope-plan.outputs.persistence_checks == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| persist-credentials: false | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version-file: package.json | |
| - name: Install root dependencies | |
| run: bun install --frozen-lockfile | |
| - name: Install desktop dependencies | |
| working-directory: desktop | |
| run: bun install --frozen-lockfile | |
| - name: Run persistence upgrade contracts | |
| run: bun run check:persistence-upgrade | |
| docs-checks: | |
| name: docs-checks | |
| needs: scope-plan | |
| if: needs.scope-plan.outputs.docs_checks == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| persist-credentials: false | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 22 | |
| cache: npm | |
| cache-dependency-path: site/package-lock.json | |
| - name: Run docs checks | |
| run: npm --prefix site ci && npm --prefix site run build && npm --prefix site run check | |
| coverage-checks: | |
| name: coverage-checks | |
| needs: scope-plan | |
| if: needs.scope-plan.outputs.coverage_checks == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version-file: package.json | |
| - name: Install root dependencies | |
| run: bun install --frozen-lockfile | |
| - name: Install desktop dependencies | |
| working-directory: desktop | |
| run: bun install --frozen-lockfile | |
| - name: Install adapter dependencies | |
| working-directory: adapters | |
| run: bun install --frozen-lockfile | |
| - name: Run coverage checks | |
| env: | |
| COVERAGE_BASE_REF: origin/${{ github.base_ref }} | |
| run: bun run check:coverage | |
| - name: Summarize coverage report | |
| if: always() | |
| run: | | |
| latest_report="$(find artifacts/coverage -name coverage-report.md -print | sort | tail -n 1)" | |
| if [ -n "$latest_report" ]; then | |
| cat "$latest_report" >> "$GITHUB_STEP_SUMMARY" | |
| fi | |
| - name: Upload coverage report | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: coverage-report | |
| path: artifacts/coverage/ | |
| retention-days: 14 | |
| pr-quality-gate: | |
| name: pr-quality-gate | |
| needs: | |
| - scope-plan | |
| - policy-enforcement | |
| - desktop-checks | |
| - server-checks | |
| - provider-contract-checks | |
| - chat-contract-checks | |
| - adapter-checks | |
| - desktop-native-checks | |
| - persistence-checks | |
| - docs-checks | |
| - coverage-checks | |
| if: always() | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Require every selected quality job to pass | |
| run: | | |
| failures=0 | |
| require_success() { | |
| local name="$1" | |
| local result="$2" | |
| if [ "$result" != "success" ]; then | |
| echo "::error::$name ended with result: $result" | |
| failures=$((failures + 1)) | |
| else | |
| echo "$name: success" | |
| fi | |
| } | |
| require_selected() { | |
| local name="$1" | |
| local expected="$2" | |
| local result="$3" | |
| if [ "$expected" = "true" ]; then | |
| require_success "$name" "$result" | |
| elif [ "$result" != "skipped" ]; then | |
| echo "::error::$name was not selected but ended with result: $result" | |
| failures=$((failures + 1)) | |
| else | |
| echo "$name: skipped by scope plan" | |
| fi | |
| } | |
| require_success "scope-plan" "${{ needs.scope-plan.result }}" | |
| require_success "policy-enforcement" "${{ needs.policy-enforcement.result }}" | |
| require_selected "desktop-checks" "${{ needs.scope-plan.outputs.desktop_checks }}" "${{ needs.desktop-checks.result }}" | |
| require_selected "server-checks" "${{ needs.scope-plan.outputs.server_checks }}" "${{ needs.server-checks.result }}" | |
| require_selected "provider-contract-checks" "${{ needs.scope-plan.outputs.provider_contract_checks }}" "${{ needs.provider-contract-checks.result }}" | |
| require_selected "chat-contract-checks" "${{ needs.scope-plan.outputs.chat_contract_checks }}" "${{ needs.chat-contract-checks.result }}" | |
| require_selected "adapter-checks" "${{ needs.scope-plan.outputs.adapter_checks }}" "${{ needs.adapter-checks.result }}" | |
| require_selected "desktop-native-checks" "${{ needs.scope-plan.outputs.desktop_native_checks }}" "${{ needs.desktop-native-checks.result }}" | |
| require_selected "persistence-checks" "${{ needs.scope-plan.outputs.persistence_checks }}" "${{ needs.persistence-checks.result }}" | |
| require_selected "docs-checks" "${{ needs.scope-plan.outputs.docs_checks }}" "${{ needs.docs-checks.result }}" | |
| require_selected "coverage-checks" "${{ needs.scope-plan.outputs.coverage_checks }}" "${{ needs.coverage-checks.result }}" | |
| if [ "$failures" -gt 0 ]; then | |
| exit 1 | |
| fi |