perf(metrics): stop paying telemetry startup costs on every bd invoca… #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: Main | |
| on: | |
| push: | |
| branches: [ main ] | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| BD_DISABLE_METRICS: "1" | |
| BD_DISABLE_EVENT_FLUSH: "1" | |
| jobs: | |
| detect-ci-tier: | |
| name: Detect CI tier | |
| runs-on: ubuntu-latest | |
| outputs: | |
| full_embedded: ${{ steps.tier.outputs.full_embedded }} | |
| reason: ${{ steps.tier.outputs.reason }} | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Decide embedded Dolt coverage | |
| id: tier | |
| env: | |
| PR_BASE_SHA: ${{ github.event.pull_request.base.sha }} | |
| PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }} | |
| run: bash .github/scripts/ci-embedded-tier.sh | |
| # Same guard as pr.yml's check-migration-hygiene: direct pushes to main | |
| # (and PR merges whose base moved) must not bypass the migration lints. | |
| # BASE_SHA is the pre-push tip; on force pushes or history rewrites the | |
| # script warns and skips the frozen-migrations diff but still runs the | |
| # duplicate-version and nondeterministic-SQL checks. | |
| check-migration-hygiene: | |
| name: Check migration hygiene | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Run migration hygiene checks | |
| env: | |
| BASE_SHA: ${{ github.event.before }} | |
| run: ./scripts/check-migration-hygiene.sh | |
| build-artifacts: | |
| name: Build Artifacts | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Set up Go | |
| id: setup-go | |
| uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 | |
| with: | |
| go-version-file: 'go.mod' | |
| cache: false | |
| - name: Restore Go module cache | |
| id: restore-go-module-cache | |
| uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | |
| with: | |
| path: ~/go/pkg/mod | |
| key: beads-go-mod-v2-${{ runner.os }}-${{ runner.arch }}-go-${{ steps.setup-go.outputs.go-version }}-${{ hashFiles('go.mod', 'go.sum') }} | |
| restore-keys: beads-go-mod-v2-${{ runner.os }}-${{ runner.arch }}-go-${{ steps.setup-go.outputs.go-version }}- | |
| # Per `go help cache`, Go's content-addressed build cache includes | |
| # compiler options, so this base-tag directory can serve builds with | |
| # additional tags. Race builds stay separate; Windows native/cgo | |
| # non-race builds share theirs. | |
| - name: Restore non-race Go build cache | |
| id: restore-non-race-go-build-cache | |
| uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | |
| with: | |
| path: ${{ runner.temp }}/go-cache/non-race | |
| key: beads-go-build-v2-${{ runner.os }}-${{ runner.arch }}-go-${{ steps.setup-go.outputs.go-version }}-base-gms_pure_go-non-race-${{ github.sha }} | |
| restore-keys: beads-go-build-v2-${{ runner.os }}-${{ runner.arch }}-go-${{ steps.setup-go.outputs.go-version }}-base-gms_pure_go-non-race- | |
| - name: Build reusable Linux artifacts | |
| env: | |
| GOCACHE: ${{ runner.temp }}/go-cache/non-race | |
| run: | | |
| set -euo pipefail | |
| mkdir -p artifacts | |
| source ./.buildflags | |
| go_version="$(go version)" | |
| commit="$(git rev-parse HEAD)" | |
| go build -tags "$BEADS_BUILD_TAGS" -o artifacts/bd-linux-gms-pure ./cmd/bd | |
| chmod +x artifacts/bd-linux-gms-pure | |
| go test -tags "$BEADS_BUILD_TAGS" -c -o artifacts/bd-cmd-test ./cmd/bd | |
| chmod +x artifacts/bd-cmd-test | |
| ( | |
| cd artifacts | |
| sha256sum bd-linux-gms-pure > SHA256SUMS | |
| ) | |
| { | |
| echo "commit=${commit}" | |
| echo "go_version=${go_version}" | |
| echo "build_tags=${BEADS_BUILD_TAGS}" | |
| echo "artifact=bd-linux-gms-pure" | |
| } > artifacts/build-manifest.txt | |
| - name: Upload build artifacts | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: ci-build-artifacts | |
| path: artifacts/ | |
| retention-days: 1 | |
| if-no-files-found: error | |
| - name: Save Go module cache | |
| if: steps.restore-go-module-cache.outputs.cache-hit != 'true' | |
| uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | |
| with: | |
| path: ~/go/pkg/mod | |
| key: beads-go-mod-v2-${{ runner.os }}-${{ runner.arch }}-go-${{ steps.setup-go.outputs.go-version }}-${{ hashFiles('go.mod', 'go.sum') }} | |
| - name: Save non-race Go build cache | |
| if: steps.restore-non-race-go-build-cache.outputs.cache-hit != 'true' | |
| uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | |
| with: | |
| path: ${{ runner.temp }}/go-cache/non-race | |
| key: beads-go-build-v2-${{ runner.os }}-${{ runner.arch }}-go-${{ steps.setup-go.outputs.go-version }}-base-gms_pure_go-non-race-${{ github.sha }} | |
| # Fast check: every `go build|test|run|generate|install` invocation in | |
| # tracked scripts/hooks/CI carries -tags=gms_pure_go. Prevents ICU-linkage | |
| # regressions from re-entering the build (see engdocs/ICU-POLICY.md). | |
| check-build-tags: | |
| name: Check build-tag policy | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6 | |
| - run: ./scripts/check-build-tags.sh | |
| - run: ./scripts/check-go-install-guidance.sh | |
| # Lock in the cgo-test-contamination fix (mybd-ycx / GH#3683 follow-up). | |
| # cmd/bd carries a mix of cgo-only test helpers (embedded Dolt, sql.DB) and | |
| # pure-Go tests. Untagged test files that reach for cgo-only helpers break | |
| # the entire package's CGO_ENABLED=0 compile, silently neutering pure-Go | |
| # tests (the original symptom in PR #3704). This job compiles the cmd/bd | |
| # test binary with CGO_ENABLED=0 and runs the pure-Go subset, so a | |
| # regression that re-introduces cgo coupling fails fast. | |
| check-cmd-bd-puregeo-tests: | |
| name: Check cmd/bd pure-Go tests compile (CGO_ENABLED=0) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6 | |
| - name: Set up Go | |
| uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 | |
| with: | |
| go-version-file: 'go.mod' | |
| cache: false | |
| - name: Build cmd/bd (CGO_ENABLED=0, gms_pure_go) | |
| env: | |
| CGO_ENABLED: "0" | |
| run: go build -tags gms_pure_go -o /tmp/bd-puregeo ./cmd/bd | |
| - name: Compile pure-Go test binaries (CGO_ENABLED=0, gms_pure_go) | |
| env: | |
| CGO_ENABLED: "0" | |
| run: | | |
| go test -tags gms_pure_go -c -o /tmp/bd-cmd-puregeo-test ./cmd/bd | |
| go test -tags gms_pure_go -c -o /tmp/bd-embeddeddolt-puregeo-test ./internal/storage/embeddeddolt | |
| go test -tags gms_pure_go -c -o /tmp/bd-tracker-puregeo-test ./internal/tracker | |
| - name: Run pure-Go cmd/bd test subset (CGO_ENABLED=0) | |
| env: | |
| CGO_ENABLED: "0" | |
| # Restrict to tests that exercise pure-Go code paths. Tests that | |
| # need a Dolt store skip themselves at runtime when no test server | |
| # is available; the goal here is to catch compile-time contamination, | |
| # not run the full suite. | |
| run: | | |
| go test -tags gms_pure_go -count=1 -short -run '^Test(Help|CheckRemoteSafety|FormatDestroyToken|ShouldWireInitRemote|ExtractPrefix|IsNumericID|GetWorktreeGitDir|DriftItemStatuses|RunDriftChecks|IsServerProbablyRunning|CheckHooksDriftNotGitRepo|CheckServerDriftNoBeadsDir|CheckRemoteDriftNoBeadsDir)' ./cmd/bd | |
| # Fast check to ensure all version files are in sync | |
| check-version-consistency: | |
| name: Check version consistency | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6 | |
| - name: Check all versions match | |
| run: ./scripts/check-versions.sh | |
| # Catch duplicate migration version numbers before any Go build. | |
| # Two long-lived branches both claiming 'the next number' produce a silent | |
| # under-apply when merged; this job fails at PR time with the conflicting | |
| # filenames so it is caught before any test even compiles. | |
| check-no-duplicate-migrations: | |
| name: Check no duplicate migration versions | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6 | |
| - name: Check for duplicate migration version numbers | |
| run: | | |
| dup=$( | |
| find internal/storage/schema/migrations -maxdepth 1 -name '*.up.sql' -printf '%f\n' \ | |
| | sed 's/^\([0-9]*\)_.*/\1/' \ | |
| | sort | uniq -d | |
| ) | |
| if [ -n "$dup" ]; then | |
| echo "Duplicate migration version(s) detected: $dup" | |
| echo "Conflicting files:" | |
| while IFS= read -r v; do | |
| find internal/storage/schema/migrations -name "${v}_*.up.sql" -print | |
| done <<< "$dup" | |
| echo "Renumber one of the colliding files before merging." | |
| exit 1 | |
| fi | |
| # Check documentation references match actual CLI flags | |
| check-doc-flags: | |
| name: Check doc flags freshness | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6 | |
| - name: Set up Go | |
| uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 | |
| with: | |
| go-version-file: 'go.mod' | |
| cache: false | |
| - name: Build bd | |
| run: CGO_ENABLED=0 go build -tags gms_pure_go -o bd ./cmd/bd/ | |
| - name: Validate docs against CLI | |
| run: | | |
| ./scripts/check-doc-flags.sh ./bd | |
| ./scripts/check-doc-freshness.sh | |
| detect-package-gates: | |
| name: Detect package gates | |
| runs-on: ubuntu-latest | |
| outputs: | |
| mcp_package: ${{ steps.detect.outputs.mcp_package }} | |
| npm_package: ${{ steps.detect.outputs.npm_package }} | |
| reason: ${{ steps.detect.outputs.reason }} | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Decide package gates | |
| id: detect | |
| env: | |
| PR_BASE_SHA: ${{ github.event.pull_request.base.sha }} | |
| PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }} | |
| PUSH_BEFORE_SHA: ${{ github.event.before }} | |
| PUSH_AFTER_SHA: ${{ github.sha }} | |
| run: ./scripts/ci/detect-package-gates.sh | |
| package-mcp: | |
| name: Package Gate (MCP) | |
| runs-on: ubuntu-latest | |
| needs: [detect-package-gates, build-artifacts] | |
| steps: | |
| - name: Check applicability | |
| id: applicability | |
| run: | | |
| echo "run=${{ needs.detect-package-gates.outputs.mcp_package }}" >> "$GITHUB_OUTPUT" | |
| if [[ "${{ needs.detect-package-gates.outputs.mcp_package }}" != "true" ]]; then | |
| echo "MCP package gate is not applicable: ${{ needs.detect-package-gates.outputs.reason }}" | |
| fi | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6 | |
| if: steps.applicability.outputs.run == 'true' | |
| - name: Set up Python | |
| if: steps.applicability.outputs.run == 'true' | |
| uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 | |
| with: | |
| python-version: '3.14' | |
| - name: Install uv | |
| if: steps.applicability.outputs.run == 'true' | |
| run: python -m pip install uv==0.11.16 | |
| - name: Download build artifacts | |
| if: steps.applicability.outputs.run == 'true' | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| name: ci-build-artifacts | |
| path: ci-build-artifacts | |
| - name: Verify build artifacts | |
| if: steps.applicability.outputs.run == 'true' | |
| run: | | |
| set -euo pipefail | |
| cd ci-build-artifacts | |
| sha256sum -c SHA256SUMS | |
| chmod +x bd-linux-gms-pure | |
| - name: Run MCP package gate | |
| if: steps.applicability.outputs.run == 'true' | |
| env: | |
| BEADS_TEST_BD_BINARY: ${{ github.workspace }}/ci-build-artifacts/bd-linux-gms-pure | |
| run: make ci-package-mcp | |
| package-npm: | |
| name: Package Gate (npm) | |
| runs-on: ubuntu-latest | |
| needs: [detect-package-gates, build-artifacts] | |
| steps: | |
| - name: Check applicability | |
| id: applicability | |
| run: | | |
| echo "run=${{ needs.detect-package-gates.outputs.npm_package }}" >> "$GITHUB_OUTPUT" | |
| if [[ "${{ needs.detect-package-gates.outputs.npm_package }}" != "true" ]]; then | |
| echo "npm package gate is not applicable: ${{ needs.detect-package-gates.outputs.reason }}" | |
| fi | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6 | |
| if: steps.applicability.outputs.run == 'true' | |
| - name: Set up Node.js | |
| if: steps.applicability.outputs.run == 'true' | |
| uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v6 | |
| with: | |
| node-version: '24' | |
| - name: Download build artifacts | |
| if: steps.applicability.outputs.run == 'true' | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| name: ci-build-artifacts | |
| path: ci-build-artifacts | |
| - name: Verify build artifacts | |
| if: steps.applicability.outputs.run == 'true' | |
| run: | | |
| set -euo pipefail | |
| cd ci-build-artifacts | |
| sha256sum -c SHA256SUMS | |
| chmod +x bd-linux-gms-pure | |
| - name: Run npm package gate | |
| if: steps.applicability.outputs.run == 'true' | |
| env: | |
| BEADS_TEST_BD_BINARY: ${{ github.workspace }}/ci-build-artifacts/bd-linux-gms-pure | |
| run: make ci-package-npm | |
| pr-policy-wrapper: | |
| name: PR Policy (wrapper timing) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Set up Go | |
| uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 | |
| with: | |
| go-version-file: 'go.mod' | |
| cache: false | |
| - name: Run PR policy wrapper | |
| run: make ci-pr-policy | |
| pr-core-wrapper: | |
| name: PR Core (wrapper timing) | |
| runs-on: ubuntu-latest | |
| needs: build-artifacts | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6 | |
| - name: Set up Go | |
| id: setup-go | |
| uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 | |
| with: | |
| go-version-file: 'go.mod' | |
| cache: false | |
| - name: Restore Go module cache | |
| id: restore-go-module-cache | |
| uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | |
| with: | |
| path: ~/go/pkg/mod | |
| key: beads-go-mod-v2-${{ runner.os }}-${{ runner.arch }}-go-${{ steps.setup-go.outputs.go-version }}-${{ hashFiles('go.mod', 'go.sum') }} | |
| restore-keys: beads-go-mod-v2-${{ runner.os }}-${{ runner.arch }}-go-${{ steps.setup-go.outputs.go-version }}- | |
| - name: Restore race Go build cache | |
| id: restore-race-go-build-cache | |
| uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | |
| with: | |
| path: ${{ runner.temp }}/go-cache/race | |
| key: beads-go-build-v2-${{ runner.os }}-${{ runner.arch }}-go-${{ steps.setup-go.outputs.go-version }}-base-gms_pure_go-race-${{ github.sha }} | |
| restore-keys: beads-go-build-v2-${{ runner.os }}-${{ runner.arch }}-go-${{ steps.setup-go.outputs.go-version }}-base-gms_pure_go-race- | |
| - name: Install Dolt | |
| run: curl -fsSL https://github.com/dolthub/dolt/releases/latest/download/install.sh | sudo bash | |
| - name: Configure Git and Dolt identity | |
| run: | | |
| git config --global user.name "CI Bot" | |
| git config --global user.email "ci@beads.test" | |
| dolt config --global --add user.name "CI Bot" | |
| dolt config --global --add user.email "ci@beads.test" | |
| - name: Download build artifacts | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| name: ci-build-artifacts | |
| path: ci-build-artifacts | |
| - name: Verify build artifacts | |
| run: | | |
| set -euo pipefail | |
| cd ci-build-artifacts | |
| sha256sum -c SHA256SUMS | |
| chmod +x bd-linux-gms-pure | |
| - name: Run PR core wrapper | |
| env: | |
| BEADS_TEST_BD_BINARY: ${{ github.workspace }}/ci-build-artifacts/bd-linux-gms-pure | |
| GOCACHE: ${{ runner.temp }}/go-cache/race | |
| run: make ci-pr-core | |
| pr-lint-wrapper: | |
| name: PR Lint (wrapper timing) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6 | |
| - name: Set up Go | |
| uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 | |
| with: | |
| go-version-file: 'go.mod' | |
| cache: false | |
| - name: Install golangci-lint | |
| run: go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.10.1 | |
| # No BD_LINT_NEW_FROM_MERGE_BASE here: the push lane sweeps the whole | |
| # tree, including the GOOS=windows cross-lint. pr.yml scopes the same | |
| # wrapper to the PR's own diff. | |
| - name: Run PR lint wrapper | |
| run: make ci-pr-lint | |
| # Cross-platform test matrix (Linux/macOS only - Windows uses smoke tests) | |
| test: | |
| name: Test (${{ matrix.os }}) | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| runs-on: ${{ matrix.os }} | |
| needs: build-artifacts | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest] | |
| include: | |
| # Linux: full test suite with coverage | |
| - os: ubuntu-latest | |
| coverage: true | |
| test-flags: '-v -race -short -coverprofile=coverage.out' | |
| # macOS: full test suite, no coverage (faster) | |
| - os: macos-latest | |
| coverage: false | |
| test-flags: '-v -race -short' | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6 | |
| - name: Set up Go | |
| id: setup-go | |
| uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 | |
| with: | |
| go-version-file: 'go.mod' | |
| cache: false | |
| - name: Restore Go module cache | |
| id: restore-go-module-cache | |
| uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | |
| with: | |
| path: ~/go/pkg/mod | |
| key: beads-go-mod-v2-${{ runner.os }}-${{ runner.arch }}-go-${{ steps.setup-go.outputs.go-version }}-${{ hashFiles('go.mod', 'go.sum') }} | |
| restore-keys: beads-go-mod-v2-${{ runner.os }}-${{ runner.arch }}-go-${{ steps.setup-go.outputs.go-version }}- | |
| - name: Restore non-race Go build cache | |
| id: restore-non-race-go-build-cache | |
| if: matrix.os == 'macos-latest' | |
| uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | |
| with: | |
| path: ${{ runner.temp }}/go-cache/non-race | |
| key: beads-go-build-v2-${{ runner.os }}-${{ runner.arch }}-go-${{ steps.setup-go.outputs.go-version }}-base-gms_pure_go-non-race-${{ github.sha }} | |
| restore-keys: beads-go-build-v2-${{ runner.os }}-${{ runner.arch }}-go-${{ steps.setup-go.outputs.go-version }}-base-gms_pure_go-non-race- | |
| - name: Restore race Go build cache | |
| id: restore-race-go-build-cache | |
| uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | |
| with: | |
| path: ${{ runner.temp }}/go-cache/race | |
| key: beads-go-build-v2-${{ runner.os }}-${{ runner.arch }}-go-${{ steps.setup-go.outputs.go-version }}-base-gms_pure_go-race-${{ github.sha }} | |
| restore-keys: beads-go-build-v2-${{ runner.os }}-${{ runner.arch }}-go-${{ steps.setup-go.outputs.go-version }}-base-gms_pure_go-race- | |
| - name: Install Dolt (Linux/macOS) | |
| run: curl -fsSL https://github.com/dolthub/dolt/releases/latest/download/install.sh | sudo bash | |
| - name: Verify dolt on PATH | |
| run: dolt version | |
| - name: Configure Git and Dolt identity | |
| run: | | |
| git config --global user.name "CI Bot" | |
| git config --global user.email "ci@beads.test" | |
| dolt config --global --add user.name "CI Bot" | |
| dolt config --global --add user.email "ci@beads.test" | |
| - name: Install gotestsum | |
| if: matrix.coverage | |
| run: go install gotest.tools/gotestsum@v1.13.0 | |
| - name: Download build artifacts | |
| if: matrix.os == 'ubuntu-latest' | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| name: ci-build-artifacts | |
| path: ci-build-artifacts | |
| - name: Verify build artifacts | |
| if: matrix.os == 'ubuntu-latest' | |
| run: | | |
| set -euo pipefail | |
| cd ci-build-artifacts | |
| sha256sum -c SHA256SUMS | |
| chmod +x bd-linux-gms-pure | |
| - name: Build | |
| if: matrix.os != 'ubuntu-latest' | |
| env: | |
| GOCACHE: ${{ runner.temp }}/go-cache/non-race | |
| run: go build -v -tags gms_pure_go ./cmd/bd | |
| - name: Test (with coverage + JUnit XML) | |
| if: matrix.coverage | |
| env: | |
| BEADS_TEST_BD_BINARY: ${{ github.workspace }}/ci-build-artifacts/bd-linux-gms-pure | |
| GOCACHE: ${{ runner.temp }}/go-cache/race | |
| run: | | |
| gotestsum \ | |
| --junitfile junit.xml \ | |
| --format testdox \ | |
| -- -tags gms_pure_go -race -short -coverprofile=coverage.out -skip '^TestEmbedded' ./... | |
| - name: Test | |
| if: ${{ !matrix.coverage }} | |
| env: | |
| BEADS_TEST_BD_BINARY: ${{ github.workspace }}/bd | |
| GOCACHE: ${{ runner.temp }}/go-cache/race | |
| run: go test -tags gms_pure_go ${{ matrix.test-flags }} -skip '^TestEmbedded' ./... | |
| - name: Upload coverage to Codecov | |
| if: matrix.coverage && !cancelled() | |
| uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v6 | |
| continue-on-error: true | |
| with: | |
| files: coverage.out | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| fail_ci_if_error: false | |
| - name: Upload test results to Codecov | |
| if: matrix.coverage && !cancelled() | |
| uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v6 | |
| continue-on-error: true | |
| with: | |
| files: junit.xml | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| report_type: test_results | |
| fail_ci_if_error: false | |
| # Only the macOS leg owns macOS generations. The Linux leg restores the | |
| # Linux writers above and must never become a second cache publisher. | |
| - name: Save Go module cache | |
| if: ${{ !cancelled() && matrix.os == 'macos-latest' && steps.restore-go-module-cache.outputs.cache-hit != 'true' }} | |
| uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | |
| with: | |
| path: ~/go/pkg/mod | |
| key: beads-go-mod-v2-${{ runner.os }}-${{ runner.arch }}-go-${{ steps.setup-go.outputs.go-version }}-${{ hashFiles('go.mod', 'go.sum') }} | |
| - name: Save non-race Go build cache | |
| if: ${{ !cancelled() && matrix.os == 'macos-latest' && steps.restore-non-race-go-build-cache.outputs.cache-hit != 'true' }} | |
| uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | |
| with: | |
| path: ${{ runner.temp }}/go-cache/non-race | |
| key: beads-go-build-v2-${{ runner.os }}-${{ runner.arch }}-go-${{ steps.setup-go.outputs.go-version }}-base-gms_pure_go-non-race-${{ github.sha }} | |
| - name: Save race Go build cache | |
| if: ${{ !cancelled() && matrix.os == 'macos-latest' && steps.restore-race-go-build-cache.outputs.cache-hit != 'true' }} | |
| uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | |
| with: | |
| path: ${{ runner.temp }}/go-cache/race | |
| key: beads-go-build-v2-${{ runner.os }}-${{ runner.arch }}-go-${{ steps.setup-go.outputs.go-version }}-base-gms_pure_go-race-${{ github.sha }} | |
| # Focused job for the hexagonal storage layer (internal/storage/domain/* and | |
| # internal/storage/uow). These packages back the proxied-server init path and | |
| # also live behind the existing ./... matrix, but TestDomainDB requires the | |
| # Dolt sql-server image cached locally (testcontainers checks `docker image | |
| # inspect` and skips otherwise). Pulling the image up front guarantees the | |
| # suite actually runs and surfaces failures here with a clear job name. | |
| test-domain-uow: | |
| name: Test (storage domain + uow) | |
| runs-on: ubuntu-latest | |
| needs: build-artifacts | |
| # The race-enabled storage package has outgrown Go's implicit 10-minute | |
| # timeout. Keep both per-package deadlines inside one finite job budget. | |
| timeout-minutes: 30 | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6 | |
| - name: Set up Go | |
| uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 | |
| with: | |
| go-version-file: 'go.mod' | |
| cache: false | |
| - name: Install Dolt CLI | |
| run: curl -fsSL https://github.com/dolthub/dolt/releases/latest/download/install.sh | sudo bash | |
| - name: Verify dolt on PATH | |
| run: dolt version | |
| - name: Configure Git and Dolt identity | |
| run: | | |
| git config --global user.name "CI Bot" | |
| git config --global user.email "ci@beads.test" | |
| dolt config --global --add user.name "CI Bot" | |
| dolt config --global --add user.email "ci@beads.test" | |
| - name: Pull Dolt sql-server image | |
| # Keep tag in sync with internal/testutil/testdoltcommon.go:DoltDockerImage. | |
| # Without this, RequireDoltContainer reports doltNoImage and TestDomainDB skips. | |
| run: ./scripts/ci/pull-dolt-image.sh | |
| - name: Download build artifacts | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| name: ci-build-artifacts | |
| path: ci-build-artifacts | |
| - name: Verify build artifacts | |
| run: | | |
| set -euo pipefail | |
| cd ci-build-artifacts | |
| sha256sum -c SHA256SUMS | |
| chmod +x bd-linux-gms-pure | |
| - name: Test domain + uow + tracker | |
| env: | |
| BEADS_TEST_BD_BINARY: ${{ github.workspace }}/ci-build-artifacts/bd-linux-gms-pure | |
| run: go test -tags gms_pure_go -race -count=1 -timeout 15m -v ./internal/storage/domain/... ./internal/storage/uow/... ./internal/tracker/... | |
| # The doctor/fix DB-backed suite spins its own Dolt container in | |
| # TestMain. BEADS_FIX_REQUIRE_DOLT=1 turns a missing container into a | |
| # hard failure so the suite can never silently skip in CI again | |
| # (bd-nxt5e: it was dark for months); this job pulls the image above. | |
| - name: Test doctor/fix (Dolt-backed, hard-require container) | |
| env: | |
| BEADS_TEST_BD_BINARY: ${{ github.workspace }}/ci-build-artifacts/bd-linux-gms-pure | |
| BEADS_FIX_REQUIRE_DOLT: "1" | |
| run: go test -tags gms_pure_go -race -count=1 -timeout 10m -v ./cmd/bd/doctor/fix/ | |
| main-linux-integration-packages: | |
| name: Main Linux integration packages (${{ matrix.shard }}/6) | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| runs-on: ubuntu-latest | |
| needs: build-artifacts | |
| timeout-minutes: 30 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| shard: [1, 2, 3, 4, 5, 6] | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6 | |
| - name: Set up Go | |
| uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 | |
| with: | |
| go-version-file: 'go.mod' | |
| cache: false | |
| - name: Download build artifacts | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| name: ci-build-artifacts | |
| path: ci-build-artifacts | |
| - name: Verify build artifacts | |
| run: | | |
| set -euo pipefail | |
| cd ci-build-artifacts | |
| sha256sum -c SHA256SUMS | |
| chmod +x bd-linux-gms-pure | |
| - name: Install Dolt | |
| run: curl -fsSL https://github.com/dolthub/dolt/releases/latest/download/install.sh | sudo bash | |
| - name: Configure Git and Dolt identity | |
| run: | | |
| git config --global user.name "CI Bot" | |
| git config --global user.email "ci@beads.test" | |
| dolt config --global --add user.name "CI Bot" | |
| dolt config --global --add user.email "ci@beads.test" | |
| - name: Test package shard | |
| env: | |
| SHARD: ${{ matrix.shard }} | |
| TOTAL_SHARDS: 6 | |
| BEADS_TEST_BD_BINARY: ${{ github.workspace }}/ci-build-artifacts/bd-linux-gms-pure | |
| run: | | |
| set -euo pipefail | |
| mkdir -p artifacts | |
| source scripts/ci/lib/timing.sh | |
| ci_time "install gotestsum" -- go install gotest.tools/gotestsum@v1.13.0 | |
| package_manifest="artifacts/main-linux-integration-packages-${SHARD}-of-${TOTAL_SHARDS}.txt" | |
| write_package_manifest() { | |
| GO_TEST_SHARD_TAGS=integration,gms_pure_go \ | |
| GO_TEST_SHARD_EXCLUDE_REGEX="^github.com/steveyegge/beads/cmd/bd$" \ | |
| scripts/ci/go-test-shard-packages.sh "$SHARD" "$TOTAL_SHARDS" > "$package_manifest" | |
| } | |
| ci_time "list integration package shard ${SHARD}/${TOTAL_SHARDS}" -- write_package_manifest | |
| cat "$package_manifest" | |
| mapfile -t packages < "$package_manifest" | |
| if [[ "${#packages[@]}" -eq 0 ]]; then | |
| echo "No packages assigned to shard ${SHARD}/${TOTAL_SHARDS}; skipping go test" | |
| exit 0 | |
| fi | |
| ci_time "main linux integration package shard ${SHARD}/${TOTAL_SHARDS} go test" -- \ | |
| env BEADS_TEST_SKIP=dolt gotestsum \ | |
| --junitfile "artifacts/main-linux-integration-packages-${SHARD}-of-${TOTAL_SHARDS}.xml" \ | |
| --format testdox \ | |
| -- -v -race -tags=integration,gms_pure_go -timeout=30m "${packages[@]}" | |
| - name: Upload integration artifacts | |
| if: always() | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: main-linux-integration-packages-${{ matrix.shard }}-of-6 | |
| path: artifacts/ | |
| retention-days: 7 | |
| if-no-files-found: ignore | |
| main-linux-integration-cmd-bd: | |
| name: Main Linux integration cmd/bd (${{ matrix.shard }}/8) | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| runs-on: ubuntu-latest | |
| needs: build-artifacts | |
| timeout-minutes: 30 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| shard: [1, 2, 3, 4, 5, 6, 7, 8] | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6 | |
| - name: Set up Go | |
| uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 | |
| with: | |
| go-version-file: 'go.mod' | |
| cache: false | |
| - name: Download build artifacts | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| name: ci-build-artifacts | |
| path: ci-build-artifacts | |
| - name: Verify build artifacts | |
| run: | | |
| set -euo pipefail | |
| cd ci-build-artifacts | |
| sha256sum -c SHA256SUMS | |
| chmod +x bd-linux-gms-pure | |
| - name: Install Dolt | |
| run: curl -fsSL https://github.com/dolthub/dolt/releases/latest/download/install.sh | sudo bash | |
| - name: Configure Git and Dolt identity | |
| run: | | |
| git config --global user.name "CI Bot" | |
| git config --global user.email "ci@beads.test" | |
| dolt config --global --add user.name "CI Bot" | |
| dolt config --global --add user.email "ci@beads.test" | |
| - name: Test cmd/bd shard | |
| env: | |
| SHARD: ${{ matrix.shard }} | |
| TOTAL_SHARDS: 8 | |
| BEADS_TEST_BD_BINARY: ${{ github.workspace }}/ci-build-artifacts/bd-linux-gms-pure | |
| run: | | |
| set -euo pipefail | |
| mkdir -p artifacts | |
| source scripts/ci/lib/timing.sh | |
| ci_time "install gotestsum" -- go install gotest.tools/gotestsum@v1.13.0 | |
| test_manifest="artifacts/main-linux-integration-cmd-bd-tests-${SHARD}-of-${TOTAL_SHARDS}.txt" | |
| write_test_manifest() { | |
| GO_TEST_SHARD_TAGS=integration,gms_pure_go \ | |
| scripts/ci/go-test-shard-names.sh "$SHARD" "$TOTAL_SHARDS" ./cmd/bd > "$test_manifest" | |
| } | |
| ci_time "list cmd/bd test shard ${SHARD}/${TOTAL_SHARDS}" -- write_test_manifest | |
| cat "$test_manifest" | |
| mapfile -t tests < "$test_manifest" | |
| if [[ "${#tests[@]}" -eq 0 ]]; then | |
| echo "No tests assigned to shard ${SHARD}/${TOTAL_SHARDS}; skipping go test" | |
| exit 0 | |
| fi | |
| run_regex="^($(IFS='|'; echo "${tests[*]}"))$" | |
| ci_time "main linux integration cmd/bd shard ${SHARD}/${TOTAL_SHARDS} go test" -- \ | |
| env BEADS_TEST_SKIP=dolt gotestsum \ | |
| --junitfile "artifacts/main-linux-integration-cmd-bd-${SHARD}-of-${TOTAL_SHARDS}.xml" \ | |
| --format testdox \ | |
| -- -v -race -tags=integration,gms_pure_go -timeout=30m -run "$run_regex" ./cmd/bd | |
| - name: Upload integration artifacts | |
| if: always() | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: main-linux-integration-cmd-bd-${{ matrix.shard }}-of-8 | |
| path: artifacts/ | |
| retention-days: 7 | |
| if-no-files-found: ignore | |
| # End-to-end coverage for proxied-server CLI subcommands, sharded across the | |
| # CI matrix. Each sub-test drives the bd CLI subprocess against a real dolt | |
| # sql-server started via testcontainers by the shared proxied harness | |
| # (cmd/bd/*_proxied_integration_test.go). | |
| # | |
| # Reuses the cmd/bd test binary compiled once by build-artifacts (bd-cmd-test): | |
| # the proxied tests share the package and are gated at runtime by | |
| # BEADS_TEST_PROXIED_SERVER=1. Shard assignment is committed in | |
| # .github/scripts/proxied-cmd-test-shards.txt; newly-added TestProxiedServer* | |
| # tests hash-distribute until listed there. Adopt the | |
| # `TestProxiedServer<Subcommand>` naming convention for new entry points. | |
| test-proxied-cmd: | |
| name: Test (proxied-server cmd ${{ matrix.shard }}/15) | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| runs-on: ubuntu-latest | |
| needs: build-artifacts | |
| timeout-minutes: 20 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| shard: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6 | |
| - name: Download build artifacts | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| name: ci-build-artifacts | |
| path: ci-build-artifacts | |
| - name: Verify build artifacts | |
| run: | | |
| set -euo pipefail | |
| cd ci-build-artifacts | |
| sha256sum -c SHA256SUMS | |
| chmod +x bd-linux-gms-pure bd-cmd-test | |
| - name: Install Dolt CLI | |
| # TestProxiedServerExternalCreate needs the dolt binary on PATH; the | |
| # shared harness itself uses the dolt sql-server container image. | |
| run: curl -fsSL https://github.com/dolthub/dolt/releases/latest/download/install.sh | sudo bash | |
| - name: Configure Git and Dolt identity | |
| run: | | |
| git config --global user.name "CI Bot" | |
| git config --global user.email "ci@beads.test" | |
| dolt config --global --add user.name "CI Bot" | |
| dolt config --global --add user.email "ci@beads.test" | |
| - name: Pull Dolt sql-server image | |
| # The shared proxied harness requires the image cached locally | |
| # (isDoltImageCached); without it every proxied test self-skips. Keep the | |
| # tag in sync with internal/testutil/testdoltcommon.go:DoltDockerImage. | |
| run: ./scripts/ci/pull-dolt-image.sh | |
| - name: Test proxied-server cmd shard | |
| env: | |
| BEADS_TEST_PROXIED_SERVER: "1" | |
| BEADS_TEST_BD_BINARY: ${{ github.workspace }}/ci-build-artifacts/bd-linux-gms-pure | |
| BEADS_TEST_CMD_BINARY: ${{ github.workspace }}/ci-build-artifacts/bd-cmd-test | |
| run: bash .github/scripts/proxied-test-shard.sh ${{ matrix.shard }} 15 | |
| # Embedded Dolt tests - test the in-process Dolt engine (no server required) | |
| # | |
| # Split into: build → storage tests + parallel cmd test shards. | |
| # cmd/bd embedded tests use a committed shard manifest; newly-added tests | |
| # still auto-distribute via hash fallback until the manifest is updated. | |
| build-embedded: | |
| name: Build (Embedded Dolt) | |
| needs: detect-ci-tier | |
| if: needs.detect-ci-tier.outputs.full_embedded == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6 | |
| - name: Set up Go | |
| id: setup-go | |
| uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 | |
| with: | |
| go-version-file: 'go.mod' | |
| cache: false | |
| - name: Restore Go module cache | |
| id: restore-go-module-cache | |
| uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | |
| with: | |
| path: ~/go/pkg/mod | |
| key: beads-go-mod-v2-${{ runner.os }}-${{ runner.arch }}-go-${{ steps.setup-go.outputs.go-version }}-${{ hashFiles('go.mod', 'go.sum') }} | |
| restore-keys: beads-go-mod-v2-${{ runner.os }}-${{ runner.arch }}-go-${{ steps.setup-go.outputs.go-version }}- | |
| - name: Restore race Go build cache | |
| id: restore-race-go-build-cache | |
| uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | |
| with: | |
| path: ${{ runner.temp }}/go-cache/race | |
| key: beads-go-build-v2-${{ runner.os }}-${{ runner.arch }}-go-${{ steps.setup-go.outputs.go-version }}-base-gms_pure_go-race-${{ github.sha }} | |
| restore-keys: beads-go-build-v2-${{ runner.os }}-${{ runner.arch }}-go-${{ steps.setup-go.outputs.go-version }}-base-gms_pure_go-race- | |
| - name: Build embedded bd binary | |
| env: | |
| GOCACHE: ${{ runner.temp }}/go-cache/race | |
| run: go build -tags gms_pure_go -race -o /tmp/bd-embedded-test ./cmd/bd/ | |
| - name: Build embedded storage test binary | |
| env: | |
| GOCACHE: ${{ runner.temp }}/go-cache/race | |
| run: go test -tags gms_pure_go -race -c -o /tmp/embeddeddolt-test ./internal/storage/embeddeddolt/ | |
| - name: Build embedded cmd test binary | |
| env: | |
| GOCACHE: ${{ runner.temp }}/go-cache/race | |
| run: go test -tags gms_pure_go -race -c -o /tmp/bd-cmd-test ./cmd/bd/ | |
| - name: Upload binaries | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: embedded-test-binaries | |
| path: | | |
| /tmp/bd-embedded-test | |
| /tmp/embeddeddolt-test | |
| /tmp/bd-cmd-test | |
| retention-days: 1 | |
| - name: Save race Go build cache | |
| if: steps.restore-race-go-build-cache.outputs.cache-hit != 'true' | |
| uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | |
| with: | |
| path: ${{ runner.temp }}/go-cache/race | |
| key: beads-go-build-v2-${{ runner.os }}-${{ runner.arch }}-go-${{ steps.setup-go.outputs.go-version }}-base-gms_pure_go-race-${{ github.sha }} | |
| test-embedded-storage: | |
| name: Test (Embedded Dolt Storage ${{ matrix.shard }}/${{ strategy.job-total }}) | |
| needs: [detect-ci-tier, build-embedded] | |
| if: needs.detect-ci-tier.outputs.full_embedded == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| shard: [1, 2, 3, 4, 5] | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6 | |
| - name: Download binaries | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| name: embedded-test-binaries | |
| path: /tmp/ | |
| - name: Fix permissions | |
| run: chmod +x /tmp/embeddeddolt-test | |
| - name: Configure Git | |
| run: | | |
| git config --global user.name "CI Bot" | |
| git config --global user.email "ci@beads.test" | |
| - name: Test | |
| env: | |
| BEADS_TEST_EMBEDDED_DOLT: "1" | |
| BEADS_TEST_EMBEDDED_TEST_BINARY: /tmp/embeddeddolt-test | |
| # Manifest-driven shard of the storage suite (mirrors test-embedded-cmd | |
| # / embedded-test-shard.sh). Conformance runs separately in the | |
| # dedicated test-embedded-conformance job below (mirrors pr-risk.yml); | |
| # embedded-storage-test-shard.sh excludes TestConformance from | |
| # discovery, so it never lands in one of these shards. | |
| run: bash .github/scripts/embedded-storage-test-shard.sh ${{ matrix.shard }} 5 | |
| test-embedded-conformance: | |
| name: Test (Embedded Dolt Conformance - ${{ matrix.partition }}) | |
| needs: [detect-ci-tier, build-embedded] | |
| if: needs.detect-ci-tier.outputs.full_embedded == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 35 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| partition: [core, audit] | |
| env: | |
| BEADS_TEST_EMBEDDED_DOLT: "1" | |
| BEADS_TEST_EMBEDDED_TEST_BINARY: /tmp/embeddeddolt-test | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6 | |
| - name: Download binaries | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| name: embedded-test-binaries | |
| path: /tmp/ | |
| - name: Fix permissions | |
| run: chmod +x /tmp/embeddeddolt-test | |
| - name: Configure Git | |
| run: | | |
| git config --global user.name "CI Bot" | |
| git config --global user.email "ci@beads.test" | |
| - name: Test core conformance | |
| if: matrix.partition == 'core' | |
| # RunAll has a natural Audit seam. Run everything except Audit in the | |
| # core shard and Audit alone in the other shard. The combined suite has | |
| # exceeded 30m under runner variance; each half currently takes ~15m. | |
| # Keep the Go timeout below the job timeout so a real stall still emits | |
| # a diagnostic goroutine dump before Actions stops the job. | |
| run: /tmp/embeddeddolt-test -test.v -test.count=1 -test.timeout=30m -test.run '^TestConformance$' -test.skip '^TestConformance$/^Audit$' | |
| - name: Test audit conformance | |
| if: matrix.partition == 'audit' | |
| run: /tmp/embeddeddolt-test -test.v -test.count=1 -test.timeout=30m -test.run '^TestConformance$/^Audit$' | |
| test-embedded-cmd: | |
| name: Test (Embedded Dolt Cmd ${{ matrix.shard }}/${{ strategy.job-total }}) | |
| needs: [detect-ci-tier, build-embedded] | |
| if: needs.detect-ci-tier.outputs.full_embedded == 'true' | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| shard: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6 | |
| - name: Download binaries | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| name: embedded-test-binaries | |
| path: /tmp/ | |
| - name: Fix permissions | |
| run: chmod +x /tmp/bd-embedded-test /tmp/embeddeddolt-test /tmp/bd-cmd-test | |
| - name: Configure Git | |
| run: | | |
| git config --global user.name "CI Bot" | |
| git config --global user.email "ci@beads.test" | |
| - name: Test | |
| env: | |
| BEADS_TEST_EMBEDDED_DOLT: "1" | |
| BEADS_TEST_BD_BINARY: /tmp/bd-embedded-test | |
| run: bash .github/scripts/embedded-test-shard.sh ${{ matrix.shard }} 20 | |
| # Windows smoke tests only - full test suite times out (see bd-bmev) | |
| # Linux/macOS run comprehensive tests; Windows just verifies binary works | |
| # | |
| # Windows uses -tags gms_pure_go to avoid the ICU regex dependency. | |
| # go-icu-regex's regex_windows.go also uses Go stdlib regexp (build tag: windows). | |
| # CGO is still required for gozstd (bundled C source) and the embedded dolt engine. | |
| test-windows: | |
| name: Test (Windows - smoke) | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| runs-on: windows-latest | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6 | |
| - name: Set up Go | |
| id: setup-go | |
| uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 | |
| with: | |
| go-version-file: 'go.mod' | |
| cache: false | |
| - name: Restore Go module cache | |
| id: restore-go-module-cache | |
| uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | |
| with: | |
| path: ~/go/pkg/mod | |
| key: beads-go-mod-v2-${{ runner.os }}-${{ runner.arch }}-go-${{ steps.setup-go.outputs.go-version }}-${{ hashFiles('go.mod', 'go.sum') }} | |
| restore-keys: beads-go-mod-v2-${{ runner.os }}-${{ runner.arch }}-go-${{ steps.setup-go.outputs.go-version }}- | |
| - name: Restore non-race Go build cache | |
| id: restore-non-race-go-build-cache | |
| uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | |
| with: | |
| path: ${{ runner.temp }}/go-cache/non-race | |
| key: beads-go-build-v2-${{ runner.os }}-${{ runner.arch }}-go-${{ steps.setup-go.outputs.go-version }}-base-gms_pure_go-non-race-${{ github.sha }} | |
| restore-keys: beads-go-build-v2-${{ runner.os }}-${{ runner.arch }}-go-${{ steps.setup-go.outputs.go-version }}-base-gms_pure_go-non-race- | |
| - name: Configure Git | |
| run: | | |
| git config --global user.name "CI Bot" | |
| git config --global user.email "ci@beads.test" | |
| - name: Build (pure Go regex) | |
| env: | |
| GOCACHE: ${{ runner.temp }}/go-cache/non-race | |
| run: go build -v -tags gms_pure_go -o bd.exe ./cmd/bd | |
| - name: Smoke test - version | |
| run: ./bd.exe version | |
| - name: Smoke test - help | |
| run: ./bd.exe help | |
| - name: Save Go module cache | |
| if: steps.restore-go-module-cache.outputs.cache-hit != 'true' | |
| uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | |
| with: | |
| path: ~/go/pkg/mod | |
| key: beads-go-mod-v2-${{ runner.os }}-${{ runner.arch }}-go-${{ steps.setup-go.outputs.go-version }}-${{ hashFiles('go.mod', 'go.sum') }} | |
| - name: Save non-race Go build cache | |
| if: steps.restore-non-race-go-build-cache.outputs.cache-hit != 'true' | |
| uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | |
| with: | |
| path: ${{ runner.temp }}/go-cache/non-race | |
| key: beads-go-build-v2-${{ runner.os }}-${{ runner.arch }}-go-${{ steps.setup-go.outputs.go-version }}-base-gms_pure_go-non-race-${{ github.sha }} | |
| fmt-check: | |
| name: Check formatting | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6 | |
| - name: Set up Go | |
| uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 | |
| with: | |
| go-version-file: 'go.mod' | |
| cache: false | |
| - name: Check gofmt | |
| run: make fmt-check | |
| # The whole-tree lint sweep. pr.yml's job of the same name reports only what | |
| # a PR introduces, so this push lane is where a pre-existing or newly landed | |
| # issue anywhere in the tree surfaces. | |
| lint: | |
| name: Lint | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6 | |
| - name: Set up Go | |
| uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 | |
| with: | |
| go-version-file: 'go.mod' | |
| cache: false | |
| - name: golangci-lint | |
| uses: golangci/golangci-lint-action@ba0d7d2ec06a0ea1cb5fa41b2e4a3ab91d21278a # v9 | |
| env: | |
| GOWORK: "off" | |
| with: | |
| version: v2.10.1 | |
| args: --config=.golangci.yml --modules-download-mode=readonly --timeout=5m --build-tags=gms_pure_go | |
| test-nix: | |
| name: Test Nix Flake | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6 | |
| - uses: DeterminateSystems/determinate-nix-action@61cbfe2efc2d4e7a8a6d56967c3c1058e846c858 # v3 | |
| - name: Run bd help via Nix | |
| id: nix_help | |
| run: | | |
| nix run .#default -- --help > help.txt | |
| - name: Verify help text | |
| if: steps.nix_help.outcome == 'success' | |
| run: | | |
| FIRST_LINE=$(head -n 1 help.txt) | |
| EXPECTED="Issues chained together like beads. A lightweight issue tracker with first-class dependency support." | |
| if [ "$FIRST_LINE" != "$EXPECTED" ]; then | |
| echo "First line of help.txt doesn't match expected output" | |
| echo "Expected: $EXPECTED" | |
| echo "Got: $FIRST_LINE" | |
| exit 1 | |
| fi | |
| echo "Help text first line is correct" |