Skip to content

Commit 9dd5317

Browse files
anacrolixCopilot
andauthored
ci: add CI gate workflow (#19912)
Closes #19909. ## Summary Switches CI from individual per-workflow required checks to a single `CI Gate / ci-gate` aggregator. This is required for clean handling of merge queues and PRs simultaneously — without a gate, there's no single check to require on `merge_group` events, and managing required checks means touching GitHub settings rather than code. The gate currently requires exactly the same jobs that were previously required, so this is a one-to-one transition: - `Lint / lint` - `All tests / tests-mac-linux (ubuntu-24.04, macos-15, windows-2025)` - `All tests (with -race) / ...` - `Test Hive / test-hive (...)` - `Consensus spec / ...` - `Check large files / check` - `Benchmarks / benchmarks` - `Kurtosis Assertoor GitHub Action / assertoor_{regular,pectra}_test` - `Manifest Check / ManifestCheck` - `Reproducible build / reproducible-build (...)` - `QA - RPC Integration Tests (Gnosis) / gnosis-rpc-integ-tests` - `QA - RPC Integration Tests Remote / mainnet-rpc-integ-tests-remote` Each called workflow gains `workflow_call:` and loses its `pull_request:` trigger — the gate owns PR and merge-queue coverage. Standalone `push`, `schedule`, and `workflow_dispatch` triggers are preserved. ## Running different jobs on PR vs merge queue Because the gate triggers on both `pull_request` and `merge_group`, it's now straightforward to run a lighter suite on PRs and the full suite only when merging: ```yaml # ci-gate.yml expensive-job: if: github.event_name == 'merge_group' uses: ./.github/workflows/expensive.yml secrets: inherit ``` The aggregator ignores skipped jobs, so jobs conditional on event type don't block the gate in the other context. This is a follow-up opportunity — for now all jobs run on both. ## How to merge 1. In branch protection for `main`, remove all individual required checks and add `CI Gate / ci-gate` 2. Merge this PR — the gate is now in effect for all subsequent PRs and merge queue entries ## Other changes - Deletes stub workflows `ci.yml`, `test-win-downloader.yml`, `check.yml` - Fixes `event_name`-dependent conditions in `test-hive.yml` and `test-kurtosis-assertoor.yml` - Upgrades `check-large-files.yml` checkout v4→v6 - Adds `workflow_dispatch` to `test-bench.yml` and `test-integration-caplin.yml` - Removes redundant daily schedule from `test-all-erigon.yml` - Documents `workflow_call` vs inline guidance in `.github/README.md` --------- Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: anacrolix <988750+anacrolix@users.noreply.github.com>
1 parent a094862 commit 9dd5317

17 files changed

Lines changed: 159 additions & 203 deletions

.github/README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,30 @@ Without `ready_for_review`, converting a draft PR to ready-for-review fires an e
4040
the workflow doesn't subscribe to, so the job never runs — the PR appears to have
4141
skipped CI until the next push.
4242

43+
### CI gate and workflow_call
44+
45+
All PR and merge-queue checks run through `.github/workflows/ci-gate.yml`. It calls
46+
each sub-workflow via `uses:` (reusable workflow call) rather than inlining the job
47+
definitions. This avoids duplicating job definitions that also appear in standalone
48+
`push`/`schedule` runs.
49+
50+
Use `workflow_call:` on a workflow (and call it from ci-gate) when the workflow has
51+
other triggers besides PRs — `push` to `main`, `schedule`, etc. — so there is one
52+
source of truth for the job definition.
53+
54+
Only inline job definitions directly into ci-gate if the workflow is exclusively
55+
PR-gated with no other triggers, since there is then no duplication concern.
56+
57+
Workflows called by ci-gate must not have `pull_request:` triggers — ci-gate owns
58+
PR coverage and a `pull_request:` trigger would cause every job to run twice.
59+
60+
ci-gate has a workflow-level `concurrency:` group that cancels the entire previous
61+
run (all sub-workflow jobs) when a new PR push or merge_group event arrives. Sub-
62+
workflows called via `workflow_call` must **not** define their own job-level
63+
`concurrency:` for this purpose — `github.workflow` and `github.job` resolve to
64+
the caller's values (or empty) in a `workflow_call` context, which causes collisions
65+
that cancel sibling jobs within the same run.
66+
4367
### Required checks and path filters
4468

4569
Required checks must always report a status or they block the PR indefinitely.

.github/workflows/check-large-files.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
name: Check large files
22

3-
on: pull_request
3+
on:
4+
workflow_dispatch:
5+
workflow_call:
46

57
defaults:
68
run:
@@ -10,7 +12,7 @@ jobs:
1012
check:
1113
runs-on: ubuntu-24.04
1214
steps:
13-
- uses: actions/checkout@v4
15+
- uses: actions/checkout@v6
1416
with:
1517
fetch-depth: 0
1618
filter: blob:none

.github/workflows/check.yml

Lines changed: 0 additions & 15 deletions
This file was deleted.

.github/workflows/ci-gate.yml

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
name: CI Gate
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- main
7+
- 'release/**'
8+
types:
9+
- opened
10+
- reopened
11+
- synchronize
12+
- ready_for_review
13+
push:
14+
branches:
15+
- main
16+
- 'release/**'
17+
merge_group:
18+
workflow_dispatch:
19+
20+
concurrency:
21+
# For PRs: one run per branch; new push cancels the old run.
22+
# For push/merge_group/workflow_dispatch: unique per run so runs never cancel each other.
23+
group: >-
24+
${{
25+
github.event_name == 'pull_request' &&
26+
format('{0}-{1}', github.workflow, github.head_ref) ||
27+
format('{0}-{1}', github.workflow, github.run_id)
28+
}}
29+
cancel-in-progress: true
30+
31+
jobs:
32+
lint:
33+
if: github.event_name == 'pull_request'
34+
uses: ./.github/workflows/lint.yml
35+
secrets: inherit
36+
37+
tests:
38+
uses: ./.github/workflows/test-all-erigon.yml
39+
secrets: inherit
40+
41+
race-tests:
42+
uses: ./.github/workflows/test-all-erigon-race.yml
43+
secrets: inherit
44+
45+
hive:
46+
uses: ./.github/workflows/test-hive.yml
47+
secrets: inherit
48+
49+
caplin:
50+
uses: ./.github/workflows/test-integration-caplin.yml
51+
secrets: inherit
52+
53+
# Only meaningful for PRs: needs github.event.pull_request.base.sha.
54+
large-files:
55+
if: github.event_name == 'pull_request'
56+
uses: ./.github/workflows/check-large-files.yml
57+
secrets: inherit
58+
59+
bench:
60+
uses: ./.github/workflows/test-bench.yml
61+
secrets: inherit
62+
63+
kurtosis:
64+
uses: ./.github/workflows/test-kurtosis-assertoor.yml
65+
secrets: inherit
66+
67+
manifest:
68+
uses: ./.github/workflows/manifest.yml
69+
secrets: inherit
70+
71+
repro:
72+
uses: ./.github/workflows/reproducible-build.yml
73+
secrets: inherit
74+
75+
qa-rpc-gnosis:
76+
uses: ./.github/workflows/qa-rpc-integration-tests-gnosis.yml
77+
secrets: inherit
78+
79+
qa-rpc-remote:
80+
uses: ./.github/workflows/qa-rpc-integration-tests-remote.yml
81+
secrets: inherit
82+
83+
ci-gate:
84+
if: always()
85+
needs:
86+
- lint
87+
- tests
88+
- race-tests
89+
- hive
90+
- caplin
91+
- large-files
92+
- bench
93+
- kurtosis
94+
- manifest
95+
- repro
96+
- qa-rpc-gnosis
97+
- qa-rpc-remote
98+
runs-on: ubuntu-latest
99+
steps:
100+
- name: Check all required jobs
101+
run: |
102+
echo '${{ toJSON(needs) }}' > needs.json
103+
failed=$(jq -r 'to_entries[] | select(.value.result == "failure" or .value.result == "cancelled") | .key' needs.json)
104+
if [ -n "$failed" ]; then
105+
echo "The following jobs failed or were cancelled:"
106+
echo "$failed"
107+
exit 1
108+
fi
109+
echo "All required jobs passed or were skipped."

.github/workflows/ci.yml

Lines changed: 0 additions & 20 deletions
This file was deleted.

.github/workflows/lint.yml

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
11
name: Lint
22
on:
33
workflow_dispatch:
4-
pull_request:
5-
branches:
6-
- main
7-
- 'release/**'
8-
- performance
9-
- performance-stable
4+
workflow_call:
105

116
defaults:
127
run:
@@ -15,9 +10,6 @@ defaults:
1510
jobs:
1611
lint:
1712
runs-on: ubuntu-latest
18-
concurrency:
19-
group: ${{ format('{0}-{1}', github.workflow, github.ref) }}
20-
cancel-in-progress: true
2113

2214
steps:
2315
- name: Checkout custom actions

.github/workflows/manifest.yml

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,8 @@ on:
66
- 'release/**'
77
paths:
88
- 'go.mod'
9-
pull_request:
10-
branches:
11-
- main
12-
- 'release/**'
13-
paths:
14-
- 'go.mod'
15-
types:
16-
- opened
17-
- reopened
18-
- synchronize
19-
- ready_for_review
209
workflow_dispatch:
10+
workflow_call:
2111

2212
jobs:
2313
ManifestCheck:

.github/workflows/qa-rpc-integration-tests-gnosis.yml

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,15 @@ name: QA - RPC Integration Tests (Gnosis)
22

33
on:
44
workflow_dispatch: # Run manually
5+
workflow_call:
56
push:
67
branches:
78
- main
89
- 'release/3.*'
9-
pull_request:
10-
branches:
11-
- main
12-
- 'release/3.*'
13-
types:
14-
- opened
15-
- reopened
16-
- synchronize
17-
- ready_for_review
1810

1911

2012
jobs:
2113
gnosis-rpc-integ-tests:
22-
concurrency:
23-
group: >-
24-
${{
25-
(github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/')) &&
26-
format('{0}-{1}', github.workflow, github.run_id) ||
27-
format('{0}-{1}', github.workflow, github.ref)
28-
}}
29-
cancel-in-progress: true
3014
runs-on: [ self-hosted, qa, Gnosis, rpc-integration ]
3115
env:
3216
ERIGON_TESTBED_AREA: /opt/erigon-testbed
@@ -135,7 +119,7 @@ jobs:
135119
if: always() && steps.test_step.outputs.test_executed == 'true'
136120
uses: actions/upload-artifact@v6
137121
with:
138-
name: test-results
122+
name: test-results-gnosis
139123
path: ${{ env.TEST_RESULT_DIR }}
140124

141125
- name: Save test results

.github/workflows/qa-rpc-integration-tests-remote.yml

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,15 @@ name: QA - RPC Integration Tests Remote
22

33
on:
44
workflow_dispatch: # Run manually
5+
workflow_call:
56
push:
67
branches:
78
- main
89
- 'release/3.*'
9-
pull_request:
10-
branches:
11-
- main
12-
- 'release/3.*'
13-
types:
14-
- opened
15-
- reopened
16-
- synchronize
17-
- ready_for_review
1810

1911

2012
jobs:
2113
mainnet-rpc-integ-tests-remote:
22-
concurrency:
23-
group: >-
24-
${{
25-
(github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/')) &&
26-
format('{0}-{1}', github.workflow, github.run_id) ||
27-
format('{0}-{1}', github.workflow, github.ref)
28-
}}
29-
cancel-in-progress: true
3014
runs-on: [ self-hosted, qa, Ethereum, rpc-integration-commitment ]
3115
env:
3216
ERIGON_TESTBED_AREA: /opt/erigon-testbed
@@ -235,7 +219,7 @@ jobs:
235219
if: always() && steps.test_step.outputs.test_executed == 'true'
236220
uses: actions/upload-artifact@v6
237221
with:
238-
name: test-results
222+
name: test-results-remote-mainnet
239223
path: |
240224
${{ env.TEST_RESULT_DIR }}
241225
${{ github.workspace }}/build/bin/rpcdaemon.log

.github/workflows/reproducible-build.yml

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,8 @@
11
name: Reproducible build
22

33
on:
4-
pull_request:
5-
branches:
6-
- main
7-
- 'release/**'
8-
types:
9-
- opened
10-
- reopened
11-
- synchronize
12-
- ready_for_review
134
workflow_dispatch:
5+
workflow_call:
146

157
defaults:
168
run:
@@ -25,9 +17,6 @@ jobs:
2517
- macos-15
2618
- windows-2025
2719
runs-on: ${{ matrix.os }}
28-
concurrency:
29-
group: ${{ github.workflow }}-${{ matrix.os }}-${{ github.ref }}
30-
cancel-in-progress: true
3120

3221
steps:
3322
- uses: actions/checkout@v6

0 commit comments

Comments
 (0)