diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..d60dcf2 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,72 @@ +version: 2 + +updates: + # Keep GitHub Actions SHAs up to date. + # Dependabot will open PRs to update pinned commit SHAs whenever a new + # version tag is published, preserving the SHA-pinning security posture + # while still receiving upstream updates. + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + day: "monday" + commit-message: + prefix: "chore(deps)" + labels: + - "dependencies" + - "ci" + + # Keep npm dependencies up to date for comebackhere-frontend. + - package-ecosystem: "npm" + directory: "/comebackhere-frontend" + schedule: + interval: "weekly" + day: "monday" + commit-message: + prefix: "chore(deps)" + labels: + - "dependencies" + + # Keep npm dependencies up to date for comebackhere-backend. + - package-ecosystem: "npm" + directory: "/comebackhere-backend" + schedule: + interval: "weekly" + day: "monday" + commit-message: + prefix: "chore(deps)" + labels: + - "dependencies" + + # Keep npm dependencies up to date for frontend. + - package-ecosystem: "npm" + directory: "/frontend" + schedule: + interval: "weekly" + day: "monday" + commit-message: + prefix: "chore(deps)" + labels: + - "dependencies" + + # Keep Cargo dependencies up to date for the contracts tree. + - package-ecosystem: "cargo" + directory: "/contracts" + schedule: + interval: "weekly" + day: "monday" + commit-message: + prefix: "chore(deps)" + labels: + - "dependencies" + + # Keep Cargo dependencies up to date for the COMEBACKHERE-contracts tree. + - package-ecosystem: "cargo" + directory: "/COMEBACKHERE-contracts" + schedule: + interval: "weekly" + day: "monday" + commit-message: + prefix: "chore(deps)" + labels: + - "dependencies" diff --git a/.github/workflows/backend-tests.yml b/.github/workflows/backend-tests.yml index 28d8c60..5c12b2c 100644 --- a/.github/workflows/backend-tests.yml +++ b/.github/workflows/backend-tests.yml @@ -3,40 +3,44 @@ name: Backend Tests on: pull_request: branches: [main] + workflow_call: # called by ci-summary.yml permissions: contents: read jobs: + # ── Rust backend (backend/) ───────────────────────────────────────────── unit: + name: rust / unit tests (contracts/) runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: dtolnay/rust-toolchain@stable + - uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 # stable with: toolchain: stable - - uses: actions/cache@v4 + - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 with: path: ~/.cargo/registry key: cargo-registry-${{ hashFiles('**/Cargo.lock') }} restore-keys: cargo-registry- - - uses: actions/cache@v4 + - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 with: path: contracts/target key: cargo-target-${{ hashFiles('**/Cargo.lock') }}-${{ runner.os }} restore-keys: cargo-target- - - name: Run unit tests + - name: Run unit tests (Rust backend) run: cargo test -p comebackhere-invoice working-directory: contracts integration: + name: rust / integration tests (contracts/) runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Start Soroban sandbox run: docker compose up -d soroban @@ -50,22 +54,54 @@ jobs: sleep 3 done - - uses: dtolnay/rust-toolchain@stable + - uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 # stable with: toolchain: stable - - uses: actions/cache@v4 + - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 with: path: ~/.cargo/registry key: cargo-registry-${{ hashFiles('**/Cargo.lock') }} restore-keys: cargo-registry- - - uses: actions/cache@v4 + - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 with: path: contracts/target key: cargo-target-${{ hashFiles('**/Cargo.lock') }}-${{ runner.os }} restore-keys: cargo-target- - - name: Run API integration tests + - name: Run API integration tests (Rust backend) run: cargo test -p api-integration-tests -- --test-threads=1 working-directory: contracts + + # ── TypeScript backend (comebackhere-backend/) ───────────────────────── + # Previously missing: this job covers the Node/TS backend tree that was + # not exercised by the original workflow. Fixes #493. + ts-backend: + name: typescript / unit tests (comebackhere-backend/) + runs-on: ubuntu-latest + defaults: + run: + working-directory: comebackhere-backend + + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 + with: + node-version: 20 + + - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 + with: + path: comebackhere-backend/node_modules + key: node-modules-ts-backend-${{ runner.os }}-${{ hashFiles('comebackhere-backend/package-lock.json') }} + restore-keys: node-modules-ts-backend- + + - name: Install dependencies + run: npm ci + + - name: Type check + run: npx tsc --noEmit + + - name: Run tests + run: npm test diff --git a/.github/workflows/ci-abi-metadata.yml b/.github/workflows/ci-abi-metadata.yml index ea6e786..46e1dc6 100644 --- a/.github/workflows/ci-abi-metadata.yml +++ b/.github/workflows/ci-abi-metadata.yml @@ -5,6 +5,7 @@ on: branches: [main] paths: - 'COMEBACKHERE-contracts/contracts/**' + workflow_call: # called by ci-summary.yml permissions: contents: read @@ -15,17 +16,17 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: repository: WHEELBACK/COMEBACKHERE-contracts ref: main path: COMEBACKHERE-contracts - - uses: actions-rust-lang/setup-rust-toolchain@v1 + - uses: actions-rust-lang/setup-rust-toolchain@9399c7bb15d4c7d47b27263d024f0a4978346ba4 # v1.11.0 - - uses: actions/cache@v4 + - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 with: path: | ~/.cargo/registry @@ -35,7 +36,7 @@ jobs: restore-keys: | ${{ runner.os }}-cargo-abi-meta- - - uses: actions/setup-python@v5 + - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 with: python-version: '3.12' diff --git a/.github/workflows/ci-abi-snapshots.yml b/.github/workflows/ci-abi-snapshots.yml index eabd289..bbcc2b5 100644 --- a/.github/workflows/ci-abi-snapshots.yml +++ b/.github/workflows/ci-abi-snapshots.yml @@ -3,6 +3,7 @@ name: CI - ABI Snapshots on: pull_request: branches: [main] + workflow_call: # called by ci-summary.yml jobs: check-abi: @@ -10,17 +11,17 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: repository: WHEELBACK/COMEBACKHERE-contracts ref: main path: COMEBACKHERE-contracts - - uses: actions-rust-lang/setup-rust-toolchain@v1 + - uses: actions-rust-lang/setup-rust-toolchain@9399c7bb15d4c7d47b27263d024f0a4978346ba4 # v1.11.0 - - uses: actions/cache@v4 + - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 with: path: | ~/.cargo/registry @@ -30,7 +31,7 @@ jobs: restore-keys: | ${{ runner.os }}-cargo-abi- - - uses: actions/setup-python@v5 + - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 with: python-version: '3.12' diff --git a/.github/workflows/ci-contracts.yml b/.github/workflows/ci-contracts.yml index 97f4049..bc9307b 100644 --- a/.github/workflows/ci-contracts.yml +++ b/.github/workflows/ci-contracts.yml @@ -3,6 +3,11 @@ name: CI - Contracts on: pull_request: branches: [main] + paths: + - 'COMEBACKHERE-contracts/**' + - 'contracts/**' + - 'abis/**' + workflow_call: # called by ci-summary.yml jobs: test: @@ -13,15 +18,15 @@ jobs: working-directory: COMEBACKHERE-contracts steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: repository: WHEELBACK/COMEBACKHERE-contracts ref: main path: COMEBACKHERE-contracts - - uses: actions-rust-lang/setup-rust-toolchain@v1 + - uses: actions-rust-lang/setup-rust-toolchain@9399c7bb15d4c7d47b27263d024f0a4978346ba4 # v1.11.0 - - uses: actions/cache@v4 + - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 with: path: | ~/.cargo/registry diff --git a/.github/workflows/ci-coverage.yml b/.github/workflows/ci-coverage.yml index 545ca2f..0243ab3 100644 --- a/.github/workflows/ci-coverage.yml +++ b/.github/workflows/ci-coverage.yml @@ -3,6 +3,7 @@ name: CI - Contract Coverage on: pull_request: branches: [main] + workflow_call: # called by ci-summary.yml permissions: contents: read @@ -20,20 +21,20 @@ jobs: working-directory: COMEBACKHERE-contracts steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: repository: WHEELBACK/COMEBACKHERE-contracts ref: main path: COMEBACKHERE-contracts - - uses: actions-rust-lang/setup-rust-toolchain@v1 + - uses: actions-rust-lang/setup-rust-toolchain@9399c7bb15d4c7d47b27263d024f0a4978346ba4 # v1.11.0 - name: Install cargo-llvm-cov - uses: taiki-e/install-action@v2 + uses: taiki-e/install-action@e03236526ace47fa2e04bebcfc6da471ebd4690c # v2.49.0 with: tool: cargo-llvm-cov - - uses: actions/cache@v4 + - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 with: path: | ~/.cargo/registry @@ -68,7 +69,7 @@ jobs: 'BEGIN { if (p+0 < t+0) { print "FAIL: coverage below threshold"; exit 1 } }' - name: Upload coverage artifacts - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: coverage-report path: | @@ -77,7 +78,7 @@ jobs: - name: Post coverage comment if: github.event_name == 'pull_request' - uses: actions/github-script@v7 + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 with: script: | const pct = '${{ steps.cov.outputs.pct }}'; diff --git a/.github/workflows/ci-error-docs.yml b/.github/workflows/ci-error-docs.yml index c926709..3252eb9 100644 --- a/.github/workflows/ci-error-docs.yml +++ b/.github/workflows/ci-error-docs.yml @@ -9,6 +9,7 @@ on: - 'docs/error-codes.md' - 'scripts/check_error_docs_sync.sh' - '.github/workflows/ci-error-docs.yml' + workflow_call: # called by ci-summary.yml permissions: contents: read @@ -19,7 +20,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Verify contract error variants are documented run: ./scripts/check_error_docs_sync.sh diff --git a/.github/workflows/ci-post-deploy-verify.yml b/.github/workflows/ci-post-deploy-verify.yml index 99c423c..e03f7cb 100644 --- a/.github/workflows/ci-post-deploy-verify.yml +++ b/.github/workflows/ci-post-deploy-verify.yml @@ -25,17 +25,17 @@ jobs: if: github.event_name == 'workflow_dispatch' steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: repository: WHEELBACK/COMEBACKHERE-contracts ref: main path: COMEBACKHERE-contracts - - uses: actions-rust-lang/setup-rust-toolchain@v1 + - uses: actions-rust-lang/setup-rust-toolchain@9399c7bb15d4c7d47b27263d024f0a4978346ba4 # v1.11.0 - - uses: actions/cache@v4 + - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 with: path: | ~/.cargo/registry @@ -67,17 +67,17 @@ jobs: needs: deploy-testnet steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: repository: WHEELBACK/COMEBACKHERE-contracts ref: main path: COMEBACKHERE-contracts - - uses: actions-rust-lang/setup-rust-toolchain@v1 + - uses: actions-rust-lang/setup-rust-toolchain@9399c7bb15d4c7d47b27263d024f0a4978346ba4 # v1.11.0 - - uses: actions/cache@v4 + - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 with: path: | ~/.cargo/registry @@ -107,7 +107,7 @@ jobs: needs: verify steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Run export_deployed_addresses.sh env: @@ -118,7 +118,7 @@ jobs: run: ./scripts/export_deployed_addresses.sh - name: Upload addresses artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: deployed-addresses-${{ github.event.inputs.network }} path: artifacts/addresses.json diff --git a/.github/workflows/ci-summary.yml b/.github/workflows/ci-summary.yml new file mode 100644 index 0000000..0deb22c --- /dev/null +++ b/.github/workflows/ci-summary.yml @@ -0,0 +1,75 @@ +name: CI Summary + +# This workflow is the single required status check for branch protection. +# It depends on every other CI workflow via `needs:` so that a single check +# (ci-summary / all-checks-passed) is all that must be listed in branch +# protection rules. When a new workflow is added, add its job name here +# rather than touching branch protection settings. + +on: + pull_request: + branches: [main] + +jobs: + # ── Re-usable fans-in ────────────────────────────────────────────────── + # Each entry below mirrors a job from one of the ci-*.yml / lint-docs.yml + # workflows. GitHub requires that the jobs listed in `needs:` live in the + # *same* workflow file, so we use a lightweight call-workflow pattern: + # each leaf workflow exposes a reusable workflow_call trigger and this file + # calls them, then a single aggregator job depends on all of them. + # + # If the upstream workflows do not yet expose workflow_call, the aggregator + # is still useful as a single named check — the individual jobs below can + # be replaced with `uses:` calls once those workflows are updated. + + ci-frontend: + name: ci / frontend build-and-lint + uses: ./.github/workflows/ci.yml + + ci-contracts: + name: ci / contract tests + uses: ./.github/workflows/ci-contracts.yml + + ci-abi-metadata: + name: ci / abi metadata + uses: ./.github/workflows/ci-abi-metadata.yml + + ci-abi-snapshots: + name: ci / abi snapshots + uses: ./.github/workflows/ci-abi-snapshots.yml + + ci-coverage: + name: ci / contract coverage + uses: ./.github/workflows/ci-coverage.yml + + ci-error-docs: + name: ci / error docs sync + uses: ./.github/workflows/ci-error-docs.yml + + ci-backend-tests: + name: ci / backend tests + uses: ./.github/workflows/backend-tests.yml + + ci-lint-docs: + name: ci / lint docs + uses: ./.github/workflows/lint-docs.yml + + # ── Aggregator ──────────────────────────────────────────────────────── + # This is the *only* job that needs to be listed in branch protection + # required status checks. Its name is intentionally stable — rename the + # leaf workflows above freely without touching branch protection settings. + all-checks-passed: + name: all-checks-passed + runs-on: ubuntu-latest + needs: + - ci-frontend + - ci-contracts + - ci-abi-metadata + - ci-abi-snapshots + - ci-coverage + - ci-error-docs + - ci-backend-tests + - ci-lint-docs + steps: + - name: All CI checks passed + run: echo "All required CI checks passed." diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1208463..eeb1fef 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,6 +3,7 @@ name: CI on: pull_request: branches: [main] + workflow_call: # called by ci-summary.yml jobs: build-and-lint: @@ -13,16 +14,16 @@ jobs: working-directory: comebackhere-frontend steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Setup Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: 20 - name: Cache node_modules id: cache-node-modules - uses: actions/cache@v4 + uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 with: path: comebackhere-frontend/node_modules key: node-modules-${{ runner.os }}-${{ hashFiles('comebackhere-frontend/package-lock.json') }} diff --git a/.github/workflows/lint-docs.yml b/.github/workflows/lint-docs.yml index 123a7a7..8e006f9 100644 --- a/.github/workflows/lint-docs.yml +++ b/.github/workflows/lint-docs.yml @@ -3,6 +3,7 @@ name: Lint Docs on: pull_request: branches: [main] + workflow_call: # called by ci-summary.yml permissions: contents: read @@ -13,10 +14,10 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Setup Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: 20 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 94184e4..e9d4076 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -57,13 +57,23 @@ The `main` branch is protected. Direct pushes are not allowed; all changes must ### Required status checks -All of the following checks must pass before a PR can be merged: - -- `contract-build` — Soroban contract compilation -- `contract-tests` — contract unit and integration tests -- `abi-snapshot-hygiene` — ABI metadata in `abis/` is consistent with contract source -- `markdown-lint` — documentation linting -- `frontend-build` — frontend build succeeds +Only **one** check must be listed in branch protection: **`all-checks-passed`** +(from `.github/workflows/ci-summary.yml`). + +That workflow fans in every other CI workflow via `needs:`, so a single green +check means all of the following have passed: + +- `ci / frontend build-and-lint` — TypeScript type check, lint, and build +- `ci / contract tests` — Soroban contract compilation and unit tests +- `ci / abi metadata` — ABI metadata consistent with contract source +- `ci / abi snapshots` — ABI snapshot files are up to date +- `ci / contract coverage` — contract line coverage above threshold +- `ci / error docs sync` — error-code variants are all documented +- `ci / backend tests` — Rust and TypeScript backend test suites +- `ci / lint docs` — Markdown documentation linting + +When adding a new workflow, wire it into `ci-summary.yml` rather than +adding it directly to branch protection. ### Required reviews