From 570e50e7f192acde96edcb261f83488f0f2f41d0 Mon Sep 17 00:00:00 2001 From: loothero Date: Sun, 8 Mar 2026 12:23:29 -0700 Subject: [PATCH 01/10] ci: partition heavy EGS test modules for parallel execution MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use snforge --partition to split token (4 partitions), minigame, metagame, and registry (2 partitions each) across multiple cheaper runners. This eliminates ubuntu-latest-32 and ubuntu-latest-8 runners for EGS while doubling fuzzer runs from 32 to 64. Jobs: 16 → 22 (all on ubuntu-latest-4/8 instead of 32-core runners) Co-Authored-By: Claude Opus 4.6 --- .github/workflows/main-ci.yml | 113 +++++++++++++++++++++++++++++----- .github/workflows/pr-ci.yml | 64 +++++++++++-------- AGENTS.md | 46 +++++++------- codecov.yml | 5 +- 4 files changed, 162 insertions(+), 66 deletions(-) diff --git a/.github/workflows/main-ci.yml b/.github/workflows/main-ci.yml index 0756e24..0da9794 100644 --- a/.github/workflows/main-ci.yml +++ b/.github/workflows/main-ci.yml @@ -68,16 +68,16 @@ jobs: matrix_count=$(grep -cE '^\s+module:' .github/workflows/main-ci.yml) codecov_count=$(grep 'after_n_builds:' codecov.yml | grep -oE '[0-9]+') - echo "Matrix modules: $matrix_count" + echo "Matrix entries: $matrix_count" echo "Codecov after_n_builds: $codecov_count" if [ "$matrix_count" != "$codecov_count" ]; then - echo "::error::Matrix has $matrix_count modules but codecov.yml expects $codecov_count builds" - echo "::error::Update codecov.yml after_n_builds to match module count" + echo "::error::Matrix has $matrix_count entries but codecov.yml expects $codecov_count builds" + echo "::error::Update codecov.yml after_n_builds to match matrix entry count" exit 1 fi - echo "Configuration validated: $matrix_count modules" + echo "Configuration validated: $matrix_count matrix entries" lint: needs: changes @@ -150,7 +150,7 @@ jobs: fi test: - name: test (${{ matrix.module }}) + name: test (${{ matrix.module }}${{ matrix.total_partitions > 1 && format(' {0}/{1}', matrix.partition, matrix.total_partitions) || '' }}) needs: setup runs-on: ${{ matrix.runner }} timeout-minutes: 10 @@ -158,78 +158,152 @@ jobs: fail-fast: true matrix: # NOTE: When adding/removing modules, also update: - # - codecov.yml: after_n_builds must equal module count + # - codecov.yml: after_n_builds must equal matrix entry count # - AGENTS.md: CI Configuration section + # Partitioned modules use snforge --partition INDEX/TOTAL to split + # tests across multiple cheaper runners for parallelism. include: - # Embeddable Game Standard + # Embeddable Game Standard — partitioned for parallelism + # token: 4 partitions (~159 tests each) - package: game_components_embeddable_game_standard module: token - runner: ubuntu-latest-32 - fuzzer_runs: 32 + runner: ubuntu-latest-8 + fuzzer_runs: 64 + partition: 1 + total_partitions: 4 - package: game_components_embeddable_game_standard - module: minigame + module: token runner: ubuntu-latest-8 - fuzzer_runs: 32 + fuzzer_runs: 64 + partition: 2 + total_partitions: 4 - package: game_components_embeddable_game_standard - module: metagame + module: token runner: ubuntu-latest-8 - fuzzer_runs: 32 + fuzzer_runs: 64 + partition: 3 + total_partitions: 4 - package: game_components_embeddable_game_standard - module: registry + module: token runner: ubuntu-latest-8 - fuzzer_runs: 32 + fuzzer_runs: 64 + partition: 4 + total_partitions: 4 + # minigame: 2 partitions (~107 tests each) + - package: game_components_embeddable_game_standard + module: minigame + runner: ubuntu-latest-4 + fuzzer_runs: 64 + partition: 1 + total_partitions: 2 + - package: game_components_embeddable_game_standard + module: minigame + runner: ubuntu-latest-4 + fuzzer_runs: 64 + partition: 2 + total_partitions: 2 + # metagame: 2 partitions (~40 tests each) + - package: game_components_embeddable_game_standard + module: metagame + runner: ubuntu-latest-4 + fuzzer_runs: 64 + partition: 1 + total_partitions: 2 + - package: game_components_embeddable_game_standard + module: metagame + runner: ubuntu-latest-4 + fuzzer_runs: 64 + partition: 2 + total_partitions: 2 + # registry: 2 partitions (~69 tests each) + - package: game_components_embeddable_game_standard + module: registry + runner: ubuntu-latest-4 + fuzzer_runs: 64 + partition: 1 + total_partitions: 2 + - package: game_components_embeddable_game_standard + module: registry + runner: ubuntu-latest-4 + fuzzer_runs: 64 + partition: 2 + total_partitions: 2 # Metagame - package: game_components_metagame module: leaderboard runner: ubuntu-latest-4 fuzzer_runs: 256 + partition: 1 + total_partitions: 1 - package: game_components_metagame module: registration runner: ubuntu-latest-4 fuzzer_runs: 256 + partition: 1 + total_partitions: 1 - package: game_components_metagame module: entry_requirement runner: ubuntu-latest-4 fuzzer_runs: 256 + partition: 1 + total_partitions: 1 - package: game_components_metagame module: entry_fee runner: ubuntu-latest-4 fuzzer_runs: 256 + partition: 1 + total_partitions: 1 - package: game_components_metagame module: prize runner: ubuntu-latest-4 fuzzer_runs: 256 + partition: 1 + total_partitions: 1 - package: game_components_metagame module: ticket_booth runner: ubuntu-latest-4 fuzzer_runs: 256 + partition: 1 + total_partitions: 1 # Economy - package: game_components_economy module: tokenomics runner: ubuntu-latest-4 fuzzer_runs: 256 + partition: 1 + total_partitions: 1 # Utilities - package: game_components_utilities module: math runner: ubuntu-latest-4 fuzzer_runs: 256 + partition: 1 + total_partitions: 1 - package: game_components_utilities module: distribution runner: ubuntu-latest-4 fuzzer_runs: 256 + partition: 1 + total_partitions: 1 - package: game_components_utilities module: utils runner: ubuntu-latest-4 fuzzer_runs: 256 + partition: 1 + total_partitions: 1 - package: game_components_utilities module: renderer runner: ubuntu-latest-4 fuzzer_runs: 256 + partition: 1 + total_partitions: 1 # Presets (standalone package, no module filter) - package: game_components_presets module: presets runner: ubuntu-latest-4 fuzzer_runs: 256 + partition: 1 + total_partitions: 1 steps: - uses: actions/checkout@v6 @@ -289,10 +363,15 @@ jobs: - name: Run tests with coverage run: | + PARTITION_FLAG="" + if [ "${{ matrix.total_partitions }}" != "1" ]; then + PARTITION_FLAG="--partition ${{ matrix.partition }}/${{ matrix.total_partitions }}" + fi + if [ "${{ matrix.package }}" = "game_components_${{ matrix.module }}" ]; then - snforge test -p ${{ matrix.package }} --fuzzer-runs ${{ matrix.fuzzer_runs }} --coverage 2>&1 | tee /tmp/test.log + snforge test -p ${{ matrix.package }} --fuzzer-runs ${{ matrix.fuzzer_runs }} $PARTITION_FLAG --coverage 2>&1 | tee /tmp/test.log else - snforge test -p ${{ matrix.package }} "::${{ matrix.module }}::" --fuzzer-runs ${{ matrix.fuzzer_runs }} --coverage 2>&1 | tee /tmp/test.log + snforge test -p ${{ matrix.package }} "::${{ matrix.module }}::" --fuzzer-runs ${{ matrix.fuzzer_runs }} $PARTITION_FLAG --coverage 2>&1 | tee /tmp/test.log fi - name: Check for compiler warnings diff --git a/.github/workflows/pr-ci.yml b/.github/workflows/pr-ci.yml index 699bd76..acb0243 100644 --- a/.github/workflows/pr-ci.yml +++ b/.github/workflows/pr-ci.yml @@ -242,16 +242,16 @@ jobs: matrix_count=$(grep -cE '^\s+module:' .github/workflows/main-ci.yml) codecov_count=$(grep 'after_n_builds:' codecov.yml | grep -oE '[0-9]+') - echo "Matrix modules: $matrix_count" + echo "Matrix entries: $matrix_count" echo "Codecov after_n_builds: $codecov_count" if [ "$matrix_count" != "$codecov_count" ]; then - echo "::error::Matrix has $matrix_count modules but codecov.yml expects $codecov_count builds" - echo "::error::Update codecov.yml after_n_builds to match module count" + echo "::error::Matrix has $matrix_count entries but codecov.yml expects $codecov_count builds" + echo "::error::Update codecov.yml after_n_builds to match matrix entry count" exit 1 fi - echo "Configuration validated: $matrix_count modules" + echo "Configuration validated: $matrix_count matrix entries" lint: needs: changes @@ -290,35 +290,44 @@ jobs: NEED_PRESETS: ${{ needs.changes.outputs.need_presets }} run: | # Build JSON matrix from per-package boolean flags - # Module catalog must match main-ci.yml + # Module catalog must match main-ci.yml (including partitions) INCLUDES="[]" - add() { INCLUDES=$(echo "$INCLUDES" | jq -c --arg p "$1" --arg m "$2" --arg r "$3" --argjson f "$4" '. + [{package:$p,module:$m,runner:$r,fuzzer_runs:$f}]'); } + add() { + INCLUDES=$(echo "$INCLUDES" | jq -c \ + --arg p "$1" --arg m "$2" --arg r "$3" \ + --argjson f "$4" --argjson part "$5" --argjson total "$6" \ + '. + [{package:$p,module:$m,runner:$r,fuzzer_runs:$f,partition:$part,total_partitions:$total}]') + } if [ "$NEED_EGS" = "true" ]; then - add game_components_embeddable_game_standard token ubuntu-latest-32 32 - add game_components_embeddable_game_standard minigame ubuntu-latest-8 32 - add game_components_embeddable_game_standard metagame ubuntu-latest-8 32 - add game_components_embeddable_game_standard registry ubuntu-latest-8 32 + for p in 1 2 3 4; do + add game_components_embeddable_game_standard token ubuntu-latest-8 64 "$p" 4 + done + for p in 1 2; do + add game_components_embeddable_game_standard minigame ubuntu-latest-4 64 "$p" 2 + add game_components_embeddable_game_standard metagame ubuntu-latest-4 64 "$p" 2 + add game_components_embeddable_game_standard registry ubuntu-latest-4 64 "$p" 2 + done fi if [ "$NEED_METAGAME" = "true" ]; then - add game_components_metagame leaderboard ubuntu-latest-4 256 - add game_components_metagame registration ubuntu-latest-4 256 - add game_components_metagame entry_requirement ubuntu-latest-4 256 - add game_components_metagame entry_fee ubuntu-latest-4 256 - add game_components_metagame prize ubuntu-latest-4 256 - add game_components_metagame ticket_booth ubuntu-latest-4 256 + add game_components_metagame leaderboard ubuntu-latest-4 256 1 1 + add game_components_metagame registration ubuntu-latest-4 256 1 1 + add game_components_metagame entry_requirement ubuntu-latest-4 256 1 1 + add game_components_metagame entry_fee ubuntu-latest-4 256 1 1 + add game_components_metagame prize ubuntu-latest-4 256 1 1 + add game_components_metagame ticket_booth ubuntu-latest-4 256 1 1 fi if [ "$NEED_ECONOMY" = "true" ]; then - add game_components_economy tokenomics ubuntu-latest-4 256 + add game_components_economy tokenomics ubuntu-latest-4 256 1 1 fi if [ "$NEED_UTILITIES" = "true" ]; then - add game_components_utilities math ubuntu-latest-4 256 - add game_components_utilities distribution ubuntu-latest-4 256 - add game_components_utilities utils ubuntu-latest-4 256 - add game_components_utilities renderer ubuntu-latest-4 256 + add game_components_utilities math ubuntu-latest-4 256 1 1 + add game_components_utilities distribution ubuntu-latest-4 256 1 1 + add game_components_utilities utils ubuntu-latest-4 256 1 1 + add game_components_utilities renderer ubuntu-latest-4 256 1 1 fi if [ "$NEED_PRESETS" = "true" ]; then - add game_components_presets presets ubuntu-latest-4 256 + add game_components_presets presets ubuntu-latest-4 256 1 1 fi MATRIX=$(echo "$INCLUDES" | jq -c '{include:.}') @@ -372,7 +381,7 @@ jobs: fi test: - name: test (${{ matrix.module }}) + name: test (${{ matrix.module }}${{ matrix.total_partitions > 1 && format(' {0}/{1}', matrix.partition, matrix.total_partitions) || '' }}) needs: [changes, setup] if: needs.changes.outputs.has_tests == 'true' runs-on: ${{ matrix.runner }} @@ -439,10 +448,15 @@ jobs: - name: Run tests with coverage run: | + PARTITION_FLAG="" + if [ "${{ matrix.total_partitions }}" != "1" ]; then + PARTITION_FLAG="--partition ${{ matrix.partition }}/${{ matrix.total_partitions }}" + fi + if [ "${{ matrix.package }}" = "game_components_${{ matrix.module }}" ]; then - snforge test -p ${{ matrix.package }} --fuzzer-runs ${{ matrix.fuzzer_runs }} --coverage 2>&1 | tee /tmp/test.log + snforge test -p ${{ matrix.package }} --fuzzer-runs ${{ matrix.fuzzer_runs }} $PARTITION_FLAG --coverage 2>&1 | tee /tmp/test.log else - snforge test -p ${{ matrix.package }} "::${{ matrix.module }}::" --fuzzer-runs ${{ matrix.fuzzer_runs }} --coverage 2>&1 | tee /tmp/test.log + snforge test -p ${{ matrix.package }} "::${{ matrix.module }}::" --fuzzer-runs ${{ matrix.fuzzer_runs }} $PARTITION_FLAG --coverage 2>&1 | tee /tmp/test.log fi - name: Check for compiler warnings diff --git a/AGENTS.md b/AGENTS.md index 3149492..3defd1b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -123,31 +123,33 @@ When adding a new module to a group package, update **both** files: fuzzer_runs: 256 ``` - For memory-intensive modules (like `token` or `minigame`), assign a larger runner (e.g., `ubuntu-latest-4` or `ubuntu-latest-32`). + For memory-intensive modules (like `token` or `minigame`), assign a larger runner (e.g., `ubuntu-latest-4` or `ubuntu-latest-8`) and consider partitioning with `--partition INDEX/TOTAL`. 2. **`codecov.yml`** - Update the build count: ```yaml notify: - after_n_builds: 15 # ← Must equal total module count in matrix + after_n_builds: 22 # ← Must equal total matrix entry count (including partitions) ``` -### Current Matrix (16 modules) - -| Group Package | Module | Runner | Fuzzer Runs | -|---------------|--------|--------|-------------| -| `embeddable_game_standard` | `token` | `ubuntu-latest-32` | 32 | -| `embeddable_game_standard` | `minigame` | `ubuntu-latest-32` | 32 | -| `embeddable_game_standard` | `metagame` | `ubuntu-latest-32` | 256 | -| `embeddable_game_standard` | `registry` | `ubuntu-latest-32` | 256 | -| `metagame` | `leaderboard` | `ubuntu-latest-4` | 256 | -| `metagame` | `registration` | `ubuntu-latest-4` | 256 | -| `metagame` | `entry_requirement` | `ubuntu-latest-4` | 256 | -| `metagame` | `entry_fee` | `ubuntu-latest-4` | 256 | -| `metagame` | `prize` | `ubuntu-latest-4` | 256 | -| `metagame` | `ticket_booth` | `ubuntu-latest-4` | 256 | -| `economy` | `tokenomics` | `ubuntu-latest-4` | 256 | -| `utilities` | `math` | `ubuntu-latest-4` | 256 | -| `utilities` | `distribution` | `ubuntu-latest-4` | 256 | -| `utilities` | `utils` | `ubuntu-latest-4` | 256 | -| `utilities` | `renderer` | `ubuntu-latest-4` | 256 | -| `presets` | `presets` | `ubuntu-latest-4` | 256 | +### Current Matrix (22 jobs across 16 modules) + +Heavy EGS modules are partitioned via `snforge --partition` for parallelism on cheaper runners. + +| Group Package | Module | Runner | Fuzzer Runs | Partitions | +|---------------|--------|--------|-------------|------------| +| `embeddable_game_standard` | `token` | `ubuntu-latest-8` | 64 | 4 | +| `embeddable_game_standard` | `minigame` | `ubuntu-latest-4` | 64 | 2 | +| `embeddable_game_standard` | `metagame` | `ubuntu-latest-4` | 64 | 2 | +| `embeddable_game_standard` | `registry` | `ubuntu-latest-4` | 64 | 2 | +| `metagame` | `leaderboard` | `ubuntu-latest-4` | 256 | 1 | +| `metagame` | `registration` | `ubuntu-latest-4` | 256 | 1 | +| `metagame` | `entry_requirement` | `ubuntu-latest-4` | 256 | 1 | +| `metagame` | `entry_fee` | `ubuntu-latest-4` | 256 | 1 | +| `metagame` | `prize` | `ubuntu-latest-4` | 256 | 1 | +| `metagame` | `ticket_booth` | `ubuntu-latest-4` | 256 | 1 | +| `economy` | `tokenomics` | `ubuntu-latest-4` | 256 | 1 | +| `utilities` | `math` | `ubuntu-latest-4` | 256 | 1 | +| `utilities` | `distribution` | `ubuntu-latest-4` | 256 | 1 | +| `utilities` | `utils` | `ubuntu-latest-4` | 256 | 1 | +| `utilities` | `renderer` | `ubuntu-latest-4` | 256 | 1 | +| `presets` | `presets` | `ubuntu-latest-4` | 256 | 1 | diff --git a/codecov.yml b/codecov.yml index 84001da..fb0f08f 100644 --- a/codecov.yml +++ b/codecov.yml @@ -1,9 +1,10 @@ codecov: require_ci_to_pass: true notify: - # Must equal package count in .github/workflows/main-ci.yml matrix + # Must equal matrix entry count in .github/workflows/main-ci.yml + # (partitioned modules count once per partition) # See AGENTS.md "CI Configuration" section when adding packages - after_n_builds: 16 + after_n_builds: 22 comment: layout: "diff, files, header, footer" From 58a9d540497ebe4501daf09db2c84d3fe5332975 Mon Sep 17 00:00:00 2001 From: loothero Date: Sun, 8 Mar 2026 12:25:45 -0700 Subject: [PATCH 02/10] test: trivial comment change to trigger full CI matrix Co-Authored-By: Claude Opus 4.6 --- packages/testing/src/constants.cairo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/testing/src/constants.cairo b/packages/testing/src/constants.cairo index 87b13bb..c9b7ac9 100644 --- a/packages/testing/src/constants.cairo +++ b/packages/testing/src/constants.cairo @@ -1,6 +1,6 @@ use starknet::ContractAddress; -// Test addresses - using try_into().unwrap() pattern +// Test addresses — using try_into().unwrap() pattern pub fn ALICE() -> ContractAddress { 'ALICE'.try_into().unwrap() } From 4053dd035ca148f7d7d178bd871836cf7dda1e23 Mon Sep 17 00:00:00 2001 From: loothero Date: Sun, 8 Mar 2026 12:33:13 -0700 Subject: [PATCH 03/10] ci: re-trigger CI (previous run had flaky snfoundry setup) Co-Authored-By: Claude Opus 4.6 From 529b822688cef96d7301045faa114dbfb3fd0c49 Mon Sep 17 00:00:00 2001 From: loothero Date: Sun, 8 Mar 2026 12:33:37 -0700 Subject: [PATCH 04/10] test: retrigger CI after flaky snfoundry setup failure Co-Authored-By: Claude Opus 4.6 --- packages/testing/src/constants.cairo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/testing/src/constants.cairo b/packages/testing/src/constants.cairo index c9b7ac9..87b13bb 100644 --- a/packages/testing/src/constants.cairo +++ b/packages/testing/src/constants.cairo @@ -1,6 +1,6 @@ use starknet::ContractAddress; -// Test addresses — using try_into().unwrap() pattern +// Test addresses - using try_into().unwrap() pattern pub fn ALICE() -> ContractAddress { 'ALICE'.try_into().unwrap() } From 495cba031e760af970b23e3c8fe94db1f1c5e1d5 Mon Sep 17 00:00:00 2001 From: loothero Date: Sun, 8 Mar 2026 12:34:45 -0700 Subject: [PATCH 05/10] test: trigger full CI with actual diff from main Co-Authored-By: Claude Opus 4.6 --- packages/testing/src/constants.cairo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/testing/src/constants.cairo b/packages/testing/src/constants.cairo index 87b13bb..208b243 100644 --- a/packages/testing/src/constants.cairo +++ b/packages/testing/src/constants.cairo @@ -41,7 +41,7 @@ pub fn CREATOR() -> ContractAddress { 'CREATOR'.try_into().unwrap() } -// Edge case values +// Edge-case values pub const MAX_U64: u64 = 18446744073709551615; pub const MAX_U32: u32 = 4294967295; // Max 35-bit timestamp - maximum value that fits in TokenMetadata lifecycle packing From d609fbc9c2d813b33d30c6009f384e5e0ee0ecef Mon Sep 17 00:00:00 2001 From: loothero Date: Sun, 8 Mar 2026 12:45:49 -0700 Subject: [PATCH 06/10] ci: partition all >60s modules and remove redundant scarb build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Partition all 11 modules that took >60s into 2 partitions each (only distribution stays at 1 — it ran in 54s) - Remove `scarb build --workspace` from setup job; snforge test already compiles and each test job checks for warnings - Jobs: 22 → 33 (all on ubuntu-latest-4, except token on -8) Co-Authored-By: Claude Opus 4.6 --- .github/workflows/main-ci.yml | 101 ++++++++++++++++++++++++++-------- .github/workflows/pr-ci.yml | 39 +++++++------ AGENTS.md | 28 +++++----- codecov.yml | 2 +- 4 files changed, 113 insertions(+), 57 deletions(-) diff --git a/.github/workflows/main-ci.yml b/.github/workflows/main-ci.yml index 0da9794..fb0418d 100644 --- a/.github/workflows/main-ci.yml +++ b/.github/workflows/main-ci.yml @@ -140,15 +140,6 @@ jobs: - name: Warm snforge plugin cache run: snforge --version - - name: Verify workspace compiles (no warnings) - run: | - scarb build --workspace 2>&1 | tee /tmp/build.log - if grep -qE '^ --> .*\.cairo:[0-9]+:[0-9]+' /tmp/build.log; then - echo "::error::Build produced compiler warnings. Fix all warnings before merging." - grep -B1 -E '^ --> .*\.cairo:[0-9]+:[0-9]+' /tmp/build.log - exit 1 - fi - test: name: test (${{ matrix.module }}${{ matrix.total_partitions > 1 && format(' {0}/{1}', matrix.partition, matrix.total_partitions) || '' }}) needs: setup @@ -228,57 +219,105 @@ jobs: fuzzer_runs: 64 partition: 2 total_partitions: 2 - # Metagame + # Metagame — all partitioned (2 each) - package: game_components_metagame module: leaderboard runner: ubuntu-latest-4 fuzzer_runs: 256 partition: 1 - total_partitions: 1 + total_partitions: 2 + - package: game_components_metagame + module: leaderboard + runner: ubuntu-latest-4 + fuzzer_runs: 256 + partition: 2 + total_partitions: 2 - package: game_components_metagame module: registration runner: ubuntu-latest-4 fuzzer_runs: 256 partition: 1 - total_partitions: 1 + total_partitions: 2 + - package: game_components_metagame + module: registration + runner: ubuntu-latest-4 + fuzzer_runs: 256 + partition: 2 + total_partitions: 2 - package: game_components_metagame module: entry_requirement runner: ubuntu-latest-4 fuzzer_runs: 256 partition: 1 - total_partitions: 1 + total_partitions: 2 + - package: game_components_metagame + module: entry_requirement + runner: ubuntu-latest-4 + fuzzer_runs: 256 + partition: 2 + total_partitions: 2 - package: game_components_metagame module: entry_fee runner: ubuntu-latest-4 fuzzer_runs: 256 partition: 1 - total_partitions: 1 + total_partitions: 2 + - package: game_components_metagame + module: entry_fee + runner: ubuntu-latest-4 + fuzzer_runs: 256 + partition: 2 + total_partitions: 2 - package: game_components_metagame module: prize runner: ubuntu-latest-4 fuzzer_runs: 256 partition: 1 - total_partitions: 1 + total_partitions: 2 + - package: game_components_metagame + module: prize + runner: ubuntu-latest-4 + fuzzer_runs: 256 + partition: 2 + total_partitions: 2 - package: game_components_metagame module: ticket_booth runner: ubuntu-latest-4 fuzzer_runs: 256 partition: 1 - total_partitions: 1 + total_partitions: 2 + - package: game_components_metagame + module: ticket_booth + runner: ubuntu-latest-4 + fuzzer_runs: 256 + partition: 2 + total_partitions: 2 # Economy - package: game_components_economy module: tokenomics runner: ubuntu-latest-4 fuzzer_runs: 256 partition: 1 - total_partitions: 1 - # Utilities + total_partitions: 2 + - package: game_components_economy + module: tokenomics + runner: ubuntu-latest-4 + fuzzer_runs: 256 + partition: 2 + total_partitions: 2 + # Utilities — all partitioned except distribution - package: game_components_utilities module: math runner: ubuntu-latest-4 fuzzer_runs: 256 partition: 1 - total_partitions: 1 + total_partitions: 2 + - package: game_components_utilities + module: math + runner: ubuntu-latest-4 + fuzzer_runs: 256 + partition: 2 + total_partitions: 2 - package: game_components_utilities module: distribution runner: ubuntu-latest-4 @@ -290,20 +329,38 @@ jobs: runner: ubuntu-latest-4 fuzzer_runs: 256 partition: 1 - total_partitions: 1 + total_partitions: 2 + - package: game_components_utilities + module: utils + runner: ubuntu-latest-4 + fuzzer_runs: 256 + partition: 2 + total_partitions: 2 - package: game_components_utilities module: renderer runner: ubuntu-latest-4 fuzzer_runs: 256 partition: 1 - total_partitions: 1 + total_partitions: 2 + - package: game_components_utilities + module: renderer + runner: ubuntu-latest-4 + fuzzer_runs: 256 + partition: 2 + total_partitions: 2 # Presets (standalone package, no module filter) - package: game_components_presets module: presets runner: ubuntu-latest-4 fuzzer_runs: 256 partition: 1 - total_partitions: 1 + total_partitions: 2 + - package: game_components_presets + module: presets + runner: ubuntu-latest-4 + fuzzer_runs: 256 + partition: 2 + total_partitions: 2 steps: - uses: actions/checkout@v6 diff --git a/.github/workflows/pr-ci.yml b/.github/workflows/pr-ci.yml index acb0243..000c548 100644 --- a/.github/workflows/pr-ci.yml +++ b/.github/workflows/pr-ci.yml @@ -310,24 +310,32 @@ jobs: done fi if [ "$NEED_METAGAME" = "true" ]; then - add game_components_metagame leaderboard ubuntu-latest-4 256 1 1 - add game_components_metagame registration ubuntu-latest-4 256 1 1 - add game_components_metagame entry_requirement ubuntu-latest-4 256 1 1 - add game_components_metagame entry_fee ubuntu-latest-4 256 1 1 - add game_components_metagame prize ubuntu-latest-4 256 1 1 - add game_components_metagame ticket_booth ubuntu-latest-4 256 1 1 + for p in 1 2; do + add game_components_metagame leaderboard ubuntu-latest-4 256 "$p" 2 + add game_components_metagame registration ubuntu-latest-4 256 "$p" 2 + add game_components_metagame entry_requirement ubuntu-latest-4 256 "$p" 2 + add game_components_metagame entry_fee ubuntu-latest-4 256 "$p" 2 + add game_components_metagame prize ubuntu-latest-4 256 "$p" 2 + add game_components_metagame ticket_booth ubuntu-latest-4 256 "$p" 2 + done fi if [ "$NEED_ECONOMY" = "true" ]; then - add game_components_economy tokenomics ubuntu-latest-4 256 1 1 + for p in 1 2; do + add game_components_economy tokenomics ubuntu-latest-4 256 "$p" 2 + done fi if [ "$NEED_UTILITIES" = "true" ]; then - add game_components_utilities math ubuntu-latest-4 256 1 1 + for p in 1 2; do + add game_components_utilities math ubuntu-latest-4 256 "$p" 2 + add game_components_utilities utils ubuntu-latest-4 256 "$p" 2 + add game_components_utilities renderer ubuntu-latest-4 256 "$p" 2 + done add game_components_utilities distribution ubuntu-latest-4 256 1 1 - add game_components_utilities utils ubuntu-latest-4 256 1 1 - add game_components_utilities renderer ubuntu-latest-4 256 1 1 fi if [ "$NEED_PRESETS" = "true" ]; then - add game_components_presets presets ubuntu-latest-4 256 1 1 + for p in 1 2; do + add game_components_presets presets ubuntu-latest-4 256 "$p" 2 + done fi MATRIX=$(echo "$INCLUDES" | jq -c '{include:.}') @@ -371,15 +379,6 @@ jobs: - name: Warm snforge plugin cache run: snforge --version - - name: Verify workspace compiles (no warnings) - run: | - scarb build --workspace 2>&1 | tee /tmp/build.log - if grep -qE '^ --> .*\.cairo:[0-9]+:[0-9]+' /tmp/build.log; then - echo "::error::Build produced compiler warnings. Fix all warnings before merging." - grep -B1 -E '^ --> .*\.cairo:[0-9]+:[0-9]+' /tmp/build.log - exit 1 - fi - test: name: test (${{ matrix.module }}${{ matrix.total_partitions > 1 && format(' {0}/{1}', matrix.partition, matrix.total_partitions) || '' }}) needs: [changes, setup] diff --git a/AGENTS.md b/AGENTS.md index 3defd1b..6b34df6 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -128,12 +128,12 @@ When adding a new module to a group package, update **both** files: 2. **`codecov.yml`** - Update the build count: ```yaml notify: - after_n_builds: 22 # ← Must equal total matrix entry count (including partitions) + after_n_builds: 33 # ← Must equal total matrix entry count (including partitions) ``` -### Current Matrix (22 jobs across 16 modules) +### Current Matrix (33 jobs across 16 modules) -Heavy EGS modules are partitioned via `snforge --partition` for parallelism on cheaper runners. +All modules >60s are partitioned via `snforge --partition` for parallelism. | Group Package | Module | Runner | Fuzzer Runs | Partitions | |---------------|--------|--------|-------------|------------| @@ -141,15 +141,15 @@ Heavy EGS modules are partitioned via `snforge --partition` for parallelism on c | `embeddable_game_standard` | `minigame` | `ubuntu-latest-4` | 64 | 2 | | `embeddable_game_standard` | `metagame` | `ubuntu-latest-4` | 64 | 2 | | `embeddable_game_standard` | `registry` | `ubuntu-latest-4` | 64 | 2 | -| `metagame` | `leaderboard` | `ubuntu-latest-4` | 256 | 1 | -| `metagame` | `registration` | `ubuntu-latest-4` | 256 | 1 | -| `metagame` | `entry_requirement` | `ubuntu-latest-4` | 256 | 1 | -| `metagame` | `entry_fee` | `ubuntu-latest-4` | 256 | 1 | -| `metagame` | `prize` | `ubuntu-latest-4` | 256 | 1 | -| `metagame` | `ticket_booth` | `ubuntu-latest-4` | 256 | 1 | -| `economy` | `tokenomics` | `ubuntu-latest-4` | 256 | 1 | -| `utilities` | `math` | `ubuntu-latest-4` | 256 | 1 | +| `metagame` | `leaderboard` | `ubuntu-latest-4` | 256 | 2 | +| `metagame` | `registration` | `ubuntu-latest-4` | 256 | 2 | +| `metagame` | `entry_requirement` | `ubuntu-latest-4` | 256 | 2 | +| `metagame` | `entry_fee` | `ubuntu-latest-4` | 256 | 2 | +| `metagame` | `prize` | `ubuntu-latest-4` | 256 | 2 | +| `metagame` | `ticket_booth` | `ubuntu-latest-4` | 256 | 2 | +| `economy` | `tokenomics` | `ubuntu-latest-4` | 256 | 2 | +| `utilities` | `math` | `ubuntu-latest-4` | 256 | 2 | | `utilities` | `distribution` | `ubuntu-latest-4` | 256 | 1 | -| `utilities` | `utils` | `ubuntu-latest-4` | 256 | 1 | -| `utilities` | `renderer` | `ubuntu-latest-4` | 256 | 1 | -| `presets` | `presets` | `ubuntu-latest-4` | 256 | 1 | +| `utilities` | `utils` | `ubuntu-latest-4` | 256 | 2 | +| `utilities` | `renderer` | `ubuntu-latest-4` | 256 | 2 | +| `presets` | `presets` | `ubuntu-latest-4` | 256 | 2 | diff --git a/codecov.yml b/codecov.yml index fb0f08f..2899e1b 100644 --- a/codecov.yml +++ b/codecov.yml @@ -4,7 +4,7 @@ codecov: # Must equal matrix entry count in .github/workflows/main-ci.yml # (partitioned modules count once per partition) # See AGENTS.md "CI Configuration" section when adding packages - after_n_builds: 22 + after_n_builds: 33 comment: layout: "diff, files, header, footer" From 9c86a4cb812c0a7b5149ea41b6f7e30840e90662 Mon Sep 17 00:00:00 2001 From: loothero Date: Sun, 8 Mar 2026 13:04:48 -0700 Subject: [PATCH 07/10] ci: use standard runners with proportional partitioning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace all non-standard runners (4-core, 8-core) with ubuntu-latest (standard 2-core) by scaling partition counts proportionally: - 4-core modules → 4× partitions (e.g., 2→8) - 8-core EGS modules → 8× partitions (e.g., 4→32 for token) Extract shared module catalog into module-catalog.sh sourced by both main-ci.yml and pr-ci.yml. Update snforge to v0.57.0 for --partition support. Total: 148 jobs across 16 modules, all on standard runners. Co-Authored-By: Claude Opus 4.6 --- .github/workflows/main-ci.yml | 247 +++------------------------- .github/workflows/module-catalog.sh | 65 ++++++++ .github/workflows/pr-ci.yml | 76 +++------ .tool-versions | 2 +- AGENTS.md | 67 ++++---- codecov.yml | 2 +- 6 files changed, 145 insertions(+), 314 deletions(-) create mode 100644 .github/workflows/module-catalog.sh diff --git a/.github/workflows/main-ci.yml b/.github/workflows/main-ci.yml index fb0418d..e5ac281 100644 --- a/.github/workflows/main-ci.yml +++ b/.github/workflows/main-ci.yml @@ -63,9 +63,13 @@ jobs: npx -y "$YAML_CLI" valid < codecov.yml fi - - name: Validate package count matches codecov config + - name: Validate matrix entry count matches codecov config run: | - matrix_count=$(grep -cE '^\s+module:' .github/workflows/main-ci.yml) + # Source the module catalog and count generated entries + source .github/workflows/module-catalog.sh + INCLUDES="[]" + add_all_modules + matrix_count=$(echo "$INCLUDES" | jq 'length') codecov_count=$(grep 'after_n_builds:' codecov.yml | grep -oE '[0-9]+') echo "Matrix entries: $matrix_count" @@ -101,9 +105,22 @@ jobs: if: needs.changes.outputs.packages == 'true' runs-on: ubuntu-latest timeout-minutes: 5 + outputs: + test_matrix: ${{ steps.build-matrix.outputs.test_matrix }} steps: - uses: actions/checkout@v6 + - name: Build test matrix + id: build-matrix + run: | + source .github/workflows/module-catalog.sh + INCLUDES="[]" + add_all_modules + + MATRIX=$(echo "$INCLUDES" | jq -c '{include:.}') + echo "test_matrix=$MATRIX" >> "$GITHUB_OUTPUT" + echo "Matrix: $(echo "$INCLUDES" | jq 'length') entries" + - name: Extract tool versions run: | echo "SCARB_VERSION=$(grep '^scarb ' .tool-versions | awk '{print $2}')" >> "$GITHUB_ENV" @@ -143,224 +160,11 @@ jobs: test: name: test (${{ matrix.module }}${{ matrix.total_partitions > 1 && format(' {0}/{1}', matrix.partition, matrix.total_partitions) || '' }}) needs: setup - runs-on: ${{ matrix.runner }} + runs-on: ubuntu-latest timeout-minutes: 10 strategy: fail-fast: true - matrix: - # NOTE: When adding/removing modules, also update: - # - codecov.yml: after_n_builds must equal matrix entry count - # - AGENTS.md: CI Configuration section - # Partitioned modules use snforge --partition INDEX/TOTAL to split - # tests across multiple cheaper runners for parallelism. - include: - # Embeddable Game Standard — partitioned for parallelism - # token: 4 partitions (~159 tests each) - - package: game_components_embeddable_game_standard - module: token - runner: ubuntu-latest-8 - fuzzer_runs: 64 - partition: 1 - total_partitions: 4 - - package: game_components_embeddable_game_standard - module: token - runner: ubuntu-latest-8 - fuzzer_runs: 64 - partition: 2 - total_partitions: 4 - - package: game_components_embeddable_game_standard - module: token - runner: ubuntu-latest-8 - fuzzer_runs: 64 - partition: 3 - total_partitions: 4 - - package: game_components_embeddable_game_standard - module: token - runner: ubuntu-latest-8 - fuzzer_runs: 64 - partition: 4 - total_partitions: 4 - # minigame: 2 partitions (~107 tests each) - - package: game_components_embeddable_game_standard - module: minigame - runner: ubuntu-latest-4 - fuzzer_runs: 64 - partition: 1 - total_partitions: 2 - - package: game_components_embeddable_game_standard - module: minigame - runner: ubuntu-latest-4 - fuzzer_runs: 64 - partition: 2 - total_partitions: 2 - # metagame: 2 partitions (~40 tests each) - - package: game_components_embeddable_game_standard - module: metagame - runner: ubuntu-latest-4 - fuzzer_runs: 64 - partition: 1 - total_partitions: 2 - - package: game_components_embeddable_game_standard - module: metagame - runner: ubuntu-latest-4 - fuzzer_runs: 64 - partition: 2 - total_partitions: 2 - # registry: 2 partitions (~69 tests each) - - package: game_components_embeddable_game_standard - module: registry - runner: ubuntu-latest-4 - fuzzer_runs: 64 - partition: 1 - total_partitions: 2 - - package: game_components_embeddable_game_standard - module: registry - runner: ubuntu-latest-4 - fuzzer_runs: 64 - partition: 2 - total_partitions: 2 - # Metagame — all partitioned (2 each) - - package: game_components_metagame - module: leaderboard - runner: ubuntu-latest-4 - fuzzer_runs: 256 - partition: 1 - total_partitions: 2 - - package: game_components_metagame - module: leaderboard - runner: ubuntu-latest-4 - fuzzer_runs: 256 - partition: 2 - total_partitions: 2 - - package: game_components_metagame - module: registration - runner: ubuntu-latest-4 - fuzzer_runs: 256 - partition: 1 - total_partitions: 2 - - package: game_components_metagame - module: registration - runner: ubuntu-latest-4 - fuzzer_runs: 256 - partition: 2 - total_partitions: 2 - - package: game_components_metagame - module: entry_requirement - runner: ubuntu-latest-4 - fuzzer_runs: 256 - partition: 1 - total_partitions: 2 - - package: game_components_metagame - module: entry_requirement - runner: ubuntu-latest-4 - fuzzer_runs: 256 - partition: 2 - total_partitions: 2 - - package: game_components_metagame - module: entry_fee - runner: ubuntu-latest-4 - fuzzer_runs: 256 - partition: 1 - total_partitions: 2 - - package: game_components_metagame - module: entry_fee - runner: ubuntu-latest-4 - fuzzer_runs: 256 - partition: 2 - total_partitions: 2 - - package: game_components_metagame - module: prize - runner: ubuntu-latest-4 - fuzzer_runs: 256 - partition: 1 - total_partitions: 2 - - package: game_components_metagame - module: prize - runner: ubuntu-latest-4 - fuzzer_runs: 256 - partition: 2 - total_partitions: 2 - - package: game_components_metagame - module: ticket_booth - runner: ubuntu-latest-4 - fuzzer_runs: 256 - partition: 1 - total_partitions: 2 - - package: game_components_metagame - module: ticket_booth - runner: ubuntu-latest-4 - fuzzer_runs: 256 - partition: 2 - total_partitions: 2 - # Economy - - package: game_components_economy - module: tokenomics - runner: ubuntu-latest-4 - fuzzer_runs: 256 - partition: 1 - total_partitions: 2 - - package: game_components_economy - module: tokenomics - runner: ubuntu-latest-4 - fuzzer_runs: 256 - partition: 2 - total_partitions: 2 - # Utilities — all partitioned except distribution - - package: game_components_utilities - module: math - runner: ubuntu-latest-4 - fuzzer_runs: 256 - partition: 1 - total_partitions: 2 - - package: game_components_utilities - module: math - runner: ubuntu-latest-4 - fuzzer_runs: 256 - partition: 2 - total_partitions: 2 - - package: game_components_utilities - module: distribution - runner: ubuntu-latest-4 - fuzzer_runs: 256 - partition: 1 - total_partitions: 1 - - package: game_components_utilities - module: utils - runner: ubuntu-latest-4 - fuzzer_runs: 256 - partition: 1 - total_partitions: 2 - - package: game_components_utilities - module: utils - runner: ubuntu-latest-4 - fuzzer_runs: 256 - partition: 2 - total_partitions: 2 - - package: game_components_utilities - module: renderer - runner: ubuntu-latest-4 - fuzzer_runs: 256 - partition: 1 - total_partitions: 2 - - package: game_components_utilities - module: renderer - runner: ubuntu-latest-4 - fuzzer_runs: 256 - partition: 2 - total_partitions: 2 - # Presets (standalone package, no module filter) - - package: game_components_presets - module: presets - runner: ubuntu-latest-4 - fuzzer_runs: 256 - partition: 1 - total_partitions: 2 - - package: game_components_presets - module: presets - runner: ubuntu-latest-4 - fuzzer_runs: 256 - partition: 2 - total_partitions: 2 + matrix: ${{ fromJson(needs.setup.outputs.test_matrix) }} steps: - uses: actions/checkout@v6 @@ -425,12 +229,13 @@ jobs: PARTITION_FLAG="--partition ${{ matrix.partition }}/${{ matrix.total_partitions }}" fi - if [ "${{ matrix.package }}" = "game_components_${{ matrix.module }}" ]; then - snforge test -p ${{ matrix.package }} --fuzzer-runs ${{ matrix.fuzzer_runs }} $PARTITION_FLAG --coverage 2>&1 | tee /tmp/test.log - else - snforge test -p ${{ matrix.package }} "::${{ matrix.module }}::" --fuzzer-runs ${{ matrix.fuzzer_runs }} $PARTITION_FLAG --coverage 2>&1 | tee /tmp/test.log + TEST_FILTER="" + if [ "${{ matrix.package }}" != "game_components_${{ matrix.module }}" ]; then + TEST_FILTER="::${{ matrix.module }}::" fi + snforge test -p ${{ matrix.package }} $TEST_FILTER --fuzzer-runs ${{ matrix.fuzzer_runs }} $PARTITION_FLAG --coverage 2>&1 | tee /tmp/test.log + - name: Check for compiler warnings if: always() && steps.cache-tools.outcome != 'failure' run: | diff --git a/.github/workflows/module-catalog.sh b/.github/workflows/module-catalog.sh new file mode 100644 index 0000000..cb3ee2c --- /dev/null +++ b/.github/workflows/module-catalog.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env bash +# Module catalog for CI test matrix generation. +# Sourced by both main-ci.yml and pr-ci.yml. +# +# All modules run on ubuntu-latest (standard 2-core runners). +# Partition counts are scaled to compensate: modules that previously +# needed 4-core runners get 4× partitions, 8-core get 8×. +# +# Usage: +# source .github/workflows/module-catalog.sh +# INCLUDES="[]" +# add_all_modules # or add selectively with add_egs, add_metagame, etc. +# echo "$INCLUDES" | jq . + +add() { + INCLUDES=$(echo "$INCLUDES" | jq -c \ + --arg p "$1" --arg m "$2" \ + --argjson f "$3" --argjson total "$4" \ + '. + [range($total) | {package:$p, module:$m, runner:"ubuntu-latest", fuzzer_runs:$f, partition:(. + 1), total_partitions:$total}]') +} + +# Embeddable Game Standard (previously 8-core or 4-core runners) +add_egs() { + add game_components_embeddable_game_standard token 64 32 # was 8-core × 4 → 32 partitions + add game_components_embeddable_game_standard minigame 64 8 # was 4-core × 2 → 8 partitions + add game_components_embeddable_game_standard metagame 64 8 # was 4-core × 2 → 8 partitions + add game_components_embeddable_game_standard registry 64 8 # was 4-core × 2 → 8 partitions +} + +# Metagame extensions (previously 4-core runners) +add_metagame() { + add game_components_metagame leaderboard 256 8 + add game_components_metagame registration 256 8 + add game_components_metagame entry_requirement 256 8 + add game_components_metagame entry_fee 256 8 + add game_components_metagame prize 256 8 + add game_components_metagame ticket_booth 256 8 +} + +# Economy (previously 4-core runner) +add_economy() { + add game_components_economy tokenomics 256 8 +} + +# Utilities (previously 4-core runners) +add_utilities() { + add game_components_utilities math 256 8 + add game_components_utilities distribution 256 4 + add game_components_utilities utils 256 8 + add game_components_utilities renderer 256 8 +} + +# Presets (previously 4-core runner) +add_presets() { + add game_components_presets presets 256 8 +} + +# All modules — used by main-ci.yml (always runs everything) +add_all_modules() { + add_egs + add_metagame + add_economy + add_utilities + add_presets +} diff --git a/.github/workflows/pr-ci.yml b/.github/workflows/pr-ci.yml index 000c548..48c7135 100644 --- a/.github/workflows/pr-ci.yml +++ b/.github/workflows/pr-ci.yml @@ -237,9 +237,13 @@ jobs: npx -y "$YAML_CLI" valid < codecov.yml fi - - name: Validate package count matches codecov config + - name: Validate matrix entry count matches codecov config run: | - matrix_count=$(grep -cE '^\s+module:' .github/workflows/main-ci.yml) + # Source the module catalog and count generated entries + source .github/workflows/module-catalog.sh + INCLUDES="[]" + add_all_modules + matrix_count=$(echo "$INCLUDES" | jq 'length') codecov_count=$(grep 'after_n_builds:' codecov.yml | grep -oE '[0-9]+') echo "Matrix entries: $matrix_count" @@ -289,59 +293,18 @@ jobs: NEED_UTILITIES: ${{ needs.changes.outputs.need_utilities }} NEED_PRESETS: ${{ needs.changes.outputs.need_presets }} run: | - # Build JSON matrix from per-package boolean flags - # Module catalog must match main-ci.yml (including partitions) + source .github/workflows/module-catalog.sh INCLUDES="[]" - add() { - INCLUDES=$(echo "$INCLUDES" | jq -c \ - --arg p "$1" --arg m "$2" --arg r "$3" \ - --argjson f "$4" --argjson part "$5" --argjson total "$6" \ - '. + [{package:$p,module:$m,runner:$r,fuzzer_runs:$f,partition:$part,total_partitions:$total}]') - } - - if [ "$NEED_EGS" = "true" ]; then - for p in 1 2 3 4; do - add game_components_embeddable_game_standard token ubuntu-latest-8 64 "$p" 4 - done - for p in 1 2; do - add game_components_embeddable_game_standard minigame ubuntu-latest-4 64 "$p" 2 - add game_components_embeddable_game_standard metagame ubuntu-latest-4 64 "$p" 2 - add game_components_embeddable_game_standard registry ubuntu-latest-4 64 "$p" 2 - done - fi - if [ "$NEED_METAGAME" = "true" ]; then - for p in 1 2; do - add game_components_metagame leaderboard ubuntu-latest-4 256 "$p" 2 - add game_components_metagame registration ubuntu-latest-4 256 "$p" 2 - add game_components_metagame entry_requirement ubuntu-latest-4 256 "$p" 2 - add game_components_metagame entry_fee ubuntu-latest-4 256 "$p" 2 - add game_components_metagame prize ubuntu-latest-4 256 "$p" 2 - add game_components_metagame ticket_booth ubuntu-latest-4 256 "$p" 2 - done - fi - if [ "$NEED_ECONOMY" = "true" ]; then - for p in 1 2; do - add game_components_economy tokenomics ubuntu-latest-4 256 "$p" 2 - done - fi - if [ "$NEED_UTILITIES" = "true" ]; then - for p in 1 2; do - add game_components_utilities math ubuntu-latest-4 256 "$p" 2 - add game_components_utilities utils ubuntu-latest-4 256 "$p" 2 - add game_components_utilities renderer ubuntu-latest-4 256 "$p" 2 - done - add game_components_utilities distribution ubuntu-latest-4 256 1 1 - fi - if [ "$NEED_PRESETS" = "true" ]; then - for p in 1 2; do - add game_components_presets presets ubuntu-latest-4 256 "$p" 2 - done - fi + + [ "$NEED_EGS" = "true" ] && add_egs + [ "$NEED_METAGAME" = "true" ] && add_metagame + [ "$NEED_ECONOMY" = "true" ] && add_economy + [ "$NEED_UTILITIES" = "true" ] && add_utilities + [ "$NEED_PRESETS" = "true" ] && add_presets MATRIX=$(echo "$INCLUDES" | jq -c '{include:.}') echo "test_matrix=$MATRIX" >> "$GITHUB_OUTPUT" - echo "Matrix: $(echo "$INCLUDES" | jq 'length') modules" - echo "$MATRIX" | jq . + echo "Matrix: $(echo "$INCLUDES" | jq 'length') entries" - name: Extract tool versions run: | @@ -383,7 +346,7 @@ jobs: name: test (${{ matrix.module }}${{ matrix.total_partitions > 1 && format(' {0}/{1}', matrix.partition, matrix.total_partitions) || '' }}) needs: [changes, setup] if: needs.changes.outputs.has_tests == 'true' - runs-on: ${{ matrix.runner }} + runs-on: ubuntu-latest timeout-minutes: 10 strategy: fail-fast: true @@ -452,12 +415,13 @@ jobs: PARTITION_FLAG="--partition ${{ matrix.partition }}/${{ matrix.total_partitions }}" fi - if [ "${{ matrix.package }}" = "game_components_${{ matrix.module }}" ]; then - snforge test -p ${{ matrix.package }} --fuzzer-runs ${{ matrix.fuzzer_runs }} $PARTITION_FLAG --coverage 2>&1 | tee /tmp/test.log - else - snforge test -p ${{ matrix.package }} "::${{ matrix.module }}::" --fuzzer-runs ${{ matrix.fuzzer_runs }} $PARTITION_FLAG --coverage 2>&1 | tee /tmp/test.log + TEST_FILTER="" + if [ "${{ matrix.package }}" != "game_components_${{ matrix.module }}" ]; then + TEST_FILTER="::${{ matrix.module }}::" fi + snforge test -p ${{ matrix.package }} $TEST_FILTER --fuzzer-runs ${{ matrix.fuzzer_runs }} $PARTITION_FLAG --coverage 2>&1 | tee /tmp/test.log + - name: Check for compiler warnings if: always() && steps.cache-tools.outcome != 'failure' run: | diff --git a/.tool-versions b/.tool-versions index e9cb626..5cdf476 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,4 +1,4 @@ rust 1.89.0 scarb 2.15.1 -starknet-foundry 0.55.0 +starknet-foundry 0.57.0 voyager 2.2.0 \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md index 6b34df6..63df5e3 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -23,7 +23,7 @@ You are a **senior Starknet smart contract engineer** specializing in Cairo deve ## Technology Stack -- **Cairo**: 2.15.1 | **Starknet**: 2.15.1 | **snforge**: v0.55.0 | **OpenZeppelin**: v3.0.0 +- **Cairo**: 2.15.1 | **Starknet**: 2.15.1 | **snforge**: v0.57.0 | **OpenZeppelin**: v3.0.0 ## Build Commands @@ -110,46 +110,43 @@ When adding a new group package or changing a workspace-level dependency in the ### Adding a New Module -When adding a new module to a group package, update **both** files: +When adding a new module to a group package, update **three** files: -1. **`.github/workflows/main-ci.yml`** and **`.github/workflows/pr-ci.yml`** - Add the module to both matrices: +1. **`.github/workflows/module-catalog.sh`** — Add the module to the appropriate `add_*` function: - ```yaml - matrix: - include: - - package: game_components_GROUP_PACKAGE - module: NEW_MODULE - runner: ubuntu-latest - fuzzer_runs: 256 + ```bash + add game_components_GROUP_PACKAGE NEW_MODULE 256 8 # fuzzer_runs partitions ``` - For memory-intensive modules (like `token` or `minigame`), assign a larger runner (e.g., `ubuntu-latest-4` or `ubuntu-latest-8`) and consider partitioning with `--partition INDEX/TOTAL`. + All modules run on `ubuntu-latest` (standard 2-core runners). Compensate by increasing partition count: modules that previously needed 4-core runners get 4 partitions, 8-core get 8, etc. -2. **`codecov.yml`** - Update the build count: +2. **`codecov.yml`** — Update the build count: ```yaml notify: - after_n_builds: 33 # ← Must equal total matrix entry count (including partitions) + after_n_builds: 148 # ← Must equal total matrix entry count (including partitions) ``` -### Current Matrix (33 jobs across 16 modules) - -All modules >60s are partitioned via `snforge --partition` for parallelism. - -| Group Package | Module | Runner | Fuzzer Runs | Partitions | -|---------------|--------|--------|-------------|------------| -| `embeddable_game_standard` | `token` | `ubuntu-latest-8` | 64 | 4 | -| `embeddable_game_standard` | `minigame` | `ubuntu-latest-4` | 64 | 2 | -| `embeddable_game_standard` | `metagame` | `ubuntu-latest-4` | 64 | 2 | -| `embeddable_game_standard` | `registry` | `ubuntu-latest-4` | 64 | 2 | -| `metagame` | `leaderboard` | `ubuntu-latest-4` | 256 | 2 | -| `metagame` | `registration` | `ubuntu-latest-4` | 256 | 2 | -| `metagame` | `entry_requirement` | `ubuntu-latest-4` | 256 | 2 | -| `metagame` | `entry_fee` | `ubuntu-latest-4` | 256 | 2 | -| `metagame` | `prize` | `ubuntu-latest-4` | 256 | 2 | -| `metagame` | `ticket_booth` | `ubuntu-latest-4` | 256 | 2 | -| `economy` | `tokenomics` | `ubuntu-latest-4` | 256 | 2 | -| `utilities` | `math` | `ubuntu-latest-4` | 256 | 2 | -| `utilities` | `distribution` | `ubuntu-latest-4` | 256 | 1 | -| `utilities` | `utils` | `ubuntu-latest-4` | 256 | 2 | -| `utilities` | `renderer` | `ubuntu-latest-4` | 256 | 2 | -| `presets` | `presets` | `ubuntu-latest-4` | 256 | 2 | +3. **`.github/workflows/pr-ci.yml`** — If adding a new group package, add it to the `compute-matrix` dependency graph and the `NEED_*` flags in the `build-matrix` step. + +### Current Matrix (148 jobs across 16 modules) + +All modules use `ubuntu-latest` (standard 2-core) runners with partitioning for parallelism. The shared module catalog is defined in `.github/workflows/module-catalog.sh`. + +| Group Package | Module | Fuzzer Runs | Partitions | +|---------------|--------|-------------|------------| +| `embeddable_game_standard` | `token` | 64 | 32 | +| `embeddable_game_standard` | `minigame` | 64 | 8 | +| `embeddable_game_standard` | `metagame` | 64 | 8 | +| `embeddable_game_standard` | `registry` | 64 | 8 | +| `metagame` | `leaderboard` | 256 | 8 | +| `metagame` | `registration` | 256 | 8 | +| `metagame` | `entry_requirement` | 256 | 8 | +| `metagame` | `entry_fee` | 256 | 8 | +| `metagame` | `prize` | 256 | 8 | +| `metagame` | `ticket_booth` | 256 | 8 | +| `economy` | `tokenomics` | 256 | 8 | +| `utilities` | `math` | 256 | 8 | +| `utilities` | `distribution` | 256 | 4 | +| `utilities` | `utils` | 256 | 8 | +| `utilities` | `renderer` | 256 | 8 | +| `presets` | `presets` | 256 | 8 | diff --git a/codecov.yml b/codecov.yml index 2899e1b..4d7be5d 100644 --- a/codecov.yml +++ b/codecov.yml @@ -4,7 +4,7 @@ codecov: # Must equal matrix entry count in .github/workflows/main-ci.yml # (partitioned modules count once per partition) # See AGENTS.md "CI Configuration" section when adding packages - after_n_builds: 33 + after_n_builds: 148 comment: layout: "diff, files, header, footer" From b35fecdf2056eaf3244fe65972cdc9d628329fb3 Mon Sep 17 00:00:00 2001 From: loothero Date: Sun, 8 Mar 2026 13:05:42 -0700 Subject: [PATCH 08/10] fix: avoid set -e failure in conditional add_* calls GitHub Actions runs bash with set -eo pipefail. The pattern `[ cond ] && fn` exits 1 when the condition is false, killing the step. Use if/then/fi instead. Co-Authored-By: Claude Opus 4.6 --- .github/workflows/pr-ci.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pr-ci.yml b/.github/workflows/pr-ci.yml index 48c7135..49e08a7 100644 --- a/.github/workflows/pr-ci.yml +++ b/.github/workflows/pr-ci.yml @@ -296,11 +296,11 @@ jobs: source .github/workflows/module-catalog.sh INCLUDES="[]" - [ "$NEED_EGS" = "true" ] && add_egs - [ "$NEED_METAGAME" = "true" ] && add_metagame - [ "$NEED_ECONOMY" = "true" ] && add_economy - [ "$NEED_UTILITIES" = "true" ] && add_utilities - [ "$NEED_PRESETS" = "true" ] && add_presets + if [ "$NEED_EGS" = "true" ]; then add_egs; fi + if [ "$NEED_METAGAME" = "true" ]; then add_metagame; fi + if [ "$NEED_ECONOMY" = "true" ]; then add_economy; fi + if [ "$NEED_UTILITIES" = "true" ]; then add_utilities; fi + if [ "$NEED_PRESETS" = "true" ]; then add_presets; fi MATRIX=$(echo "$INCLUDES" | jq -c '{include:.}') echo "test_matrix=$MATRIX" >> "$GITHUB_OUTPUT" From e8ed76f8d8cc07f5abfc40815ff6a11b50f6a73a Mon Sep 17 00:00:00 2001 From: loothero Date: Sun, 8 Mar 2026 13:12:33 -0700 Subject: [PATCH 09/10] fix: update snforge_std dependency to v0.57.0 The snforge CLI was updated to 0.57.0 in .tool-versions but the snforge_std library dependency in Scarb.toml was still pinned to v0.55.0, causing a version mismatch warning. Co-Authored-By: Claude Opus 4.6 --- Scarb.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scarb.toml b/Scarb.toml index 1cfd6a6..e38665c 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -31,7 +31,7 @@ keywords = [ [workspace.dependencies] starknet = "2.15.1" -snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry", tag = "v0.55.0" } +snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry", tag = "v0.57.0" } openzeppelin_access = { git = "https://github.com/OpenZeppelin/cairo-contracts.git", tag = "v3.0.0" } openzeppelin_introspection = { git = "https://github.com/OpenZeppelin/cairo-contracts.git", tag = "v3.0.0" } openzeppelin_token = { git = "https://github.com/OpenZeppelin/cairo-contracts.git", tag = "v3.0.0" } From 33a266bc8341b7f7e2af7a78cc057921a4feef26 Mon Sep 17 00:00:00 2001 From: loothero Date: Sun, 8 Mar 2026 13:17:28 -0700 Subject: [PATCH 10/10] ci: cap partitions at 8 max, use 4 for smaller modules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Scale partition counts to match original runner sizes: - 32-core/8-core modules (EGS) → 8 partitions - 4-core modules (all others) → 4 partitions Total: 80 jobs across 16 modules, all on standard runners. Co-Authored-By: Claude Opus 4.6 --- .github/workflows/module-catalog.sh | 45 +++++++++++++++-------------- AGENTS.md | 28 +++++++++--------- codecov.yml | 2 +- 3 files changed, 38 insertions(+), 37 deletions(-) diff --git a/.github/workflows/module-catalog.sh b/.github/workflows/module-catalog.sh index cb3ee2c..7caae5f 100644 --- a/.github/workflows/module-catalog.sh +++ b/.github/workflows/module-catalog.sh @@ -3,8 +3,9 @@ # Sourced by both main-ci.yml and pr-ci.yml. # # All modules run on ubuntu-latest (standard 2-core runners). -# Partition counts are scaled to compensate: modules that previously -# needed 4-core runners get 4× partitions, 8-core get 8×. +# Partition counts compensate for smaller runners: +# was 32-core or 8-core → 8 partitions +# was 4-core → 4 partitions # # Usage: # source .github/workflows/module-catalog.sh @@ -19,40 +20,40 @@ add() { '. + [range($total) | {package:$p, module:$m, runner:"ubuntu-latest", fuzzer_runs:$f, partition:(. + 1), total_partitions:$total}]') } -# Embeddable Game Standard (previously 8-core or 4-core runners) +# Embeddable Game Standard (previously 32-core / 8-core runners → 8 partitions) add_egs() { - add game_components_embeddable_game_standard token 64 32 # was 8-core × 4 → 32 partitions - add game_components_embeddable_game_standard minigame 64 8 # was 4-core × 2 → 8 partitions - add game_components_embeddable_game_standard metagame 64 8 # was 4-core × 2 → 8 partitions - add game_components_embeddable_game_standard registry 64 8 # was 4-core × 2 → 8 partitions + add game_components_embeddable_game_standard token 64 8 + add game_components_embeddable_game_standard minigame 64 8 + add game_components_embeddable_game_standard metagame 64 8 + add game_components_embeddable_game_standard registry 64 8 } -# Metagame extensions (previously 4-core runners) +# Metagame extensions (previously 4-core runners → 4 partitions) add_metagame() { - add game_components_metagame leaderboard 256 8 - add game_components_metagame registration 256 8 - add game_components_metagame entry_requirement 256 8 - add game_components_metagame entry_fee 256 8 - add game_components_metagame prize 256 8 - add game_components_metagame ticket_booth 256 8 + add game_components_metagame leaderboard 256 4 + add game_components_metagame registration 256 4 + add game_components_metagame entry_requirement 256 4 + add game_components_metagame entry_fee 256 4 + add game_components_metagame prize 256 4 + add game_components_metagame ticket_booth 256 4 } -# Economy (previously 4-core runner) +# Economy (previously 4-core runner → 4 partitions) add_economy() { - add game_components_economy tokenomics 256 8 + add game_components_economy tokenomics 256 4 } -# Utilities (previously 4-core runners) +# Utilities (previously 4-core runners → 4 partitions) add_utilities() { - add game_components_utilities math 256 8 + add game_components_utilities math 256 4 add game_components_utilities distribution 256 4 - add game_components_utilities utils 256 8 - add game_components_utilities renderer 256 8 + add game_components_utilities utils 256 4 + add game_components_utilities renderer 256 4 } -# Presets (previously 4-core runner) +# Presets (previously 4-core runner → 4 partitions) add_presets() { - add game_components_presets presets 256 8 + add game_components_presets presets 256 4 } # All modules — used by main-ci.yml (always runs everything) diff --git a/AGENTS.md b/AGENTS.md index 63df5e3..8cee5de 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -123,30 +123,30 @@ When adding a new module to a group package, update **three** files: 2. **`codecov.yml`** — Update the build count: ```yaml notify: - after_n_builds: 148 # ← Must equal total matrix entry count (including partitions) + after_n_builds: 80 # ← Must equal total matrix entry count (including partitions) ``` 3. **`.github/workflows/pr-ci.yml`** — If adding a new group package, add it to the `compute-matrix` dependency graph and the `NEED_*` flags in the `build-matrix` step. -### Current Matrix (148 jobs across 16 modules) +### Current Matrix (80 jobs across 16 modules) All modules use `ubuntu-latest` (standard 2-core) runners with partitioning for parallelism. The shared module catalog is defined in `.github/workflows/module-catalog.sh`. | Group Package | Module | Fuzzer Runs | Partitions | |---------------|--------|-------------|------------| -| `embeddable_game_standard` | `token` | 64 | 32 | +| `embeddable_game_standard` | `token` | 64 | 8 | | `embeddable_game_standard` | `minigame` | 64 | 8 | | `embeddable_game_standard` | `metagame` | 64 | 8 | | `embeddable_game_standard` | `registry` | 64 | 8 | -| `metagame` | `leaderboard` | 256 | 8 | -| `metagame` | `registration` | 256 | 8 | -| `metagame` | `entry_requirement` | 256 | 8 | -| `metagame` | `entry_fee` | 256 | 8 | -| `metagame` | `prize` | 256 | 8 | -| `metagame` | `ticket_booth` | 256 | 8 | -| `economy` | `tokenomics` | 256 | 8 | -| `utilities` | `math` | 256 | 8 | +| `metagame` | `leaderboard` | 256 | 4 | +| `metagame` | `registration` | 256 | 4 | +| `metagame` | `entry_requirement` | 256 | 4 | +| `metagame` | `entry_fee` | 256 | 4 | +| `metagame` | `prize` | 256 | 4 | +| `metagame` | `ticket_booth` | 256 | 4 | +| `economy` | `tokenomics` | 256 | 4 | +| `utilities` | `math` | 256 | 4 | | `utilities` | `distribution` | 256 | 4 | -| `utilities` | `utils` | 256 | 8 | -| `utilities` | `renderer` | 256 | 8 | -| `presets` | `presets` | 256 | 8 | +| `utilities` | `utils` | 256 | 4 | +| `utilities` | `renderer` | 256 | 4 | +| `presets` | `presets` | 256 | 4 | diff --git a/codecov.yml b/codecov.yml index 4d7be5d..c52c513 100644 --- a/codecov.yml +++ b/codecov.yml @@ -4,7 +4,7 @@ codecov: # Must equal matrix entry count in .github/workflows/main-ci.yml # (partitioned modules count once per partition) # See AGENTS.md "CI Configuration" section when adding packages - after_n_builds: 148 + after_n_builds: 80 comment: layout: "diff, files, header, footer"