Skip to content

Commit 4b74a4a

Browse files
committed
chore(ci): address fixture release review feedback
1 parent b2ac847 commit 4b74a4a

15 files changed

Lines changed: 464 additions & 198 deletions

File tree

.github/actions/build-evm-base/action.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ outputs:
2525
evm-bin:
2626
description: "Binary name of the evm tool to use"
2727
value: ${{ steps.config-evm-reader.outputs.evm-bin }}
28-
x-dist:
28+
xdist:
2929
description: "Number of parallel pytest-xdist workers to use"
30-
value: ${{ steps.config-evm-reader.outputs.x-dist }}
30+
value: ${{ steps.config-evm-reader.outputs.xdist }}
3131
runs:
3232
using: "composite"
3333
steps:
@@ -56,7 +56,7 @@ runs:
5656
echo "Repository: ${{ steps.resolved.outputs.repo }}"
5757
echo "Reference: ${{ steps.resolved.outputs.ref }}"
5858
echo "EVM Binary: ${{ steps.config-evm-reader.outputs.evm-bin }}"
59-
echo "X-Dist parameter: ${{ steps.config-evm-reader.outputs.x-dist }}"
59+
echo "X-Dist parameter: ${{ steps.config-evm-reader.outputs.xdist }}"
6060
- name: Skip building for EELS
6161
if: steps.config-evm-reader.outputs.impl == 'eels'
6262
shell: bash

.github/actions/build-fixtures/action.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,9 @@ runs:
6464
# Allow exit code 5 (NO_TESTS_COLLECTED) for fork ranges with no tests.
6565
EXIT_CODE=0
6666
if [ "${{ steps.evm-builder.outputs.impl }}" = "eels" ]; then
67-
uv run fill -n ${{ steps.evm-builder.outputs.x-dist }} ${{ steps.properties.outputs.fill-params }} $FORK_ARGS $OUTPUT_ARG --build-name ${{ inputs.release_name }} --no-html --durations=100 --log-level=DEBUG || EXIT_CODE=$?
67+
uv run fill -n ${{ steps.evm-builder.outputs.xdist }} ${{ steps.properties.outputs.fill-params }} $FORK_ARGS $OUTPUT_ARG --build-name ${{ inputs.release_name }} --no-html --durations=100 --log-level=DEBUG || EXIT_CODE=$?
6868
else
69-
uv run fill -n ${{ steps.evm-builder.outputs.x-dist }} --evm-bin=${{ steps.evm-builder.outputs.evm-bin }} ${{ steps.properties.outputs.fill-params }} $FORK_ARGS $OUTPUT_ARG --build-name ${{ inputs.release_name }} --no-html --durations=100 --log-level=DEBUG || EXIT_CODE=$?
69+
uv run fill -n ${{ steps.evm-builder.outputs.xdist }} --evm-bin=${{ steps.evm-builder.outputs.evm-bin }} ${{ steps.properties.outputs.fill-params }} $FORK_ARGS $OUTPUT_ARG --build-name ${{ inputs.release_name }} --no-html --durations=100 --log-level=DEBUG || EXIT_CODE=$?
7070
fi
7171
if [ "$EXIT_CODE" -ne 0 ] && [ "$EXIT_CODE" -ne 5 ]; then
7272
exit "$EXIT_CODE"

.github/configs/evm.yaml

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,31 @@
1-
# Client aliases
21
benchmark:
32
impl: geth
43
repo: ethereum/go-ethereum
54
ref: master
65
evm-bin: evm
7-
x-dist: auto
8-
consensus:
9-
impl: eels
10-
repo: null
11-
ref: null
12-
evm-bin: null
13-
x-dist: auto
14-
6+
xdist: auto
157
eels:
168
impl: eels
179
repo: null
1810
ref: null
1911
evm-bin: null
20-
x-dist: auto
12+
xdist: auto
2113
evmone:
2214
impl: evmone
2315
repo: ethereum/evmone
2416
ref: master
2517
targets: ["evmone-t8n"]
2618
evm-bin: evmone-t8n
27-
x-dist: auto
19+
xdist: auto
2820
geth:
2921
impl: geth
3022
repo: ethereum/go-ethereum
3123
ref: master
3224
evm-bin: evm
33-
x-dist: auto
25+
xdist: auto
3426
besu:
3527
impl: besu
3628
repo: hyperledger/besu
3729
ref: main
3830
evm-bin: evmtool
39-
x-dist: 0
31+
xdist: 0

