fix: detect legacy bd split stores in doctor #2627
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: | |
| permissions: | |
| contents: read | |
| jobs: | |
| # Detect which paths changed to gate conditional jobs. | |
| changes: | |
| name: Detect changes | |
| runs-on: ubuntu-latest | |
| outputs: | |
| mail: ${{ steps.filter.outputs.mail }} | |
| docker: ${{ steps.filter.outputs.docker }} | |
| k8s: ${{ steps.filter.outputs.k8s }} | |
| beads: ${{ steps.filter.outputs.beads }} | |
| packs: ${{ steps.filter.outputs.packs }} | |
| rest_full: ${{ steps.filter.outputs.rest_full }} | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3 | |
| id: filter | |
| with: | |
| filters: | | |
| mail: | |
| - 'internal/mail/**' | |
| - 'contrib/mail-scripts/**' | |
| docker: | |
| - 'internal/session/**' | |
| - 'scripts/gc-session-docker' | |
| - 'scripts/test-docker-session' | |
| - 'contrib/session-scripts/**' | |
| k8s: | |
| - 'internal/session/**' | |
| - 'contrib/session-scripts/gc-session-k8s*' | |
| - 'test/integration/session_k8s_test.go' | |
| beads: | |
| - 'go.mod' | |
| - 'internal/beads/**' | |
| packs: | |
| - 'examples/gastown/packs/**' | |
| - 'internal/config/pack.go' | |
| - 'internal/config/compose.go' | |
| - 'cmd/gc/embed_builtin_packs.go' | |
| rest_full: | |
| - '.github/actions/setup-gascity-ubuntu/**' | |
| - '.github/workflows/ci.yml' | |
| - '.github/workflows/nightly.yml' | |
| - '.github/workflows/rc-gate.yml' | |
| - 'Makefile' | |
| - 'go.mod' | |
| - 'go.sum' | |
| - 'cmd/gc/**' | |
| - 'scripts/test-integration-shard' | |
| - 'test/agents/**' | |
| - 'test/integration/**' | |
| - 'test/tmuxtest/**' | |
| - 'internal/**' | |
| # Always runs: lint, fmt, vet, unit tests, docs, acceptance, coverage. | |
| check: | |
| name: Check | |
| runs-on: ubuntu-latest | |
| env: | |
| # Pinned dependency versions — keep in sync with deps.env. | |
| DOLT_VERSION: "1.86.1" | |
| BD_VERSION: "v1.0.0" | |
| # Make TestGeneratedClientInSync fatal on missing oapi-codegen so the | |
| # spec→client drift check can never silently skip in CI. | |
| GC_REQUIRE_OAPI_CODEGEN: "1" | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6 | |
| with: | |
| go-version: "1.25.8" | |
| - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 | |
| with: | |
| node-version: "22" | |
| - name: Install system dependencies | |
| run: sudo apt-get update && sudo apt-get install -y tmux jq | |
| - name: Install dolt v${{ env.DOLT_VERSION }} | |
| run: | | |
| curl -fsSL https://github.com/dolthub/dolt/releases/download/v${{ env.DOLT_VERSION }}/install.sh | sudo bash | |
| dolt version | |
| - name: Install released bd v${{ env.BD_VERSION }} | |
| run: | | |
| archive="beads_${BD_VERSION#v}_linux_amd64.tar.gz" | |
| mkdir -p "$RUNNER_TEMP/beads" | |
| curl -fsSL -o "$RUNNER_TEMP/$archive" \ | |
| "https://github.com/gastownhall/beads/releases/download/${BD_VERSION}/${archive}" | |
| tar -xzf "$RUNNER_TEMP/$archive" -C "$RUNNER_TEMP/beads" bd | |
| sudo install -m 0755 "$RUNNER_TEMP/beads/bd" /usr/local/bin/bd | |
| bd version | |
| - name: Install Claude CLI | |
| run: npm install -g @anthropic-ai/claude-code | |
| - name: Install tools | |
| run: make install-tools | |
| - name: Lint | |
| run: make lint | |
| - name: Format | |
| run: make fmt-check | |
| - name: Vet | |
| run: make vet | |
| - name: Test | |
| run: make test-cover | |
| - name: Docs | |
| run: make check-docs | |
| - name: Acceptance tests (Tier A) | |
| run: make test-acceptance | |
| - name: Dashboard bundle drift check | |
| run: make dashboard-ci | |
| - name: OpenAPI spec + client drift check | |
| run: make spec-ci | |
| - name: Upload coverage to Codecov | |
| uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5 | |
| with: | |
| files: coverage.txt | |
| flags: unit | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| verbose: true | |
| # Runs always. Keep the packages shard blocking so PRs still fail on | |
| # integration-tagged package regressions even though `Check` is now | |
| # unit-only. This is also the required non-fast path for the slow cmd/gc | |
| # process suite, because scripts/test-integration-shard forces | |
| # `GC_FAST_UNIT=0` for integration shard execution. Set repository variable | |
| # CI_PACKAGES_SHARD_SOFT_FAIL=true for an emergency rollback to best-effort | |
| # without editing the workflow. | |
| # The heavier end-to-end review-formulas shard is routed in its own | |
| # workflow so label-triggered reruns do not re-fire the whole CI suite. | |
| # The rest shard is now split: a smoke slice stays here on every PR while | |
| # the full tier runs separately on targeted runtime/workflow changes. | |
| integration-shards: | |
| name: Integration / ${{ matrix.shard_name }} | |
| runs-on: ubuntu-latest | |
| continue-on-error: >- | |
| ${{ | |
| matrix.continue_on_error || | |
| (matrix.shard_name == 'packages' && vars.CI_PACKAGES_SHARD_SOFT_FAIL == 'true') | |
| }} | |
| timeout-minutes: ${{ matrix.timeout_minutes }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - shard_name: packages | |
| continue_on_error: false | |
| timeout_minutes: 45 | |
| command: make test-integration-packages-cover | |
| coverage_file: coverage.integration-packages.txt | |
| coverage_flag: integration-packages | |
| - shard_name: bdstore | |
| continue_on_error: true | |
| timeout_minutes: 15 | |
| command: make test-integration-bdstore-cover | |
| coverage_file: coverage.integration-bdstore.txt | |
| coverage_flag: integration-bdstore | |
| - shard_name: rest-smoke | |
| continue_on_error: true | |
| timeout_minutes: 30 | |
| command: make test-integration-rest-smoke-cover | |
| coverage_file: coverage.integration-rest-smoke.txt | |
| coverage_flag: integration-rest-smoke | |
| env: | |
| DOLT_VERSION: "1.86.1" | |
| BD_VERSION: "v1.0.0" | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - uses: ./.github/actions/setup-gascity-ubuntu | |
| with: | |
| dolt-version: ${{ env.DOLT_VERSION }} | |
| bd-version: ${{ env.BD_VERSION }} | |
| install-claude-cli: "true" | |
| - name: Install tools | |
| run: make install-tools | |
| - name: Run integration shard | |
| id: shard | |
| run: ${{ matrix.command }} | |
| - name: Inspect shard coverage profile | |
| if: steps.shard.outcome == 'success' | |
| run: | | |
| if [[ -f "${{ matrix.coverage_file }}" ]]; then | |
| ls -lh "${{ matrix.coverage_file }}" | |
| else | |
| echo "coverage file missing: ${{ matrix.coverage_file }}" | |
| fi | |
| - name: Upload shard coverage to Codecov | |
| if: steps.shard.outcome == 'success' && hashFiles(matrix.coverage_file) != '' | |
| uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5 | |
| with: | |
| files: ${{ matrix.coverage_file }} | |
| flags: ${{ matrix.coverage_flag }} | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| verbose: true | |
| # The heavier rest tier only runs on workflow/runtime changes in PRs and | |
| # pushes; nightly and RC still exercise it unconditionally. | |
| integration-rest-full: | |
| name: Integration / rest-full | |
| needs: [changes] | |
| if: github.event_name == 'push' || needs.changes.outputs.rest_full == 'true' | |
| runs-on: ubuntu-latest | |
| continue-on-error: true | |
| timeout-minutes: 45 | |
| env: | |
| DOLT_VERSION: "1.86.1" | |
| BD_VERSION: "v1.0.0" | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - uses: ./.github/actions/setup-gascity-ubuntu | |
| with: | |
| dolt-version: ${{ env.DOLT_VERSION }} | |
| bd-version: ${{ env.BD_VERSION }} | |
| install-claude-cli: "true" | |
| - name: Install tools | |
| run: make install-tools | |
| - name: Run rest-full shard | |
| id: shard | |
| run: make test-integration-rest-full-cover | |
| - name: Inspect shard coverage profile | |
| if: steps.shard.outcome == 'success' | |
| run: | | |
| if [[ -f "coverage.integration-rest-full.txt" ]]; then | |
| ls -lh "coverage.integration-rest-full.txt" | |
| else | |
| echo "coverage file missing: coverage.integration-rest-full.txt" | |
| fi | |
| - name: Upload shard coverage to Codecov | |
| if: >- | |
| steps.shard.outcome == 'success' && | |
| hashFiles('coverage.integration-rest-full.txt') != '' && | |
| ( | |
| github.event_name != 'pull_request' || | |
| github.event.pull_request.head.repo.full_name == github.repository | |
| ) | |
| uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5 | |
| with: | |
| files: coverage.integration-rest-full.txt | |
| flags: integration-rest-full | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| verbose: true | |
| # Runs when pack-related files change — full gastown integration suite. | |
| pack-gate: | |
| name: Pack compatibility gate | |
| needs: [changes, check] | |
| if: needs.changes.outputs.packs == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6 | |
| with: | |
| go-version: "1.25.8" | |
| - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 | |
| with: | |
| node-version: "22" | |
| - name: Install system dependencies | |
| run: sudo apt-get update && sudo apt-get install -y tmux jq | |
| - name: Install dolt | |
| run: | | |
| curl -fsSL https://github.com/dolthub/dolt/releases/download/v${{ env.DOLT_VERSION }}/install.sh | sudo bash | |
| - name: Install released bd v${{ env.BD_VERSION }} | |
| run: | | |
| archive="beads_${BD_VERSION#v}_linux_amd64.tar.gz" | |
| mkdir -p "$RUNNER_TEMP/beads" | |
| curl -fsSL -o "$RUNNER_TEMP/$archive" \ | |
| "https://github.com/gastownhall/beads/releases/download/${BD_VERSION}/${archive}" | |
| tar -xzf "$RUNNER_TEMP/$archive" -C "$RUNNER_TEMP/beads" bd | |
| sudo install -m 0755 "$RUNNER_TEMP/beads/bd" /usr/local/bin/bd | |
| - name: Install Claude CLI | |
| run: npm install -g @anthropic-ai/claude-code | |
| - name: Install tools | |
| run: make install-tools | |
| - name: Pack compatibility tests | |
| run: make test-acceptance | |
| env: | |
| DOLT_VERSION: "1.86.1" | |
| BD_VERSION: "v1.0.0" | |
| # Dashboard SPA typecheck + tests + build. Runs on every push/PR | |
| # so TS drift against the spec (e.g. a query param tightening from | |
| # string to boolean) fails CI instead of shipping as a silent | |
| # runtime bug. Vite's build transpiles TS to JS and does not fail | |
| # on type errors; `tsc --noEmit` via `npm run typecheck` is the | |
| # load-bearing discipline step. | |
| dashboard: | |
| name: Dashboard SPA | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 | |
| with: | |
| node-version: "22" | |
| - name: Install SPA dependencies | |
| run: npm install --silent | |
| working-directory: cmd/gc/dashboard/web | |
| - name: Verify generated TS schema is in sync | |
| run: | | |
| npm run gen --silent | |
| if ! git diff --exit-code src/generated/schema.d.ts; then | |
| echo "::error::Generated TS schema drifted. Regenerate via 'npm run gen' in cmd/gc/dashboard/web." | |
| exit 1 | |
| fi | |
| working-directory: cmd/gc/dashboard/web | |
| - name: Typecheck (tsc --noEmit) | |
| run: npm run typecheck | |
| working-directory: cmd/gc/dashboard/web | |
| - name: Vitest | |
| run: npm test | |
| working-directory: cmd/gc/dashboard/web | |
| - name: Build | |
| run: npm run build --silent | |
| working-directory: cmd/gc/dashboard/web | |
| # Runs when mail-related source paths change. | |
| mcp-mail: | |
| name: MCP mail conformance | |
| needs: changes | |
| if: needs.changes.outputs.mail == 'true' | |
| runs-on: ubuntu-latest | |
| continue-on-error: true # upstream mcp_agent_mail API may drift | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6 | |
| with: | |
| go-version-file: go.mod | |
| - name: Install system dependencies | |
| run: sudo apt-get update && sudo apt-get install -y jq curl | |
| - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 | |
| with: | |
| python-version: '3.12' | |
| - name: Install mcp_agent_mail | |
| run: pip install 'mcp-agent-mail==0.1.0' | |
| - name: MCP mail conformance test | |
| run: make test-mcp-mail | |
| # Runs when session/Docker-related source paths change. | |
| docker-session: | |
| name: Docker session | |
| needs: changes | |
| if: needs.changes.outputs.docker == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6 | |
| with: | |
| go-version-file: go.mod | |
| - name: Install system dependencies | |
| run: sudo apt-get update && sudo apt-get install -y jq | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3 | |
| - name: Install tools | |
| run: make install-tools | |
| - name: Docker session tests | |
| run: make test-docker | |
| # Runs when session/K8s-related source paths change. | |
| # Requires K8s CI infrastructure — no-op until secrets are configured. | |
| k8s-session: | |
| name: K8s session | |
| needs: changes | |
| if: needs.changes.outputs.k8s == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6 | |
| with: | |
| go-version-file: go.mod | |
| - name: Install system dependencies | |
| run: sudo apt-get update && sudo apt-get install -y jq | |
| - name: K8s session tests | |
| if: env.GC_K8S_AVAILABLE == 'true' | |
| env: | |
| GC_K8S_AVAILABLE: ${{ secrets.GC_K8S_AVAILABLE }} | |
| run: make test-k8s |