From 4e172484fd81ad4e9f6ea3c00534750a4ce5445a Mon Sep 17 00:00:00 2001 From: giuseppere Date: Fri, 2 Oct 2026 14:33:40 +0200 Subject: [PATCH 1/2] ci: run the required checks on every PR, name them, and shorten PR invariant runs --- .github/workflows/deploy-contracts.yml | 3 +-- .github/workflows/format-lint-product.yml | 2 +- .github/workflows/push_checking.yml | 9 ++++++++- .github/workflows/release-metadata.yml | 11 ++--------- .github/workflows/secret-scan.yml | 1 + 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/deploy-contracts.yml b/.github/workflows/deploy-contracts.yml index 07588396b..3f6eb2205 100644 --- a/.github/workflows/deploy-contracts.yml +++ b/.github/workflows/deploy-contracts.yml @@ -3,8 +3,6 @@ name: Deploy Contracts and Verify artifacts on: pull_request: branches: [master] - paths: - ["contracts/**", "scripts/**", "deployments/**", "**.sol", "package.json", "bun.lock"] push: branches: [master] paths: @@ -21,6 +19,7 @@ concurrency: jobs: deploy: + name: Deploy Contracts runs-on: ubuntu-latest # Shared across steps. ACCOUNT_* is anvil test account 7 (public test keys, diff --git a/.github/workflows/format-lint-product.yml b/.github/workflows/format-lint-product.yml index da489ef93..e23b81b79 100644 --- a/.github/workflows/format-lint-product.yml +++ b/.github/workflows/format-lint-product.yml @@ -2,7 +2,6 @@ name: Format & Lint on: pull_request: - paths: ['src/**', 'script/**', 'test/**', '**.sol'] permissions: contents: read @@ -17,6 +16,7 @@ concurrency: jobs: check: + name: Format & Lint runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/push_checking.yml b/.github/workflows/push_checking.yml index d873a96c3..3c54f04f7 100644 --- a/.github/workflows/push_checking.yml +++ b/.github/workflows/push_checking.yml @@ -14,7 +14,6 @@ name: Run Solidity Tests on: pull_request: branches: [master] - paths: ["contracts/**", "test/**", "**.sol"] push: branches: [master] paths: ["contracts/**", "test/**", "**.sol"] @@ -145,6 +144,14 @@ jobs: exit 1 fi + # Pull requests run 100 invariant runs per campaign to keep the check short; pushes to + # master keep the ci profile's 300. No seed is fixed, so every run explores new + # sequences. The unit + fuzz leg runs no invariants, so this only affects the invariant + # leg. + if [ "$GITHUB_EVENT_NAME" = "pull_request" ]; then + export FOUNDRY_INVARIANT_RUNS=100 + fi + forge test -vv --summary ${{ matrix.kind.forge_args }} 2>&1 | tee test.log TEST=${PIPESTATUS[0]} diff --git a/.github/workflows/release-metadata.yml b/.github/workflows/release-metadata.yml index 22a13fd2f..dd4b51583 100644 --- a/.github/workflows/release-metadata.yml +++ b/.github/workflows/release-metadata.yml @@ -10,15 +10,6 @@ on: # Includes labeled and unlabeled so adding `deployment-record` re-runs the manifest guard # below. Listing types at all replaces the default set, so the defaults are repeated here. types: [opened, edited, synchronize, reopened, labeled, unlabeled, ready_for_review] - # A pull request touching none of the paths below never starts this workflow, so no job in - # it reports a conclusion on that pull request. Harmless while these are optional checks, - # and the thing to settle before marking any of them required: a required check that never - # reports blocks the merge. - paths: - - "deployments/**" - - ".github/abi-contracts.txt" - - "scripts/js/release-metadata.mjs" - - ".github/workflows/release-metadata.yml" permissions: contents: read @@ -32,6 +23,7 @@ concurrency: jobs: validate: + name: Release Metadata runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -53,6 +45,7 @@ jobs: # reports no conclusion, so making this a required check would leave a correctly labelled # deploy pull request unable to merge. The label is read inside the step instead. live-manifests-unchanged: + name: Live Manifests Unchanged runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/secret-scan.yml b/.github/workflows/secret-scan.yml index 6654e7cab..7e0089fd1 100644 --- a/.github/workflows/secret-scan.yml +++ b/.github/workflows/secret-scan.yml @@ -24,6 +24,7 @@ env: jobs: scan: + name: Secret Scan runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 From 6f3afb1bce3130630bc11b3b42cad748a57c9633 Mon Sep 17 00:00:00 2001 From: giuseppere Date: Mon, 5 Oct 2026 15:05:03 +0200 Subject: [PATCH 2/2] CR: add timeouts + fork limitations --- .github/workflows/deploy-contracts.yml | 6 +++++- .github/workflows/format-lint-product.yml | 4 +++- .github/workflows/publish-prerelease.yml | 4 ++++ .github/workflows/publish-release.yml | 4 ++++ .github/workflows/push_checking.yml | 13 ++++++++++++- .github/workflows/release-metadata.yml | 2 ++ .github/workflows/secret-scan.yml | 6 +++++- .github/workflows/validate-files.yml | 1 + 8 files changed, 36 insertions(+), 4 deletions(-) diff --git a/.github/workflows/deploy-contracts.yml b/.github/workflows/deploy-contracts.yml index 3f6eb2205..ef2defcc9 100644 --- a/.github/workflows/deploy-contracts.yml +++ b/.github/workflows/deploy-contracts.yml @@ -21,6 +21,7 @@ jobs: deploy: name: Deploy Contracts runs-on: ubuntu-latest + timeout-minutes: 30 # Shared across steps. ACCOUNT_* is anvil test account 7 (public test keys, # never valid on a real network) used to run the pipeline. FACTORY_DEPLOYER is @@ -430,8 +431,11 @@ jobs: if: always() run: pkill -f anvil || true + # A pull request from a fork gets a read-only token, so posting would fail this check. - name: Update PR comment - if: always() && github.event_name == 'pull_request' + if: >- + always() && github.event_name == 'pull_request' && + github.event.pull_request.head.repo.full_name == github.repository uses: actions/github-script@v7 env: SECTION: Deploy Contracts diff --git a/.github/workflows/format-lint-product.yml b/.github/workflows/format-lint-product.yml index e23b81b79..a8b7ed2d6 100644 --- a/.github/workflows/format-lint-product.yml +++ b/.github/workflows/format-lint-product.yml @@ -18,6 +18,7 @@ jobs: check: name: Format & Lint runs-on: ubuntu-latest + timeout-minutes: 15 steps: - uses: actions/checkout@v4 with: @@ -64,8 +65,9 @@ jobs: path: '*.log' retention-days: 7 + # A pull request from a fork gets a read-only token, so posting would fail this check. - name: Update PR comment - if: always() + if: always() && github.event.pull_request.head.repo.full_name == github.repository uses: actions/github-script@v7 env: SECTION: Format & Lint diff --git a/.github/workflows/publish-prerelease.yml b/.github/workflows/publish-prerelease.yml index 51d7caf82..3f89e6b5c 100644 --- a/.github/workflows/publish-prerelease.yml +++ b/.github/workflows/publish-prerelease.yml @@ -140,9 +140,13 @@ jobs: # build emits. Preserving `cache/` keeps incremental compile fast. run: rm -rf out/build-info && forge build --sizes + # The ci profile, so the released commit gets the same fuzz and invariant campaign as master. + # Unit tests and invariants run together here, about two hours, so a stuck run stops at three. - name: Run tests + timeout-minutes: 180 env: FOUNDRY_DISABLE_NIGHTLY_WARNING: "1" + FOUNDRY_PROFILE: "ci" run: forge test -vv # pallet-revive genesis, built from the code this tag ships. Unlike deployments.json diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index b55a8f8d4..b7a17234d 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -135,9 +135,13 @@ jobs: # build emits. Preserving `cache/` keeps incremental compile fast. run: rm -rf out/build-info && forge build --sizes + # The ci profile, so the released commit gets the same fuzz and invariant campaign as master. + # Unit tests and invariants run together here, about two hours, so a stuck run stops at three. - name: Run tests + timeout-minutes: 180 env: FOUNDRY_DISABLE_NIGHTLY_WARNING: "1" + FOUNDRY_PROFILE: "ci" run: forge test -vv # pallet-revive genesis, so a chain can carry dotNS from block zero rather than diff --git a/.github/workflows/push_checking.yml b/.github/workflows/push_checking.yml index 3c54f04f7..f65fe10be 100644 --- a/.github/workflows/push_checking.yml +++ b/.github/workflows/push_checking.yml @@ -34,6 +34,7 @@ jobs: if: github.event.action != 'closed' name: ${{ matrix.kind.label }} runs-on: ubuntu-latest + timeout-minutes: ${{ matrix.kind.timeout[github.event_name] }} strategy: # Each matrix kind runs on its own runner so neither has to hold the # other's peak memory. Don't fail-fast: surfacing both shards' results @@ -44,9 +45,13 @@ jobs: - id: unit-fuzz label: Contract Tests (Unit + Fuzz) forge_args: --no-match-contract Invariant --no-match-path 'test/fork/**' + timeout: { pull_request: 30, push: 30 } - id: invariant label: Contract Tests (Invariant) forge_args: --match-contract Invariant --no-match-path 'test/fork/**' + # Pull requests run 100 invariant runs per campaign (about 30 minutes), master 300 + # (about 100 minutes). + timeout: { pull_request: 60, push: 150 } steps: - uses: actions/checkout@v4 with: @@ -213,8 +218,13 @@ jobs: report: name: Report Test Results needs: test - if: always() && github.event_name == 'pull_request' && github.event.action != 'closed' + # A pull request from a fork gets a read-only token, so publishing the reports and the comment + # would fail. + if: >- + always() && github.event_name == 'pull_request' && github.event.action != 'closed' && + github.event.pull_request.head.repo.full_name == github.repository runs-on: ubuntu-latest + timeout-minutes: 10 steps: - uses: actions/checkout@v4 @@ -337,6 +347,7 @@ jobs: cleanup: runs-on: ubuntu-latest + timeout-minutes: 10 if: github.event.action == 'closed' steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/release-metadata.yml b/.github/workflows/release-metadata.yml index dd4b51583..340950a5c 100644 --- a/.github/workflows/release-metadata.yml +++ b/.github/workflows/release-metadata.yml @@ -25,6 +25,7 @@ jobs: validate: name: Release Metadata runs-on: ubuntu-latest + timeout-minutes: 10 steps: - uses: actions/checkout@v4 @@ -47,6 +48,7 @@ jobs: live-manifests-unchanged: name: Live Manifests Unchanged runs-on: ubuntu-latest + timeout-minutes: 10 steps: - uses: actions/checkout@v4 with: diff --git a/.github/workflows/secret-scan.yml b/.github/workflows/secret-scan.yml index 7e0089fd1..922e26ee6 100644 --- a/.github/workflows/secret-scan.yml +++ b/.github/workflows/secret-scan.yml @@ -26,6 +26,7 @@ jobs: scan: name: Secret Scan runs-on: ubuntu-latest + timeout-minutes: 10 steps: - uses: actions/checkout@v4 with: @@ -95,8 +96,11 @@ jobs: retention-days: 7 if-no-files-found: ignore + # A pull request from a fork gets a read-only token, so posting would fail this check. - name: Update PR comment - if: always() && github.event_name == 'pull_request' + if: >- + always() && github.event_name == 'pull_request' && + github.event.pull_request.head.repo.full_name == github.repository uses: actions/github-script@v7 env: SECTION: Secret Scan diff --git a/.github/workflows/validate-files.yml b/.github/workflows/validate-files.yml index 54bd0808c..9a3b12b63 100644 --- a/.github/workflows/validate-files.yml +++ b/.github/workflows/validate-files.yml @@ -22,6 +22,7 @@ jobs: validate: name: File Validation runs-on: ubuntu-latest + timeout-minutes: 10 steps: - uses: actions/checkout@v4