Harden paid wallet setup failures #634
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: | |
| branches: [main] | |
| jobs: | |
| build-and-test: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| pull-requests: read | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| node-version: [24.x] | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| fetch-depth: 0 | |
| - uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6 | |
| - name: Use Node.js ${{ matrix.node-version }} | |
| uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 | |
| with: | |
| node-version: ${{ matrix.node-version }} | |
| cache: pnpm | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Check cross-package version references | |
| # Non-blocking. Multi-package patch PRs (one bump touches several packages whose | |
| # downstream deps can't reference the new versions until publish) will always | |
| # report stale refs in CI. Sync-versions.mjs runs at release time to reconcile. | |
| continue-on-error: true | |
| run: node scripts/check-versions.mjs | |
| - name: Check @bsv/sdk peer-dependency contract | |
| # Blocking. Published packages/** libraries must declare @bsv/sdk as a | |
| # peerDependency (wide range), never a regular dependency — duplicate SDK | |
| # copies become incompatible nominal types for downstream consumers. | |
| run: node scripts/check-sdk-peer.mjs | |
| - name: Determine changed scope | |
| # On PRs, restrict build/lint/test to packages with changes (plus dependents) | |
| # via pnpm's `...[BASE]` filter. Push events run the full matrix. | |
| id: scope | |
| run: | | |
| if [ "${{ github.event_name }}" = "pull_request" ]; then | |
| BASE_SHA="${{ github.event.pull_request.base.sha }}" | |
| echo "filter=...[${BASE_SHA}]" >> "$GITHUB_OUTPUT" | |
| CHANGED=$(git diff --name-only "${BASE_SHA}"...HEAD) | |
| if echo "$CHANGED" | grep -q '^packages/sdk/'; then | |
| echo "sdk=true" >> "$GITHUB_OUTPUT" | |
| fi | |
| if echo "$CHANGED" | grep -q '^packages/helpers/did/'; then | |
| echo "did=true" >> "$GITHUB_OUTPUT" | |
| fi | |
| else | |
| echo "filter=" >> "$GITHUB_OUTPUT" | |
| echo "sdk=true" >> "$GITHUB_OUTPUT" | |
| echo "did=true" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Build changed packages | |
| # Build the FULL workspace (not just the changed scope): a changed | |
| # package's workspace dependencies must have their built dist present | |
| # for tsc to resolve them, but those dependencies are not part of the | |
| # `...[BASE]` changed+dependents scope. This matches the push-event | |
| # build (which already builds everything). Lint/test stay scoped below. | |
| # Exclude: workspace root (delegating script) and example-paymail (example package, not production) | |
| run: | | |
| pnpm -r --filter '!@bsv/ts-stack' --filter '!example-paymail' run build | |
| - name: Lint changed packages | |
| continue-on-error: true | |
| env: | |
| SCOPE_FILTER: ${{ steps.scope.outputs.filter }} | |
| run: | | |
| EXTRA="" | |
| if [ -n "$SCOPE_FILTER" ]; then EXTRA="--filter $SCOPE_FILTER"; fi | |
| pnpm -r --filter '!@bsv/ts-stack' $EXTRA run lint --if-present | |
| - name: Warm MongoDB memory-server binary cache | |
| # The mongodb-memory-server tests download+extract the mongod binary on first | |
| # use. When that cold start happens under the parallel `pnpm -r run test` load | |
| # below, the just-extracted binary can still be open for writing when it is | |
| # exec'd, producing `spawn ETXTBSY` and startup timeouts (seen on Node 24). | |
| # Pre-extract the binary serially here so the test step reuses a settled cache. | |
| continue-on-error: true | |
| run: > | |
| pnpm --filter @bsv/overlay-topics exec node --input-type=module -e | |
| "import { MongoMemoryServer } from 'mongodb-memory-server'; const s = await MongoMemoryServer.create({ instance: { launchTimeout: 120000 } }); await s.stop(); console.log('mongodb-memory-server binary cache warmed');" | |
| - name: Test changed packages | |
| # Exclude: workspace root (delegating script) and example-paymail (example package, not production) | |
| env: | |
| SCOPE_FILTER: ${{ steps.scope.outputs.filter }} | |
| run: | | |
| EXTRA="" | |
| if [ -n "$SCOPE_FILTER" ]; then EXTRA="--filter $SCOPE_FILTER"; fi | |
| pnpm -r --filter '!@bsv/ts-stack' --filter '!example-paymail' $EXTRA run test | |
| - name: Generate coverage (sdk) | |
| if: steps.scope.outputs.sdk == 'true' | |
| run: | | |
| pnpm --filter @bsv/sdk run test:coverage | |
| node scripts/normalize-lcov-paths.mjs packages/sdk/coverage/lcov.info packages/sdk | |
| - name: Generate coverage (did) | |
| if: steps.scope.outputs.did == 'true' | |
| run: | | |
| pnpm --filter @bsv/did run test:coverage | |
| node scripts/normalize-lcov-paths.mjs packages/helpers/did/coverage/lcov.info packages/helpers/did | |
| - name: Compose codecov inputs | |
| id: cov | |
| if: steps.scope.outputs.sdk == 'true' || steps.scope.outputs.did == 'true' | |
| run: | | |
| FILES="" | |
| FLAGS="" | |
| if [ "${{ steps.scope.outputs.sdk }}" = "true" ]; then | |
| FILES="packages/sdk/coverage/lcov.info" | |
| FLAGS="sdk" | |
| fi | |
| if [ "${{ steps.scope.outputs.did }}" = "true" ]; then | |
| FILES="${FILES:+$FILES,}packages/helpers/did/coverage/lcov.info" | |
| FLAGS="${FLAGS:+$FLAGS,}did" | |
| fi | |
| echo "files=$FILES" >> "$GITHUB_OUTPUT" | |
| echo "flags=$FLAGS" >> "$GITHUB_OUTPUT" | |
| - name: Upload coverage to Codecov | |
| if: (steps.scope.outputs.sdk == 'true' || steps.scope.outputs.did == 'true') && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) | |
| uses: codecov/codecov-action@e79a6962e0d4c0c17b229090214935d2e33f8354 # v6.0.1 | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| files: ${{ steps.cov.outputs.files }} | |
| flags: ${{ steps.cov.outputs.flags }} | |
| name: ts-stack | |
| slug: bsv-blockchain/ts-stack | |
| # Coverage upload is non-blocking: Codecov CLI GPG-verify/outages must not gate CI. | |
| fail_ci_if_error: false | |
| docs-validate: | |
| name: Docs Site Validation | |
| runs-on: ubuntu-latest | |
| # Run on every PR (cheap and protects the docs site) and on pushes that touch docs | |
| # The build step inside will fail fast on frontmatter or link problems before they reach production | |
| if: github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch' || github.event_name == 'push' | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| fetch-depth: 1 | |
| - uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6 | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 | |
| with: | |
| node-version: 24 | |
| cache: 'pnpm' | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Validate frontmatter + links (docs site) | |
| run: pnpm --filter docs-site validate | |
| # Full `pnpm docs:build` (SSG + pagefind + built-link checks + TypeDoc merge) runs in docs-deploy.yml | |
| # on pushes to main. This job provides fast feedback on every PR that touches docs. | |
| conformance: | |
| name: Conformance Vectors | |
| runs-on: ubuntu-latest | |
| needs: [build-and-test] | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6 | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 | |
| with: | |
| node-version: 24 | |
| cache: pnpm | |
| - run: pnpm install --ignore-scripts | |
| - name: Validate conformance vectors (TS) | |
| run: cd conformance/runner && node src/runner.js --validate-only | |
| - name: Run conformance vectors (TS) | |
| run: cd conformance/runner && node src/runner.js --report ../reports/ts-report.xml | |
| - name: Upload conformance reports | |
| if: always() | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: conformance-report | |
| path: conformance/reports/ | |
| if-no-files-found: ignore | |
| # Published so downstream SDKs can fetch the shared conformance corpus | |
| # and run their own language-specific runners in their own CI. | |
| - name: Publish conformance vectors | |
| if: github.ref == 'refs/heads/main' | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: conformance-vectors | |
| path: conformance/vectors/ | |
| retention-days: 90 |