code-foundry 1.41.0 → 1.42.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -38,6 +38,16 @@ on:
38
38
  required: false
39
39
  type: string
40
40
  default: task-result
41
+ e2e-shard-list:
42
+ description: Comma-separated E2E shard indices, for example "1,2". A single index runs one unsharded job.
43
+ required: false
44
+ type: string
45
+ default: '1'
46
+ e2e-total-shards:
47
+ description: Total E2E shard count handed to the repository script as E2E_TOTAL_SHARDS.
48
+ required: false
49
+ type: string
50
+ default: '1'
41
51
  secrets:
42
52
  TURBO_TOKEN:
43
53
  required: false
@@ -309,6 +319,14 @@ jobs:
309
319
  if: vars.CI_BILLING_PAUSED != 'true' && inputs.unit-only != true
310
320
  runs-on: ${{ inputs.runner }}
311
321
  timeout-minutes: 45
322
+ # Shards duplicate the whole job, but each shard owns a runner-local test
323
+ # database (repositories without DATABASE_URL fall back to their own local
324
+ # compose services), so shards stay isolated. A single-entry matrix keeps
325
+ # the unsharded default byte-compatible with the pre-matrix job.
326
+ strategy:
327
+ fail-fast: false
328
+ matrix:
329
+ shard: ${{ fromJson(format('[{0}]', inputs.e2e-shard-list)) }}
312
330
  steps:
313
331
  - name: Checkout
314
332
  uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
@@ -371,6 +389,9 @@ jobs:
371
389
  - name: E2E
372
390
  id: execute
373
391
  if: steps.applicability.outputs.applicable == 'true' && steps.applicability.outputs.affected != 'false'
392
+ env:
393
+ E2E_SHARD_INDEX: ${{ matrix.shard }}
394
+ E2E_TOTAL_SHARDS: ${{ inputs.e2e-total-shards }}
374
395
  run: node "$RUNNER_TEMP/code-foundry/src/runtime.mjs" ci e2e
375
396
  - name: Retain task receipt
376
397
  if: >-
@@ -380,7 +401,7 @@ jobs:
380
401
  hashFiles('.code-foundry/results/e2e.json') != ''
381
402
  uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
382
403
  with:
383
- name: ${{ inputs.artifact-prefix }}-${{ github.run_id }}-${{ github.run_attempt }}-e2e
404
+ name: ${{ inputs.artifact-prefix }}-${{ github.run_id }}-${{ github.run_attempt }}-e2e${{ inputs.e2e-total-shards != '1' && format('-s{0}', matrix.shard) || '' }}
384
405
  path: .code-foundry/results/e2e.json
385
406
  include-hidden-files: true
386
407
  if-no-files-found: error
@@ -70,6 +70,16 @@ on:
70
70
  required: false
71
71
  type: number
72
72
  default: 1
73
+ e2e-shard-list:
74
+ description: Comma-separated E2E shard indices passed to the test lane's matrix, e.g. "1,2".
75
+ required: false
76
+ type: string
77
+ default: '1'
78
+ e2e-total-shards:
79
+ description: Total E2E shard count passed to the repository script as E2E_TOTAL_SHARDS.
80
+ required: false
81
+ type: string
82
+ default: '1'
73
83
  artifact-prefix:
74
84
  description: Prefix for task receipts; use a unique value when calling this workflow more than once.
75
85
  required: false
@@ -119,6 +129,8 @@ jobs:
119
129
  # smoke, and performance lanes stay in the audit and scheduled lanes.
120
130
  unit-only: ${{ inputs.mode == 'fast' || inputs.mode == 'release' }}
121
131
  artifact-prefix: ${{ inputs.artifact-prefix }}
132
+ e2e-shard-list: ${{ inputs.e2e-shard-list }}
133
+ e2e-total-shards: ${{ inputs.e2e-total-shards }}
122
134
  secrets:
123
135
  TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
124
136
 
@@ -95,6 +95,10 @@ jobs:
95
95
  rust-shards: '["all"]'
96
96
  rust-threads: '1'
97
97
  rust-max-parallel: 1
