diff --git a/.github/workflows/e2e-blockchain-chrome-devnet.yml b/.github/workflows/e2e-blockchain-chrome-devnet.yml new file mode 100644 index 00000000..0bf5f8d9 --- /dev/null +++ b/.github/workflows/e2e-blockchain-chrome-devnet.yml @@ -0,0 +1,121 @@ +name: E2E Blockchain (Chrome, devnet) — Nightly + +# Chrome extension blockchain-backed E2E suite against devnet — NIGHTLY only. +# Push-on-main coverage (with the OR-tolerance gate across both networks) +# lives in `e2e-blockchain-chrome.yml`; this workflow exists per-network +# so the devnet network-monitor card can pin to a single workflow id +# without contention from push runs. Symmetric testnet sibling: +# `e2e-blockchain-chrome-testnet.yml`. + +on: + schedule: + - cron: '0 4 * * *' + workflow_dispatch: {} + +permissions: + contents: read + issues: write # for the schedule-only failure-issue step below + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + chrome-devnet: + name: Chrome E2E (devnet) + runs-on: ubuntu-latest + timeout-minutes: 60 + env: + E2E_NETWORK: devnet + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: 22 + cache: yarn + + # cargo is needed to install miden-client-cli from crates.io on first run. + - uses: dtolnay/rust-toolchain@stable + + - name: Cache miden-client-cli + # Cache key follows the root package.json so a SDK version bump + # (or any other root-level dep change) naturally invalidates — the + # CLI is installed version-matched to @miden-sdk/miden-sdk by + # helpers/miden-cli.ts. + uses: actions/cache@v4 + with: + path: ~/.cargo/bin/miden-client + key: miden-client-cli-${{ runner.os }}-${{ hashFiles('package.json') }} + + - name: Install dependencies + run: yarn install --frozen-lockfile + + # Pre-install the miden-client-cli so the cold-cache ~7 min cargo + # compile happens in its own step, not inside Playwright's 5-min + # per-test timeout. `cargo install` is a no-op on warm cache. + - name: Install miden-client-cli + shell: bash + run: | + VERSION=$(node -p "require('./node_modules/@miden-sdk/miden-sdk/package.json').version") + if [[ -x "$HOME/.cargo/bin/miden-client" ]]; then + echo "miden-client already present from cache:" + "$HOME/.cargo/bin/miden-client" --version || true + else + echo "Installing miden-client-cli@${VERSION}..." + cargo install miden-client-cli --version "$VERSION" + fi + + - name: Install xvfb + run: sudo apt-get update && sudo apt-get install -y xvfb + + - name: Install Playwright browsers + run: npx playwright install --with-deps chromium + + - name: Run blockchain E2E (devnet) + run: xvfb-run -a yarn test:e2e:blockchain:devnet + + - name: Upload artifacts + if: always() + uses: actions/upload-artifact@v4 + with: + name: chrome-e2e-devnet-${{ github.run_id }} + path: test-results/ + retention-days: 7 + if-no-files-found: ignore + + # Auto-create a tracking issue when the SCHEDULED nightly fails. Push + # failures stay visible on the merge commit + Actions tab and don't need + # an issue (PR context already covers them); only the nightly cadence — + # which has no PR context — gets an issue so a red night doesn't rot + # silently. + nightly-failure-issue: + name: Open issue on nightly failure + needs: chrome-devnet + if: failure() && github.event_name == 'schedule' + runs-on: ubuntu-latest + permissions: + issues: write + steps: + - name: Create issue + uses: actions/github-script@v7 + with: + script: | + const runUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`; + const today = new Date().toISOString().slice(0, 10); + const title = `Nightly Chrome E2E (devnet) failed — ${today}`; + const body = [ + `Nightly run [\`${context.runId}\`](${runUrl}) failed on devnet.`, + ``, + `Workflow: \`${context.workflow}\``, + `Commit: \`${context.sha}\``, + ``, + `Auto-created by \`e2e-blockchain-chrome-devnet.yml\` on schedule failure.`, + ].join('\n'); + await github.rest.issues.create({ + owner: context.repo.owner, + repo: context.repo.repo, + title, + body, + labels: ['ci-failure', 'nightly-e2e', 'devnet'], + }); diff --git a/.github/workflows/e2e-blockchain-chrome-testnet.yml b/.github/workflows/e2e-blockchain-chrome-testnet.yml new file mode 100644 index 00000000..a5bd0d97 --- /dev/null +++ b/.github/workflows/e2e-blockchain-chrome-testnet.yml @@ -0,0 +1,113 @@ +name: E2E Blockchain (Chrome, testnet) — Nightly + +# Chrome extension blockchain-backed E2E suite against testnet — NIGHTLY only. +# Push-on-main coverage (with the OR-tolerance gate across both networks) +# lives in `e2e-blockchain-chrome.yml`; this workflow exists per-network +# so the testnet network-monitor card can pin to a single workflow id +# without contention from push runs. Symmetric devnet sibling: +# `e2e-blockchain-chrome-devnet.yml`. + +on: + schedule: + - cron: '0 4 * * *' + workflow_dispatch: {} + +permissions: + contents: read + issues: write # for the schedule-only failure-issue step below + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + chrome-testnet: + name: Chrome E2E (testnet) + runs-on: ubuntu-latest + timeout-minutes: 60 + env: + E2E_NETWORK: testnet + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: 22 + cache: yarn + + - uses: dtolnay/rust-toolchain@stable + + - name: Cache miden-client-cli + uses: actions/cache@v4 + with: + path: ~/.cargo/bin/miden-client + key: miden-client-cli-${{ runner.os }}-${{ hashFiles('package.json') }} + + - name: Install dependencies + run: yarn install --frozen-lockfile + + - name: Install miden-client-cli + shell: bash + run: | + VERSION=$(node -p "require('./node_modules/@miden-sdk/miden-sdk/package.json').version") + if [[ -x "$HOME/.cargo/bin/miden-client" ]]; then + echo "miden-client already present from cache:" + "$HOME/.cargo/bin/miden-client" --version || true + else + echo "Installing miden-client-cli@${VERSION}..." + cargo install miden-client-cli --version "$VERSION" + fi + + - name: Install xvfb + run: sudo apt-get update && sudo apt-get install -y xvfb + + - name: Install Playwright browsers + run: npx playwright install --with-deps chromium + + - name: Run blockchain E2E (testnet) + run: xvfb-run -a yarn test:e2e:blockchain:testnet + + - name: Upload artifacts + if: always() + uses: actions/upload-artifact@v4 + with: + name: chrome-e2e-testnet-${{ github.run_id }} + path: test-results/ + retention-days: 7 + if-no-files-found: ignore + + # Auto-create a tracking issue when the SCHEDULED nightly fails. Push + # failures stay visible on the merge commit + Actions tab and don't need + # an issue (PR context already covers them); only the nightly cadence — + # which has no PR context — gets an issue so a red night doesn't rot + # silently. + nightly-failure-issue: + name: Open issue on nightly failure + needs: chrome-testnet + if: failure() && github.event_name == 'schedule' + runs-on: ubuntu-latest + permissions: + issues: write + steps: + - name: Create issue + uses: actions/github-script@v7 + with: + script: | + const runUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`; + const today = new Date().toISOString().slice(0, 10); + const title = `Nightly Chrome E2E (testnet) failed — ${today}`; + const body = [ + `Nightly run [\`${context.runId}\`](${runUrl}) failed on testnet.`, + ``, + `Workflow: \`${context.workflow}\``, + `Commit: \`${context.sha}\``, + ``, + `Auto-created by \`e2e-blockchain-chrome-testnet.yml\` on schedule failure.`, + ].join('\n'); + await github.rest.issues.create({ + owner: context.repo.owner, + repo: context.repo.repo, + title, + body, + labels: ['ci-failure', 'nightly-e2e', 'testnet'], + }); diff --git a/.github/workflows/e2e-blockchain-chrome.yml b/.github/workflows/e2e-blockchain-chrome.yml new file mode 100644 index 00000000..023b9b92 --- /dev/null +++ b/.github/workflows/e2e-blockchain-chrome.yml @@ -0,0 +1,181 @@ +name: E2E Blockchain (Chrome) — Push + +# Chrome extension blockchain-backed E2E suites against public networks. +# Runs on every push to main. The gate job passes as long as AT LEAST +# ONE network (devnet OR testnet) succeeded — this tolerates short +# windows where wallet@main and a single network are protocol-mismatched +# (e.g. devnet ahead of the pinned SDK version). +# +# This workflow only runs on push. Nightly per-network coverage lives in +# the schedule-only siblings: +# - e2e-blockchain-chrome-devnet.yml +# - e2e-blockchain-chrome-testnet.yml +# +# The split exists because the network-monitor's devnet/testnet +# instances each pin to one schedule-only workflow file; running both +# networks in a single push workflow keeps the merge-gate tolerance the +# team has come to rely on. + +on: + push: + branches: + - main + workflow_dispatch: + inputs: + network: + description: 'Network(s) to test against' + required: false + default: 'both' + type: choice + options: + - both + - devnet + - testnet + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + chrome-devnet: + name: Chrome E2E (devnet) + if: github.event_name != 'workflow_dispatch' || inputs.network == 'both' || inputs.network == 'devnet' + runs-on: ubuntu-latest + timeout-minutes: 60 + env: + E2E_NETWORK: devnet + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: 22 + cache: yarn + + # cargo is needed to install miden-client-cli from crates.io on first run. + - uses: dtolnay/rust-toolchain@stable + + - name: Cache miden-client-cli + # Cache key follows the root package.json so a SDK version bump + # (or any other root-level dep change) naturally invalidates — the + # CLI is installed version-matched to @miden-sdk/miden-sdk by + # helpers/miden-cli.ts. + uses: actions/cache@v4 + with: + path: ~/.cargo/bin/miden-client + key: miden-client-cli-${{ runner.os }}-${{ hashFiles('package.json') }} + + - name: Install dependencies + run: yarn install --frozen-lockfile + + # Pre-install the miden-client-cli so the cold-cache ~7 min cargo + # compile happens in its own step, not inside Playwright's 5-min + # per-test timeout. `cargo install` is a no-op on warm cache. + - name: Install miden-client-cli + shell: bash + run: | + VERSION=$(node -p "require('./node_modules/@miden-sdk/miden-sdk/package.json').version") + if [[ -x "$HOME/.cargo/bin/miden-client" ]]; then + echo "miden-client already present from cache:" + "$HOME/.cargo/bin/miden-client" --version || true + else + echo "Installing miden-client-cli@${VERSION}..." + cargo install miden-client-cli --version "$VERSION" + fi + + - name: Install xvfb + run: sudo apt-get update && sudo apt-get install -y xvfb + + - name: Install Playwright browsers + run: npx playwright install --with-deps chromium + + - name: Run blockchain E2E (devnet) + run: xvfb-run -a yarn test:e2e:blockchain:devnet + + - name: Upload artifacts + if: always() + uses: actions/upload-artifact@v4 + with: + name: chrome-e2e-devnet-${{ github.run_id }} + path: test-results/ + retention-days: 7 + if-no-files-found: ignore + + chrome-testnet: + name: Chrome E2E (testnet) + if: github.event_name != 'workflow_dispatch' || inputs.network == 'both' || inputs.network == 'testnet' + runs-on: ubuntu-latest + timeout-minutes: 60 + env: + E2E_NETWORK: testnet + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: 22 + cache: yarn + + - uses: dtolnay/rust-toolchain@stable + + - name: Cache miden-client-cli + uses: actions/cache@v4 + with: + path: ~/.cargo/bin/miden-client + key: miden-client-cli-${{ runner.os }}-${{ hashFiles('package.json') }} + + - name: Install dependencies + run: yarn install --frozen-lockfile + + - name: Install miden-client-cli + shell: bash + run: | + VERSION=$(node -p "require('./node_modules/@miden-sdk/miden-sdk/package.json').version") + if [[ -x "$HOME/.cargo/bin/miden-client" ]]; then + echo "miden-client already present from cache:" + "$HOME/.cargo/bin/miden-client" --version || true + else + echo "Installing miden-client-cli@${VERSION}..." + cargo install miden-client-cli --version "$VERSION" + fi + + - name: Install xvfb + run: sudo apt-get update && sudo apt-get install -y xvfb + + - name: Install Playwright browsers + run: npx playwright install --with-deps chromium + + - name: Run blockchain E2E (testnet) + run: xvfb-run -a yarn test:e2e:blockchain:testnet + + - name: Upload artifacts + if: always() + uses: actions/upload-artifact@v4 + with: + name: chrome-e2e-testnet-${{ github.run_id }} + path: test-results/ + retention-days: 7 + if-no-files-found: ignore + + chrome-gate: + name: Chrome E2E Gate + needs: [chrome-devnet, chrome-testnet] + if: always() + runs-on: ubuntu-latest + steps: + - name: Require at least one network to pass + shell: bash + env: + DEVNET_RESULT: ${{ needs.chrome-devnet.result }} + TESTNET_RESULT: ${{ needs.chrome-testnet.result }} + run: | + echo "devnet=$DEVNET_RESULT testnet=$TESTNET_RESULT" + if [[ "$DEVNET_RESULT" == "success" || "$TESTNET_RESULT" == "success" ]]; then + echo "Chrome E2E: at least one network passed." + exit 0 + fi + echo "Chrome E2E: both networks failed or were skipped." + exit 1 diff --git a/.github/workflows/e2e-blockchain.yml b/.github/workflows/e2e-blockchain-mobile.yml similarity index 59% rename from .github/workflows/e2e-blockchain.yml rename to .github/workflows/e2e-blockchain-mobile.yml index 8d161e57..8a8a3bbf 100644 --- a/.github/workflows/e2e-blockchain.yml +++ b/.github/workflows/e2e-blockchain-mobile.yml @@ -1,11 +1,14 @@ -name: E2E Blockchain - -# Runs the blockchain-backed E2E suites (Chrome extension + iOS simulator) -# against public networks on every push to main. The per-platform gate jobs -# pass as long as AT LEAST ONE network (devnet OR testnet) succeeded for -# that platform — this tolerates short windows where wallet@main and a -# single network are protocol-mismatched (e.g. devnet ahead of the pinned -# SDK version). +name: E2E Blockchain (Mobile) + +# iOS-simulator blockchain-backed E2E suites against public networks. +# Runs on every push to main. The gate job passes as long as AT LEAST +# ONE network (devnet OR testnet) succeeded — same protocol-mismatch +# tolerance as the Chrome suite. +# +# NOT on schedule: mobile lanes are macOS-runner-bound (~10× the cost +# of the Chrome lanes) and the on-push cadence already gives same-day +# signal. If a nightly mobile cadence is ever wanted, mirror the +# `schedule:` block from `e2e-blockchain-chrome.yml`. on: push: @@ -31,150 +34,6 @@ concurrency: cancel-in-progress: true jobs: - # --- Chrome --------------------------------------------------------------- - - chrome-devnet: - name: Chrome E2E (devnet) - if: github.event_name != 'workflow_dispatch' || inputs.network == 'both' || inputs.network == 'devnet' - runs-on: ubuntu-latest - timeout-minutes: 60 - env: - E2E_NETWORK: devnet - steps: - - uses: actions/checkout@v4 - - - uses: actions/setup-node@v4 - with: - node-version: 22 - cache: yarn - - # cargo is needed to install miden-client-cli from crates.io on first run. - - uses: dtolnay/rust-toolchain@stable - - - name: Cache miden-client-cli - # Cache key follows the root package.json so a SDK version bump - # (or any other root-level dep change) naturally invalidates — the - # CLI is installed version-matched to @miden-sdk/miden-sdk by - # helpers/miden-cli.ts. - uses: actions/cache@v4 - with: - path: ~/.cargo/bin/miden-client - key: miden-client-cli-${{ runner.os }}-${{ hashFiles('package.json') }} - - - name: Install dependencies - run: yarn install --frozen-lockfile - - # Pre-install the miden-client-cli so the cold-cache ~7 min cargo - # compile happens in its own step, not inside Playwright's 5-min - # per-test timeout. `cargo install` is a no-op on warm cache. - - name: Install miden-client-cli - shell: bash - run: | - VERSION=$(node -p "require('./node_modules/@miden-sdk/miden-sdk/package.json').version") - if [[ -x "$HOME/.cargo/bin/miden-client" ]]; then - echo "miden-client already present from cache:" - "$HOME/.cargo/bin/miden-client" --version || true - else - echo "Installing miden-client-cli@${VERSION}..." - cargo install miden-client-cli --version "$VERSION" - fi - - - name: Install xvfb - run: sudo apt-get update && sudo apt-get install -y xvfb - - - name: Install Playwright browsers - run: npx playwright install --with-deps chromium - - - name: Run blockchain E2E (devnet) - run: xvfb-run -a yarn test:e2e:blockchain:devnet - - - name: Upload artifacts - if: always() - uses: actions/upload-artifact@v4 - with: - name: chrome-e2e-devnet-${{ github.run_id }} - path: test-results/ - retention-days: 7 - if-no-files-found: ignore - - chrome-testnet: - name: Chrome E2E (testnet) - if: github.event_name != 'workflow_dispatch' || inputs.network == 'both' || inputs.network == 'testnet' - runs-on: ubuntu-latest - timeout-minutes: 60 - env: - E2E_NETWORK: testnet - steps: - - uses: actions/checkout@v4 - - - uses: actions/setup-node@v4 - with: - node-version: 22 - cache: yarn - - - uses: dtolnay/rust-toolchain@stable - - - name: Cache miden-client-cli - uses: actions/cache@v4 - with: - path: ~/.cargo/bin/miden-client - key: miden-client-cli-${{ runner.os }}-${{ hashFiles('package.json') }} - - - name: Install dependencies - run: yarn install --frozen-lockfile - - - name: Install miden-client-cli - shell: bash - run: | - VERSION=$(node -p "require('./node_modules/@miden-sdk/miden-sdk/package.json').version") - if [[ -x "$HOME/.cargo/bin/miden-client" ]]; then - echo "miden-client already present from cache:" - "$HOME/.cargo/bin/miden-client" --version || true - else - echo "Installing miden-client-cli@${VERSION}..." - cargo install miden-client-cli --version "$VERSION" - fi - - - name: Install xvfb - run: sudo apt-get update && sudo apt-get install -y xvfb - - - name: Install Playwright browsers - run: npx playwright install --with-deps chromium - - - name: Run blockchain E2E (testnet) - run: xvfb-run -a yarn test:e2e:blockchain:testnet - - - name: Upload artifacts - if: always() - uses: actions/upload-artifact@v4 - with: - name: chrome-e2e-testnet-${{ github.run_id }} - path: test-results/ - retention-days: 7 - if-no-files-found: ignore - - chrome-gate: - name: Chrome E2E Gate - needs: [chrome-devnet, chrome-testnet] - if: always() - runs-on: ubuntu-latest - steps: - - name: Require at least one network to pass - shell: bash - env: - DEVNET_RESULT: ${{ needs.chrome-devnet.result }} - TESTNET_RESULT: ${{ needs.chrome-testnet.result }} - run: | - echo "devnet=$DEVNET_RESULT testnet=$TESTNET_RESULT" - if [[ "$DEVNET_RESULT" == "success" || "$TESTNET_RESULT" == "success" ]]; then - echo "Chrome E2E: at least one network passed." - exit 0 - fi - echo "Chrome E2E: both networks failed or were skipped." - exit 1 - - # --- iOS Simulator -------------------------------------------------------- - mobile-devnet: name: Mobile E2E (devnet) if: github.event_name != 'workflow_dispatch' || inputs.network == 'both' || inputs.network == 'devnet'