.github/configs/feature.yaml

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,25 @@
1-
# Unless filling for special features, all features should fill for previous forks (starting from Frontier) too
2-
consensus:
3-
evm-type: consensus
4-
fill-params: --until=BPO4
1+
# Release feature definitions consumed by the `release_fixtures` workflow.
2+
#
3+
# Top-level keys are feature names used verbatim in the release tag
4+
# (`tests-<feature>@vX.Y.Z`), except `tests`, which tags as `tests@vX.Y.Z`.
5+
# Any `<feat>-devnet` input resolves to the shared `devnet` entry but keeps
6+
# its name in the tag; the devnet number lives in the version (X), not the
7+
# feature name, so this file needs no edits for new devnets.
8+
tests:
9+
evm-type: eels
10+
fill-params: --until=BPO4 --generate-all-formats
511

612
benchmark:
713
evm-type: benchmark
8-
fill-params: --fork=Amsterdam --gas-benchmark-values 1,10,30,60,100,150 ./tests/benchmark
14+
fill-params: --fork=Osaka --generate-all-formats --gas-benchmark-values 1,5,10,30,60,100,150 ./tests/benchmark/compute --maxprocesses=30 --dist=worksteal
15+
feature_only: true
16+
17+
benchmark_fast:
18+
evm-type: benchmark
19+
fill-params: --fork=Osaka --generate-all-formats --gas-benchmark-values 100 ./tests/benchmark/compute
20+
feature_only: true
921

22+
# Shared entry for all `<feat>-devnet` releases; matched by `-devnet` suffix.
1023
devnet:
1124
evm-type: eels
12-
fill-params: --until=Amsterdam
25+
fill-params: --until=Amsterdam --generate-all-formats

.github/scripts/create_release_tarball.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77
"""
88
Create a release tarball from a merged fixture directory.
99
10-
Archive all ``.json`` and ``.ini`` files under a ``fixtures/`` prefix,
10+
Archive all `.json` and `.ini` files under a `fixtures/` prefix,
1111
matching the structure produced by
12-
``execution_testing.cli.pytest_commands.plugins.shared.fixture_output``.
12+
`execution_testing.cli.pytest_commands.plugins.shared.fixture_output`.
1313
14-
Use ``pigz`` for parallel compression when available, otherwise fall
14+
Use `pigz` for parallel compression when available, otherwise fall
1515
back to Python's built-in gzip.
1616
"""
1717

.github/scripts/generate_build_matrix.py

Lines changed: 85 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,33 @@
77
# ]
88
# ///
99
"""
10-
Generate the build matrix for release fixture workflows.
10+
Validate release inputs and generate the build matrix for release
11+
fixture workflows.
1112
12-
Read `.github/configs/feature.yaml` and emit a flat JSON build matrix
13-
suitable for ``strategy.matrix`` in GitHub Actions.
13+
Usage: `generate_build_matrix.py <feature> <version> [branch]`.
1414
15-
Features whose ``fill-params`` contain ``--until`` are split across the
15+
First validate the dispatch inputs (see `validate_inputs`), then read
16+
`.github/configs/feature.yaml` and emit a flat JSON build matrix suitable
17+
for `strategy.matrix` in GitHub Actions.
18+
19+
Features whose `fill-params` contain `--until` are split across the
1620
shared fork ranges defined in `.github/configs/fork-ranges.yaml`.
17-
Features using ``--fork`` (single fork) produce a single unsplit entry.
21+
Features using `--fork` (single fork) produce a single unsplit entry.
1822
"""
1923

2024
import json
2125
import re
2226
import sys
2327
from pathlib import Path
28+
from typing import NoReturn
2429

2530
import yaml
2631

2732
FEATURE_CONFIG = Path(".github/configs/feature.yaml")
2833
FORK_RANGES_CONFIG = Path(".github/configs/fork-ranges.yaml")
2934