98
+ # The sync renderer rewrites both values from the e2e_shards config key;
99
+ # the defaults keep repositories without that key on one unsharded job.
100
+ e2e-shard-list: '1'
101
+ e2e-total-shards: '1'
98
102
  secrets:
99
103
  TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
100
104
  NEXTAUTH_SECRET: ${{ secrets.NEXTAUTH_SECRET }}
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.42.0](https://github.com/0xPlayerOne/code-foundry/compare/v1.41.0...v1.42.0) (2026-10-02)
4
+
5
+
6
+ ### Features
7
+
8
+ * **validation:** shard the managed E2E lane via e2e_shards ([#697](https://github.com/0xPlayerOne/code-foundry/issues/697)) ([edb20b4](https://github.com/0xPlayerOne/code-foundry/commit/edb20b4e32e2055bf22e6f6f94b51f234a24687d))
9
+
3
10
  ## [1.41.0](https://github.com/0xPlayerOne/code-foundry/compare/v1.40.0...v1.41.0) (2026-10-02)
4
11
 
5
12
 
@@ -115,25 +115,26 @@ See [Merge queue validation](merge-queues.md) before enabling it.
115
115
 
116
116
  ## Validation and quality
117
117
 
118
- | Key | Values | Purpose |
119
- | ------------------------- | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
120
- | `performance` | `auto`, `true`, `false` | Discover, require, or disable performance checks. |
121
- | `performance_command` | JSON argv array or array of argv arrays | Ordered commands for a non-package performance harness. |
122
- | `performance_profile` | empty or `node-package` | Shared package import, memory, archive, and dependency audit. |
123
- | `performance_budget_file` | repository-relative path | Budget file for `node-package`; defaults to `performance-package-budgets.json`. |
124
- | `eval` | `auto`, `true`, `false` | Discover, require, or disable the deterministic eval tier. |
125
- | `eval_command` | JSON argv array | Explicit harness command when there is no `eval` package script. |
126
- | `eval_report_file` | repository-relative path | Report validated against the eval contract; defaults to `eval-results/result.json`. |
127
- | `eval_budget_file` | repository-relative path | Optional budget file; defaults to `eval-budgets.json`. |
128
- | `eval_runner` | runner label | Runner for the `Validation / Eval` lane; defaults to the repository runner. Browser evals need a Chrome-capable runner such as `ubuntu-latest`. |
129
- | `required_capabilities` | comma-separated task names | Fail closed when a required task or coverage evidence is unavailable. |
130
- | `coverage_enforcement` | `auto`, `required`, `off` | Shared coverage-report policy. |
131
- | `coverage_minimum` | `0`–`100` | Minimum percentage; defaults to `80`. |
132
- | `coverage_metrics` | `lines`, `functions`, `branches`, `statements` | Metrics checked by the coverage gate. |
133
- | `coverage_report` | comma-separated repository paths | Istanbul JSON summary or LCOV evidence files. |
134
- | `filter_<task>` | comma-separated repository path globs | Skip a lane when no changed path matches; see [Lane path filters](#lane-path-filters). |
135
- | `rust_sccache` | `true`, `false` | Install sccache and wrap rustc so compile artifacts survive manifest/lockfile churn. |
136
- | `rust_nextest` | `true`, `false` | Install cargo-nextest and prefer `cargo nextest run` over `cargo test` in Rust test lanes. |
118
+ | Key | Values | Purpose |
119
+ | ------------------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
120
+ | `performance` | `auto`, `true`, `false` | Discover, require, or disable performance checks. |
121
+ | `performance_command` | JSON argv array or array of argv arrays | Ordered commands for a non-package performance harness. |
122
+ | `performance_profile` | empty or `node-package` | Shared package import, memory, archive, and dependency audit. |
123
+ | `performance_budget_file` | repository-relative path | Budget file for `node-package`; defaults to `performance-package-budgets.json`. |
124
+ | `eval` | `auto`, `true`, `false` | Discover, require, or disable the deterministic eval tier. |
125
+ | `eval_command` | JSON argv array | Explicit harness command when there is no `eval` package script. |
126
+ | `eval_report_file` | repository-relative path | Report validated against the eval contract; defaults to `eval-results/result.json`. |
127
+ | `eval_budget_file` | repository-relative path | Optional budget file; defaults to `eval-budgets.json`. |
128
+ | `eval_runner` | runner label | Runner for the `Validation / Eval` lane; defaults to the repository runner. Browser evals need a Chrome-capable runner such as `ubuntu-latest`. |
129
+ | `required_capabilities` | comma-separated task names | Fail closed when a required task or coverage evidence is unavailable. |
130
+ | `coverage_enforcement` | `auto`, `required`, `off` | Shared coverage-report policy. |
131
+ | `coverage_minimum` | `0`–`100` | Minimum percentage; defaults to `80`. |
132
+ | `coverage_metrics` | `lines`, `functions`, `branches`, `statements` | Metrics checked by the coverage gate. |
133
+ | `coverage_report` | comma-separated repository paths | Istanbul JSON summary or LCOV evidence files. |
134
+ | `filter_<task>` | comma-separated repository path globs | Skip a lane when no changed path matches; see [Lane path filters](#lane-path-filters). |
135
+ | `rust_sccache` | `true`, `false` | Install sccache and wrap rustc so compile artifacts survive manifest/lockfile churn. |
136
+ | `rust_nextest` | `true`, `false` | Install cargo-nextest and prefer `cargo nextest run` over `cargo test` in Rust test lanes. |
137
+ | `e2e_shards` | `1`–`8` | Fan the `Validation / Test / E2E` job into one runner per shard. The repository's `test:e2e`/`e2e` script receives `E2E_SHARD_INDEX` and `E2E_TOTAL_SHARDS` and partitions itself (Playwright takes `--shard=$E2E_SHARD_INDEX/$E2E_TOTAL_SHARDS`); each shard owns a runner-local test database, so shards stay isolated. |
137
138
 
138
139
  Supported task capabilities are `format`, `lint`, `type_check`, `build`, `unit`,
139
140
  `integration`, `e2e`, `smoke`, `eval`, and `performance`. `coverage` is a policy
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "code-foundry",
3
- "version": "1.41.0",
3
+ "version": "1.42.0",
4
4
  "description": "A fast, language-aware repository factory for agent-ready workflows, testing, security, and release automation.",
5
5
  "homepage": "https://github.com/0xPlayerOne/code-foundry#readme",
6
6
  "bugs": {
@@ -738,6 +738,21 @@ function renderWorkflow(content, config, repository, ref, rustCodeql, file, self
738
738
  if (configured(config.draft_protection, 'true') === 'false') {
739
739
  rendered = rendered.replaceAll(' && github.event.pull_request.draft == false', '')
740
740
  }
741
+ // E2E sharding fans the managed E2E job into one runner per shard; shards
742
+ // stay isolated because each job owns a runner-local test database. Fail
743
+ // closed on a malformed count rather than silently rendering a single shard.
744
+ const e2eShards =
745
+ config.e2e_shards === undefined || config.e2e_shards === '' ? 1 : Number(config.e2e_shards)
746
+ if (!Number.isInteger(e2eShards) || e2eShards < 1 || e2eShards > 8) {
747
+ throw new Error(`Unsupported e2e_shards: ${config.e2e_shards}; use an integer between 1 and 8.`)
748
+ }
749
+ if (e2eShards > 1 && file === '.github/workflows/validation.yml') {
750
+ rendered = rendered.replace(
751
+ /^(\s+e2e-shard-list:)\s+.*$/gm,
752
+ `$1 ${Array.from({ length: e2eShards }, (_, index) => index + 1).join(',')}`
753
+ )
754
+ rendered = rendered.replace(/^(\s+e2e-total-shards:)\s+.*$/gm, `$1 ${e2eShards}`)
755
+ }
741
756
  // Consumer release callers are generic package release workflows. The
742
757
  // installed-consumer qualification harness is specific to Code Foundry's
743
758
  // own package and must remain in the self workflow rather than being