Repository navigation
feat(blog): blog v7 contract and client (elected moderation, action fees, timelines, post tombstones) #1450
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: CI | |
| on: | |
| push: | |
| branches: [master] | |
| # No base-branch filter: every PR gets lint/typecheck/build regardless of its | |
| # target (previously PRs into staging or feature branches ran no CI at all). | |
| pull_request: | |
| concurrency: | |
| group: ci-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| lint: | |
| name: Lint | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| cache: 'npm' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Run ESLint | |
| run: npm run lint | |
| typecheck: | |
| name: Type Check | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| cache: 'npm' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Run TypeScript compiler | |
| run: npx tsc --noEmit | |
| unit: | |
| name: Unit Tests | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| cache: 'npm' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Run Vitest | |
| run: npm run test | |
| browser-components: | |
| name: Browser Component Tests | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| cache: 'npm' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Install Chromium | |
| run: npx playwright install --with-deps chromium | |
| - name: Type check component fixtures | |
| run: npx tsc --noEmit -p e2e/components/tsconfig.json | |
| # Isolated component fixtures simulate service failures; no live network | |
| # credentials or Platform writes are involved in these browser checks. | |
| - name: Run browser component regressions | |
| run: npm run test:components | |
| dead-code: | |
| name: Dead Code (knip) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| cache: 'npm' | |
| - name: Install dependencies | |
| run: npm ci | |
| # Everything knip reports fails the job: unused files, dependencies, | |
| # exports, types and class members. Exports that are only used inside | |
| # their own file are exempt (knip.json: ignoreExportsUsedInFile). | |
| - name: Run knip | |
| run: npx knip | |
| build: | |
| name: Build | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| cache: 'npm' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Build application | |
| run: npm run build | |
| e2e: | |
| name: End-to-End | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| # Only for master-bound changes: the suite runs against the test contracts | |
| # registered from master's schemas (.env.testing), so a PR into staging or | |
| # another branch could pair diverged app code with mismatched contracts. | |
| if: github.event_name != 'pull_request' || github.base_ref == 'master' | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| cache: 'npm' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Resolve Playwright version | |
| id: playwright | |
| run: echo "version=$(node -p "require('@playwright/test/package.json').version")" >> "$GITHUB_OUTPUT" | |
| # Keyed on the resolved @playwright/test version rather than the | |
| # lockfile hash: the browser bundle only changes when Playwright itself | |
| # changes, so unrelated dependency bumps keep reusing cached browsers. | |
| - name: Cache Playwright browsers | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.cache/ms-playwright | |
| key: ${{ runner.os }}-playwright-${{ steps.playwright.outputs.version }} | |
| # Still run on a cache hit: the browser binaries come from the cache but | |
| # the OS-level shared libraries (--with-deps) are not cached. | |
| - name: Install Playwright browsers | |
| run: npx playwright install --with-deps chromium | |
| - name: Build testing bundle | |
| run: npm run build:testing | |
| # Secrets cannot be referenced from `if:`, so surface the seed phrase's | |
| # presence as an env flag. Fork PRs have no secret; the `write` project | |
| # self-skips there and only `smoke` runs. | |
| - name: Detect E2E seed secret | |
| env: | |
| E2E_SEED_PHRASE: ${{ secrets.E2E_SEED_PHRASE }} | |
| run: | | |
| if [ -n "$E2E_SEED_PHRASE" ]; then | |
| echo "HAS_SEED=true" >> "$GITHUB_ENV" | |
| else | |
| echo "HAS_SEED=false" >> "$GITHUB_ENV" | |
| echo "::notice::E2E_SEED_PHRASE unavailable (fork PR?) — running smoke tests only" | |
| fi | |
| # Fails the job with an actionable message when the identity pool is | |
| # depleted, rather than letting the suite die mid-run on a funding error. | |
| - name: Check test identity balances | |
| if: env.HAS_SEED == 'true' | |
| env: | |
| E2E_SEED_PHRASE: ${{ secrets.E2E_SEED_PHRASE }} | |
| run: node scripts/provision-test-identity.mjs --check-balances | |
| # Spread concurrent runs across the 3-identity pool to reduce (not | |
| # eliminate) identity-nonce races; Playwright retries absorb the rest. | |
| - name: Select identity pool slot | |
| run: echo "E2E_IDENTITY_INDEX=$(( GITHUB_RUN_ID % 3 ))" >> "$GITHUB_ENV" | |
| - name: Run Playwright tests | |
| env: | |
| E2E_SEED_PHRASE: ${{ secrets.E2E_SEED_PHRASE }} | |
| run: npx playwright test | |
| - name: Upload Playwright report | |
| if: failure() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: playwright-report | |
| path: | | |
| playwright-report/ | |
| test-results/ | |
| retention-days: 7 | |
| # The devnet interaction topology (v11, on sakura) only exists on the devnet | |
| # contracts, so the specs that assert it can only run there. Every step is continue-on-error for | |
| # the same reason deploy.yml's devnet build is: the devnet is disposable and | |
| # resets without notice, its nodes are a hand-maintained three-machine pool, and | |
| # the bot identities are funded by hand — none of which may block a PR. Read its | |
| # result as a signal, not a gate; a genuine regression reproduces locally. | |
| devnet-e2e: | |
| name: End-to-End (devnet, non-blocking) | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 75 | |
| continue-on-error: true | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| cache: 'npm' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Resolve Playwright version | |
| id: playwright | |
| run: echo "version=$(node -p "require('@playwright/test/package.json').version")" >> "$GITHUB_OUTPUT" | |
| - name: Cache Playwright browsers | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.cache/ms-playwright | |
| key: ${{ runner.os }}-playwright-${{ steps.playwright.outputs.version }} | |
| - name: Install Playwright browsers | |
| run: npx playwright install --with-deps chromium | |
| # BASE_PATH=/devnet, matching the deployed /devnet site, so client-side | |
| # storage is scoped the same way it is in production for that deployment. | |
| - name: Build devnet bundle | |
| continue-on-error: true | |
| run: npm run build:devnet | |
| - name: Detect devnet E2E seed secret | |
| env: | |
| E2E_SEED_PHRASE: ${{ secrets.E2E_DEVNET_SEED_PHRASE }} | |
| run: | | |
| if [ -n "$E2E_SEED_PHRASE" ]; then | |
| echo "HAS_SEED=true" >> "$GITHUB_ENV" | |
| else | |
| echo "HAS_SEED=false" >> "$GITHUB_ENV" | |
| echo "::notice::E2E_DEVNET_SEED_PHRASE unavailable (fork PR?) — skipping the devnet write specs" | |
| fi | |
| # The devnet quorum service cold-starts (~10s) after idle and every SDK | |
| # connect fails until it is warm, so warm it before the run rather than | |
| # burning a retry on it. | |
| - name: Warm the devnet quorum service | |
| continue-on-error: true | |
| run: | | |
| for path in quorums previous masternodes; do | |
| curl -sS -o /dev/null --max-time 60 \ | |
| "https://quorums.sakura.networks.dash.org/$path" || true | |
| done | |
| - name: Run the devnet topology and username entry specs | |
| if: env.HAS_SEED == 'true' | |
| continue-on-error: true | |
| env: | |
| E2E_SEED_PHRASE: ${{ secrets.E2E_DEVNET_SEED_PHRASE }} | |
| E2E_BASE_PATH: /devnet | |
| E2E_ENV_FILE: .env.devnet | |
| NETWORK: devnet | |
| run: npx playwright test --project=write --trace=off topology dpns-username-entry | |
| # SDK connection recovery (read-only, needs no seed). The devnet pool is | |
| # small enough to exhaust within ten failed reads, so exhaustion is | |
| # required here: a pool that never exhausts fails instead of skipping. | |
| # No step-level continue-on-error and no retries, so a failure turns this | |
| # step red (the job-level continue-on-error still keeps it non-blocking) | |
| # instead of passing on a retry. It writes its own report and results, | |
| # which later steps would otherwise overwrite before the upload. | |
| - name: Run the devnet SDK recovery specs | |
| env: | |
| E2E_BASE_PATH: /devnet | |
| E2E_ENV_FILE: .env.devnet | |
| NETWORK: devnet | |
| E2E_REQUIRE_SDK_EXHAUSTION: '1' | |
| PLAYWRIGHT_HTML_OUTPUT_DIR: playwright-report-sdk-recovery | |
| run: npx playwright test --project=smoke --retries=0 --output=test-results-sdk-recovery sdk-offline-recovery | |
| # DM v5 against the real chain with several identities (pool slots 1-5 of the | |
| # same seed, listed in .env.devnet). Only the 1:1 and group files run here | |
| # (about 15 min together); the history (120-message bulk write) and | |
| # lost-state recovery files are local-only, see docs/TESTING.md. | |
| - name: Run the devnet DM v5 specs | |
| if: env.HAS_SEED == 'true' | |
| continue-on-error: true | |
| env: | |
| E2E_SEED_PHRASE: ${{ secrets.E2E_DEVNET_SEED_PHRASE }} | |
| E2E_BASE_PATH: /devnet | |
| E2E_ENV_FILE: .env.devnet | |
| NETWORK: devnet | |
| run: npx playwright test --project=write --trace=off dm-v5-direct dm-v5-groups | |
| - name: Upload Playwright report | |
| if: always() | |
| continue-on-error: true | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: playwright-report-devnet | |
| path: | | |
| playwright-report/ | |
| test-results/ | |
| playwright-report-sdk-recovery/ | |
| test-results-sdk-recovery/ | |
| retention-days: 7 | |
| if-no-files-found: ignore |