35+
VERSION_RE = re.compile(r"^v[0-9]+\.[0-9]+\.[0-9]+$")
36+
3037
# Canonical fork ordering used to filter fork ranges per feature.
3138
FORK_ORDER = [
3239
"Frontier",
@@ -64,11 +71,70 @@ def load_config(path: Path) -> dict:
6471
return yaml.safe_load(f)
6572

6673

74+
def fail(message: str) -> NoReturn:
75+
"""Print an error to stderr and exit non-zero."""
76+
print(f"Error: {message}", file=sys.stderr)
77+
sys.exit(1)
78+
79+
80+
def validate_inputs(feature: str, version: str, branch: str) -> None:
81+
"""
82+
Validate the release dispatch inputs before building a matrix.
83+
84+
Centralize the feature/version checks here so they are unit-testable
85+
rather than living as inline bash in the release workflow.
86+
87+
For `<feat>-devnet` releases the major version (`X` of `vX.Y.Z`)
88+
must equal the devnet number encoded in the release branch, so a
89+
`bal-devnet` release from `bal-devnet-7` must be tagged `v7.*.*`.
90+
"""
91+
if not feature:
92+
fail("feature name is empty")
93+
if not VERSION_RE.match(version):
94+
fail(f"version '{version}' must match vX.Y.Z (e.g. v20.0.0)")
95+
96+
# A bare `devnet` has no friendly `<feat>-` prefix to tag with.
97+
if feature in ("devnet", "-devnet"):
98+
fail("devnet releases require a <feat>- prefix, e.g. bal-devnet")
99+
100+
# `<feat>-devnet-<n>`: the devnet index belongs in the version (X of
101+
# vX.Y.Z), not in the feature name.
102+
if "-devnet-" in feature:
103+
suggested_feature, _, suggested_index = feature.rpartition("-")
104+
fail(
105+
"devnet index must go in 'version', not the feature name; "
106+
f"did you mean feature={suggested_feature} "
107+
f"version=v{suggested_index}.0.0?"
108+
)
109+
110+
if feature.endswith("-devnet"):
111+
if not branch:
112+
fail(
113+
"devnet releases require a 'branch' input, "
114+
"e.g. branch=bal-devnet-7"
115+
)
116+
match = re.search(r"(\d+)$", branch)
117+
if not match:
118+
fail(
119+
f"could not parse a devnet number from branch '{branch}' "
120+
"(expected a trailing number, e.g. bal-devnet-7)"
121+
)
122+
devnet_number = int(match.group(1))
123+
major = int(version.lstrip("v").split(".")[0])
124+
if major != devnet_number:
125+
minor_patch = version.split(".", 1)[1]
126+
fail(
127+
f"version major (v{major}) must equal the devnet number "
128+
f"({devnet_number}) from branch '{branch}'; "
129+
f"did you mean version=v{devnet_number}.{minor_patch}?"
130+
)
131+
132+
67133
def parse_until_fork(fill_params: str) -> str | None:
68134
"""
69-
Extract the ``--until`` value from fill-params.
135+
Extract the `--until` value from fill-params.
70136
71-
Return ``None`` when ``--fork`` is used instead (single-fork
137+
Return `None` when `--fork` is used instead (single-fork
72138
feature that should not be split).
73139
"""
74140
if re.search(r"--fork\b", fill_params):
@@ -79,9 +145,9 @@ def parse_until_fork(fill_params: str) -> str | None:
79145

80146
def applicable_ranges(fork_ranges: list[dict], until_fork: str) -> list[dict]:
81147
"""
82-
Return fork ranges whose ``from`` is at or before *until_fork*.
148+
Return fork ranges whose `from` is at or before *until_fork*.
83149
84-
Clamp the last applicable range's ``until`` to *until_fork* so we
150+
Clamp the last applicable range's `until` to *until_fork* so we
85151
never fill beyond the feature's declared boundary.
86152
"""
87153
limit = FORK_INDEX[until_fork]
@@ -133,17 +199,23 @@ def build_matrix(
133199

134200

135201
def main() -> None:
136-
"""Entry point."""
137-
if len(sys.argv) != 2:
202+
"""Validate the inputs and print the build matrix to stdout."""
203+
args = sys.argv[1:]
204+
if len(args) < 2:
138205
print(
139-
"Usage: generate_build_matrix.py <feature>",
206+
"Usage: generate_build_matrix.py <feature> <version> [branch]",
140207
file=sys.stderr,
141208
)
142209
sys.exit(1)
143210

211+
name = args[0]
212+
version = args[1]
213+
branch = args[2] if len(args) > 2 else ""
214+
215+
validate_inputs(name, version, branch)
216+
144217
config = load_config(FEATURE_CONFIG)
145218
fork_ranges = load_config(FORK_RANGES_CONFIG) or []
146-
name = sys.argv[1]
147219

148220
# `<feat>-devnet` releases (e.g. bal-devnet) share the `devnet` entry,
149221
# while keeping their friendly name in the matrix and artifact outputs.

.github/scripts/merge_index_files.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
Merge multiple .meta/index.json files from split fixture builds.
44
55
Accept fixture directories as arguments, load each directory's
6-
``.meta/index.json``, merge them via ``IndexFile.merge()``, and write
6+
`.meta/index.json`, merge them via `IndexFile.merge()`, and write
77
the result to the specified output path.
88
"""
99

0 commit comments

Comments
 (0)