code-foundry 1.5.3 → 1.6.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.
- package/.github/CONTRIBUTING.md +1 -1
- package/.github/actions/setup/action.yml +2 -1
- package/.github/code-foundry.yml +3 -0
- package/.github/workflows/test.yml +70 -0
- package/.github/workflows/validation.yml +6 -0
- package/.github/workflows/validation_self-ci.yml +5 -1
- package/AGENTS.md +2 -1
- package/CHANGELOG.md +14 -0
- package/docs/CONFIGURATION.md +22 -1
- package/docs/WORKFLOWS.md +1 -1
- package/package.json +1 -1
- package/src/commands/sync.mjs +3 -0
- package/src/lib/profile.mjs +1 -0
- package/src/runtime.mjs +37 -0
package/.github/CONTRIBUTING.md
CHANGED
|
@@ -19,7 +19,7 @@ Agents must follow these rules before changing code:
|
|
|
19
19
|
3. Preserve user-owned changes. Never discard or overwrite unrelated work.
|
|
20
20
|
4. Branch from `staging` and target pull requests at `staging`; do not work directly on `main`.
|
|
21
21
|
5. Keep the change focused. Do not expand scope without documenting why.
|
|
22
|
-
6. Run the applicable format, lint, type-check, build, unit, integration, E2E, smoke, and security checks.
|
|
22
|
+
6. Run the applicable format, lint, type-check, build, unit, performance, integration, E2E, smoke, and security checks.
|
|
23
23
|
7. Report exact validation results, skipped checks, known limitations, and remaining risks.
|
|
24
24
|
8. Never commit secrets, credentials, local environment files, generated artifacts, or machine-specific paths.
|
|
25
25
|
|
|
@@ -129,6 +129,7 @@ runs:
|
|
|
129
129
|
integration: ['test:integration'],
|
|
130
130
|
e2e: ['test:e2e', 'e2e'],
|
|
131
131
|
smoke: ['test:smoke', 'smoke'],
|
|
132
|
+
performance: ['performance:check', 'perf:check'],
|
|
132
133
|
}[task] || [];
|
|
133
134
|
const selected = candidates.find((name) => scripts[name]);
|
|
134
135
|
const usesTurbo = Boolean(selected && /\bturbo(?:\s|$)/.test(scripts[selected]));
|
|
@@ -441,7 +442,7 @@ runs:
|
|
|
441
442
|
- name: Install native test libraries
|
|
442
443
|
if: >-
|
|
443
444
|
inputs.install == 'true' &&
|
|
444
|
-
inputs.task == 'unit' &&
|
|
445
|
+
(inputs.task == 'unit' || inputs.task == 'performance') &&
|
|
445
446
|
hashFiles('**/package.json') != '' &&
|
|
446
447
|
steps.profile.outputs.javascript == 'true'
|
|
447
448
|
shell: bash
|
package/.github/code-foundry.yml
CHANGED
|
@@ -20,6 +20,7 @@ merge_strategy: rebase
|
|
|
20
20
|
release_merge_strategy: rebase
|
|
21
21
|
runner: ubuntu-latest
|
|
22
22
|
unit_runner: ubuntu-slim
|
|
23
|
+
performance_runner: ubuntu-latest
|
|
23
24
|
cache_packages: auto
|
|
24
25
|
cache_build: auto
|
|
25
26
|
coverage_minimum: 80
|
|
@@ -38,4 +39,6 @@ opencode_security: false
|
|
|
38
39
|
sync_mode: overlay
|
|
39
40
|
custom_workflows: preserve
|
|
40
41
|
staging_validation_mode: fast
|
|
42
|
+
performance: auto
|
|
43
|
+
performance_command:
|
|
41
44
|
opencode_security_model:
|
|
@@ -23,6 +23,11 @@ on:
|
|
|
23
23
|
required: false
|
|
24
24
|
type: string
|
|
25
25
|
default: ubuntu-slim
|
|
26
|
+
performance-runner:
|
|
27
|
+
description: Runner used by deterministic performance regression checks.
|
|
28
|
+
required: false
|
|
29
|
+
type: string
|
|
30
|
+
default: ubuntu-latest
|
|
26
31
|
unit-only:
|
|
27
32
|
description: Run only the unit-test subset; skip integration, E2E, and smoke jobs.
|
|
28
33
|
required: false
|
|
@@ -117,6 +122,71 @@ jobs:
|
|
|
117
122
|
if-no-files-found: ignore
|
|
118
123
|
retention-days: 14
|
|
119
124
|
|
|
125
|
+
performance:
|
|
126
|
+
name: Performance
|
|
127
|
+
if: vars.CI_BILLING_PAUSED != 'true'
|
|
128
|
+
runs-on: ${{ inputs.performance-runner }}
|
|
129
|
+
timeout-minutes: 30
|
|
130
|
+
steps:
|
|
131
|
+
- name: Checkout
|
|
132
|
+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
133
|
+
with:
|
|
134
|
+
persist-credentials: false
|
|
135
|
+
fetch-depth: 2
|
|
136
|
+
- name: Runtime
|
|
137
|
+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
138
|
+
with:
|
|
139
|
+
persist-credentials: false
|
|
140
|
+
repository: ${{ inputs.runtime-repository }}
|
|
141
|
+
ref: ${{ inputs.runtime-ref }}
|
|
142
|
+
path: .github/.code-foundry
|
|
143
|
+
sparse-checkout: |
|
|
144
|
+
.github/actions
|
|
145
|
+
src/lib
|
|
146
|
+
src/runtime.mjs
|
|
147
|
+
- name: Install runtime
|
|
148
|
+
run: |
|
|
149
|
+
mkdir -p .github/actions
|
|
150
|
+
mv .github/.code-foundry "$RUNNER_TEMP/code-foundry"
|
|
151
|
+
cp -R "$RUNNER_TEMP/code-foundry/.github/actions/." .github/actions/
|
|
152
|
+
- name: Detect
|
|
153
|
+
id: applicability
|
|
154
|
+
run: node $RUNNER_TEMP/code-foundry/src/runtime.mjs ci task_profile performance >> "$GITHUB_OUTPUT"
|
|
155
|
+
- name: Setup
|
|
156
|
+
if: steps.applicability.outputs.applicable == 'true'
|
|
157
|
+
uses: ./.github/actions/setup
|
|
158
|
+
with:
|
|
159
|
+
install: true
|
|
160
|
+
install-javascript: ${{ steps.applicability.outputs.javascript == 'true' }}
|
|
161
|
+
install-python: ${{ steps.applicability.outputs.python == 'true' }}
|
|
162
|
+
install-rust: ${{ steps.applicability.outputs.rust == 'true' }}
|
|
163
|
+
cache-build: false
|
|
164
|
+
cache-environment: false
|
|
165
|
+
cache-save: false
|
|
166
|
+
cache-packages: ${{ vars.REPO_FOUNDRY_CACHE_PACKAGES || 'auto' }}
|
|
167
|
+
task: performance
|
|
168
|
+
task-javascript: ${{ steps.applicability.outputs.javascript }}
|
|
169
|
+
task-python: ${{ steps.applicability.outputs.python }}
|
|
170
|
+
task-rust: ${{ steps.applicability.outputs.rust }}
|
|
171
|
+
- name: Performance
|
|
172
|
+
if: steps.applicability.outputs.applicable == 'true'
|
|
173
|
+
run: node $RUNNER_TEMP/code-foundry/src/runtime.mjs ci performance
|
|
174
|
+
- name: Upload performance results
|
|
175
|
+
if: >-
|
|
176
|
+
always() &&
|
|
177
|
+
steps.applicability.outputs.applicable == 'true' &&
|
|
178
|
+
hashFiles('artifacts/performance/**', 'performance-results.json', 'performance-results/**') != ''
|
|
179
|
+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
|
180
|
+
with:
|
|
181
|
+
name: performance-${{ github.run_id }}
|
|
182
|
+
path: |
|
|
183
|
+
artifacts/performance/**
|
|
184
|
+
performance-results.json
|
|
185
|
+
performance-results/**
|
|
186
|
+
compression-level: 1
|
|
187
|
+
if-no-files-found: ignore
|
|
188
|
+
retention-days: 14
|
|
189
|
+
|
|
120
190
|
integration:
|
|
121
191
|
name: Integration
|
|
122
192
|
if: vars.CI_BILLING_PAUSED != 'true' && inputs.unit-only != true
|
|
@@ -32,6 +32,11 @@ on:
|
|
|
32
32
|
required: false
|
|
33
33
|
type: string
|
|
34
34
|
default: ubuntu-slim
|
|
35
|
+
performance-runner:
|
|
36
|
+
description: Runner used by deterministic performance regression checks.
|
|
37
|
+
required: false
|
|
38
|
+
type: string
|
|
39
|
+
default: ubuntu-latest
|
|
35
40
|
security-runner:
|
|
36
41
|
description: Runner used by Security jobs.
|
|
37
42
|
required: false
|
|
@@ -94,6 +99,7 @@ jobs:
|
|
|
94
99
|
runtime-ref: ${{ inputs.runtime-ref }}
|
|
95
100
|
runner: ${{ inputs.test-runner }}
|
|
96
101
|
unit-runner: ${{ inputs.unit-runner }}
|
|
102
|
+
performance-runner: ${{ inputs.performance-runner }}
|
|
97
103
|
unit-only: ${{ inputs.mode == 'fast' }}
|
|
98
104
|
secrets:
|
|
99
105
|
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
|
@@ -76,10 +76,14 @@ jobs:
|
|
|
76
76
|
with:
|
|
77
77
|
mode: ${{ needs.mode.outputs.mode }}
|
|
78
78
|
runtime-repository: 0xPlayerOne/code-foundry
|
|
79
|
-
runtime
|
|
79
|
+
# Pull requests validate the proposed runtime commit. Scheduled and
|
|
80
|
+
# manually dispatched audits stay on the protected default branch so a
|
|
81
|
+
# selected branch cannot supply privileged runtime code.
|
|
82
|
+
runtime-ref: ${{ github.event_name == 'pull_request' && github.sha || 'main' }}
|
|
80
83
|
ci-runner: ubuntu-latest
|
|
81
84
|
test-runner: ubuntu-latest
|
|
82
85
|
unit-runner: ubuntu-slim
|
|
86
|
+
performance-runner: ubuntu-latest
|
|
83
87
|
security-runner: ubuntu-slim
|
|
84
88
|
codeql-runner: ubuntu-latest
|
|
85
89
|
rust-shards: '["all"]'
|
package/AGENTS.md
CHANGED
|
@@ -120,6 +120,7 @@ node src/runtime.mjs ci unit
|
|
|
120
120
|
node src/runtime.mjs ci integration
|
|
121
121
|
node src/runtime.mjs ci e2e
|
|
122
122
|
node src/runtime.mjs ci smoke
|
|
123
|
+
node src/runtime.mjs ci performance
|
|
123
124
|
Security and dependency audits run through the GitHub Security workflow.
|
|
124
125
|
```
|
|
125
126
|
|
|
@@ -138,7 +139,7 @@ If a check cannot run, state the exact reason. A skipped check is not a passing
|
|
|
138
139
|
## Tests and coverage
|
|
139
140
|
|
|
140
141
|
- Add or update tests for behavior changes and regressions.
|
|
141
|
-
- Keep unit, integration, E2E, and smoke coverage in the suite where each applies.
|
|
142
|
+
- Keep unit, performance, integration, E2E, and smoke coverage in the suite where each applies.
|
|
142
143
|
- Preserve project-specific coverage thresholds; do not lower them to make CI green.
|
|
143
144
|
- Keep test data deterministic and remove secrets from logs and fixtures.
|
|
144
145
|
- Use the narrowest test command while iterating, then run the affected package or workspace suite.
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.6.0](https://github.com/0xPlayerOne/code-foundry/compare/v1.5.4...v1.6.0) (2026-09-08)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **ci:** add shared performance validation ([#492](https://github.com/0xPlayerOne/code-foundry/issues/492)) ([ef12990](https://github.com/0xPlayerOne/code-foundry/commit/ef1299045b6d67e447def93e2096862cde64bbc7))
|
|
9
|
+
|
|
10
|
+
## [1.5.4](https://github.com/0xPlayerOne/code-foundry/compare/v1.5.3...v1.5.4) (2026-09-08)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* **security:** pin scheduled audit runtime ([#491](https://github.com/0xPlayerOne/code-foundry/issues/491)) ([af25ef6](https://github.com/0xPlayerOne/code-foundry/commit/af25ef6137078809f27c316bdde2a9d025ef34af))
|
|
16
|
+
|
|
3
17
|
## [1.5.3](https://github.com/0xPlayerOne/code-foundry/compare/v1.5.2...v1.5.3) (2026-09-08)
|
|
4
18
|
|
|
5
19
|
|
package/docs/CONFIGURATION.md
CHANGED
|
@@ -36,6 +36,8 @@ repository manifests and source
|
|
|
36
36
|
| `package_manager` | `bun`, `pnpm`, `yarn`, `npm`, `none` | JavaScript setup |
|
|
37
37
|
| `toolchain` | `auto`, `native`, `mise` | Environment setup policy; defaults to `auto` |
|
|
38
38
|
| `staging_validation_mode` | `fast`, `audit` | Validation tier for pull requests targeting `staging`; defaults to `fast` |
|
|
39
|
+
| `performance` | `auto`, `true`, `false` | Run a deterministic performance task when a supported entrypoint exists; defaults to `auto` |
|
|
40
|
+
| `performance_command` | JSON string array | Command argv for non-package performance harnesses; package scripts take precedence |
|
|
39
41
|
| `features` | `all` or a list | Standard workflow callers |
|
|
40
42
|
| `codeql` | `auto`, `true`, `false` | CodeQL policy; public repositories default to enabled, non-public repositories default to disabled |
|
|
41
43
|
| `codeql_rust_shards` | JSON array of paths | Rust scan scopes; `["all"]` keeps the safe single full scan |
|
|
@@ -51,11 +53,30 @@ repository manifests and source
|
|
|
51
53
|
| `git_workflow` | `direct` (default), `staging-release` | Branch/release model; `direct` opens feature branches into `main`, `staging-release` promotes `staging` into `main` |
|
|
52
54
|
| `merge_strategy` | `rebase` | Promotion merge method for `staging` → `main`; only enforced by the `staging-release` topology |
|
|
53
55
|
| `release_merge_strategy` | `rebase`, `squash` (direct topology only) | Merge method for Release Please version PRs into `main`; release automation fails closed on anything else |
|
|
54
|
-
| `runner` fields | GitHub runner names | Per-workflow runner policy
|
|
56
|
+
| `runner` fields | GitHub runner names | Per-workflow runner policy, including `performance_runner` |
|
|
55
57
|
|
|
56
58
|
Supported features are `ci`, `codeql`, `security`, `test`, `draft-pr`,
|
|
57
59
|
`release-pr`, `release`, and `dependabot`.
|
|
58
60
|
|
|
61
|
+
## Performance validation
|
|
62
|
+
|
|
63
|
+
The shared Test workflow exposes a deterministic `Performance` job. In JavaScript
|
|
64
|
+
repositories it discovers `performance:check` first and `perf:check` second. Other
|
|
65
|
+
repositories can declare an argv array without shell interpolation:
|
|
66
|
+
|
|
67
|
+
```yaml
|
|
68
|
+
performance: true
|
|
69
|
+
performance_command: '["python3","scripts/performance_audit.py","--check"]'
|
|
70
|
+
performance_runner: ubuntu-latest
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
`performance: false` disables discovery. Performance budgets, fixtures, mock
|
|
74
|
+
providers, and live endpoint credentials remain repository-owned. The shared job
|
|
75
|
+
owns checkout, pinned setup, billing controls, concurrency, and artifact upload;
|
|
76
|
+
it uploads `artifacts/performance/**`, `performance-results.json`, or
|
|
77
|
+
`performance-results/**` when present. Network-dependent and post-deployment
|
|
78
|
+
checks should remain separate from this deterministic validation task.
|
|
79
|
+
|
|
59
80
|
## OpenCode Security opt-in and opt-out
|
|
60
81
|
|
|
61
82
|
`opencode_security` controls the optional OpenCode scan, and the generated
|
package/docs/WORKFLOWS.md
CHANGED
|
@@ -79,7 +79,7 @@ repositories can opt in or out without a code change.
|
|
|
79
79
|
| Workflow | Responsibility |
|
|
80
80
|
| ---------- | ------------------------------------------------------------- |
|
|
81
81
|
| CI | Format, lint, type-check, and build |
|
|
82
|
-
| Test | Unit, integration, E2E, and smoke tests
|
|
82
|
+
| Test | Unit, performance, integration, E2E, and smoke tests |
|
|
83
83
|
| Security | Profile, audits, and public-only Dependency Review |
|
|
84
84
|
| CodeQL | GitHub-native code scanning, kept separate from CI |
|
|
85
85
|
| Draft PR | Create/update development pull requests |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "code-foundry",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.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": {
|
package/src/commands/sync.mjs
CHANGED
|
@@ -549,6 +549,7 @@ function renderWorkflow(content, config, repository, ref, rustCodeql) {
|
|
|
549
549
|
'security-runner': config.security_runner ?? config.runner,
|
|
550
550
|
'codeql-runner': config.codeql_runner ?? config.runner,
|
|
551
551
|
'unit-runner': config.unit_runner,
|
|
552
|
+
'performance-runner': config.performance_runner ?? config.test_runner ?? config.runner,
|
|
552
553
|
}
|
|
553
554
|
for (const [input, value] of Object.entries(runnerInputs)) {
|
|
554
555
|
if (!value) continue
|
|
@@ -1088,6 +1089,8 @@ function createDefaultConfig(root, source) {
|
|
|
1088
1089
|
...runners,
|
|
1089
1090
|
toolchain: 'auto',
|
|
1090
1091
|
staging_validation_mode: 'fast',
|
|
1092
|
+
performance: 'auto',
|
|
1093
|
+
performance_command: '',
|
|
1091
1094
|
prune_standard: 'false',
|
|
1092
1095
|
cache_packages: 'auto',
|
|
1093
1096
|
cache_build: 'auto',
|
package/src/lib/profile.mjs
CHANGED
|
@@ -129,6 +129,7 @@ export function recommendRunners(root) {
|
|
|
129
129
|
ci_runner: heavy ? 'ubuntu-latest' : 'ubuntu-slim',
|
|
130
130
|
test_runner: heavy ? 'ubuntu-latest' : 'ubuntu-slim',
|
|
131
131
|
unit_runner: heavy ? 'ubuntu-latest' : 'ubuntu-slim',
|
|
132
|
+
performance_runner: 'ubuntu-latest',
|
|
132
133
|
security_runner: 'ubuntu-slim',
|
|
133
134
|
codeql_runner: 'ubuntu-latest',
|
|
134
135
|
pr_runner: 'ubuntu-slim',
|
package/src/runtime.mjs
CHANGED
|
@@ -52,6 +52,29 @@ function readPackage() {
|
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
+
function performanceEnabled() {
|
|
56
|
+
return configured(config.performance, 'auto') !== 'false'
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function performanceCommand() {
|
|
60
|
+
const raw = configured(config.performance_command, '').trim()
|
|
61
|
+
if (!raw) return null
|
|
62
|
+
let command
|
|
63
|
+
try {
|
|
64
|
+
command = JSON.parse(raw)
|
|
65
|
+
} catch {
|
|
66
|
+
throw new Error('performance_command must be a JSON array of command arguments.')
|
|
67
|
+
}
|
|
68
|
+
if (
|
|
69
|
+
!Array.isArray(command) ||
|
|
70
|
+
command.length === 0 ||
|
|
71
|
+
command.some((argument) => typeof argument !== 'string' || argument.length === 0)
|
|
72
|
+
) {
|
|
73
|
+
throw new Error('performance_command must be a non-empty JSON array of non-empty strings.')
|
|
74
|
+
}
|
|
75
|
+
return command
|
|
76
|
+
}
|
|
77
|
+
|
|
55
78
|
/** @param {string} task */
|
|
56
79
|
function validation(task) {
|
|
57
80
|
if (task === 'mode') {
|
|
@@ -271,7 +294,14 @@ function relevant(task) {
|
|
|
271
294
|
integration: ['test:integration'],
|
|
272
295
|
e2e: ['test:e2e', 'e2e'],
|
|
273
296
|
smoke: ['test:smoke', 'smoke'],
|
|
297
|
+
performance: ['performance:check', 'perf:check'],
|
|
274
298
|
}[task]
|
|
299
|
+
if (task === 'performance') {
|
|
300
|
+
if (!performanceEnabled()) return false
|
|
301
|
+
return Boolean(
|
|
302
|
+
(scripted && scripted.some((candidate) => hasScript(candidate))) || performanceCommand()
|
|
303
|
+
)
|
|
304
|
+
}
|
|
275
305
|
if (scripted && scripted.some((candidate) => hasScript(candidate)))
|
|
276
306
|
return packageManager !== 'none'
|
|
277
307
|
if (task === 'format' || task === 'lint' || task === 'type_check' || task === 'build') {
|
|
@@ -434,6 +464,13 @@ function ci(task) {
|
|
|
434
464
|
run('cargo', ['build', '--all-targets'])
|
|
435
465
|
return
|
|
436
466
|
}
|
|
467
|
+
if (task === 'performance') {
|
|
468
|
+
if (!performanceEnabled()) return
|
|
469
|
+
if (runScript(['performance:check', 'perf:check'])) return
|
|
470
|
+
const command = performanceCommand()
|
|
471
|
+
if (command) run(command[0], command.slice(1))
|
|
472
|
+
return
|
|
473
|
+
}
|
|
437
474
|
/** @type {Record<string, string[]>} */
|
|
438
475
|
const scriptsByTask = {
|
|
439
476
|
unit: ['test:unit', 'test:coverage', 'test'],
|