code-foundry 0.8.0 → 0.10.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.
@@ -11,6 +11,7 @@ force=false
11
11
  languages="${REPO_FOUNDRY_LANGUAGES:-auto}"
12
12
  features="${REPO_FOUNDRY_FEATURES:-all}"
13
13
  package_manager="${REPO_FOUNDRY_PACKAGE_MANAGER:-auto}"
14
+ runtime_repository="${REPO_FOUNDRY_RUNTIME_REPOSITORY:-0xPlayerOne/code-foundry}"
14
15
  bootstrap=true
15
16
  release_type="${REPO_FOUNDRY_RELEASE_TYPE:-auto}"
16
17
  npm_publish="${REPO_FOUNDRY_NPM_PUBLISH:-false}"
@@ -37,6 +38,7 @@ Options:
37
38
  --features LIST all or comma-separated optional features:
38
39
  ci,codeql,security,test,draft-pr,release-pr,release,dependabot
39
40
  --package-manager NAME auto, bun, pnpm, yarn, or npm
41
+ --runtime-repository OWNER/REPO Reusable workflow runtime repository
40
42
  --release-type NAME auto, node, python, rust, or simple
41
43
  --license NAME agpl-3.0-or-later, mit, preserve, or none
42
44
  --license-file PATH Use an exact custom license file
@@ -63,6 +65,7 @@ while [ "$#" -gt 0 ]; do
63
65
  --languages) languages="${2:?missing language list}"; shift 2 ;;
64
66
  --features) features="${2:?missing feature list}"; shift 2 ;;
65
67
  --package-manager) package_manager="${2:?missing package manager}"; shift 2 ;;
68
+ --runtime-repository) runtime_repository="${2:?missing runtime repository}"; shift 2 ;;
66
69
  --release-type) release_type="${2:?missing release type}"; shift 2 ;;
67
70
  --license) license="${2:?missing license}"; shift 2 ;;
68
71
  --license-file) license_file="${2:?missing license file}"; shift 2 ;;
@@ -108,6 +111,7 @@ sync_args=(
108
111
  --languages "$languages"
109
112
  --features "$features"
110
113
  --package-manager "$package_manager"
114
+ --runtime-repository "$runtime_repository"
111
115
  --license "$license"
112
116
  )
113
117
  if [ -n "$license_file" ]; then sync_args+=(--license-file "$license_file"); fi
@@ -127,6 +131,7 @@ profile="$(awk -F': ' '/^profile:/ {print $2; exit}' .github/template.yml 2>/dev
127
131
  languages="$(awk -F': ' '/^languages:/ {print $2; exit}' .github/template.yml 2>/dev/null || true)"
128
132
  features="$(awk -F': ' '/^features:/ {print $2; exit}' .github/template.yml 2>/dev/null || true)"
129
133
  package_manager="$(awk -F': ' '/^package_manager:/ {print $2; exit}' .github/template.yml 2>/dev/null || true)"
134
+ runtime_repository="$(awk -F': ' '/^runtime_repository:/ {print $2; exit}' .github/template.yml 2>/dev/null || true)"
130
135
  release_type="$(awk -F': ' '/^release_type:/ {print $2; exit}' .github/template.yml 2>/dev/null || true)"
131
136
  npm_publish="$(awk -F': ' '/^npm_publish:/ {print $2; exit}' .github/template.yml 2>/dev/null || true)"
132
137
  license="$(awk -F': ' '/^license:/ {print $2; exit}' .github/template.yml 2>/dev/null || true)"
@@ -139,6 +144,7 @@ license="$(awk -F': ' '/^license:/ {print $2; exit}' .github/template.yml 2>/dev
139
144
  printf 'languages: %s\n' "$languages"
140
145
  printf 'features: %s\n' "$features"
141
146
  printf 'package_manager: %s\n' "$package_manager"
147
+ printf 'runtime_repository: %s\n' "$runtime_repository"
142
148
  printf 'release_type: %s\n' "$release_type"
143
149
  printf 'npm_publish: %s\n' "$npm_publish"
144
150
  printf 'license: %s\n' "$license"
@@ -13,6 +13,7 @@ Options:
13
13
  --languages LIST auto or comma-separated: typescript,rust,python,solidity
14
14
  --features LIST all or comma-separated standard features
15
15
  --package-manager NAME auto, bun, pnpm, yarn, or npm
16
+ --runtime-repository OWNER/REPO Reusable workflow runtime repository
16
17
  --license NAME preserve, agpl-3.0-or-later, mit, or none
17
18
  --license-file PATH Use an exact custom license file
18
19
  --check Preview changes (default)
@@ -40,6 +41,9 @@ features_set=false
40
41
  package_manager="${REPO_FOUNDRY_PACKAGE_MANAGER:-}"
41
42
  package_manager_set=false
42
43
  [ -n "${REPO_FOUNDRY_PACKAGE_MANAGER:-}" ] && package_manager_set=true
44
+ runtime_repository="${REPO_FOUNDRY_RUNTIME_REPOSITORY:-}"
45
+ runtime_repository_set=false
46
+ [ -n "${REPO_FOUNDRY_RUNTIME_REPOSITORY:-}" ] && runtime_repository_set=true
43
47
  template_ref=""
44
48
  release_type="${REPO_FOUNDRY_RELEASE_TYPE:-auto}"
45
49
  npm_publish="${REPO_FOUNDRY_NPM_PUBLISH:-false}"
@@ -104,6 +108,7 @@ while [ "$#" -gt 0 ]; do
104
108
  --languages) languages="${2:?missing language list}"; languages_set=true; shift 2 ;;
105
109
  --features) features="${2:?missing feature list}"; features_set=true; shift 2 ;;
106
110
  --package-manager) package_manager="${2:?missing package manager}"; package_manager_set=true; shift 2 ;;
111
+ --runtime-repository) runtime_repository="${2:?missing runtime repository}"; runtime_repository_set=true; shift 2 ;;
107
112
  --license) license="${2:?missing license}"; license_set=true; shift 2 ;;
108
113
  --license-file) license_file="${2:?missing license file}"; shift 2 ;;
109
114
  --check) mode="check"; shift ;;
@@ -132,6 +137,9 @@ if [ -f .github/template.yml ]; then
132
137
  if [ "$package_manager_set" = false ]; then
133
138
  package_manager="$(awk -F': ' '/^package_manager:/ {print $2; exit}' .github/template.yml)"
134
139
  fi
140
+ if [ "$runtime_repository_set" = false ]; then
141
+ runtime_repository="$(awk -F': ' '/^runtime_repository:/ {print $2; exit}' .github/template.yml)"
142
+ fi
135
143
  template_ref="$(awk -F': ' '/^template:/ {print $2; exit}' .github/template.yml)"
136
144
  if [ "$release_type_set" != true ]; then
137
145
  configured_release_type="$(awk -F': ' '/^release_type:/ {print $2; exit}' .github/template.yml)"
@@ -147,6 +155,18 @@ if [ -f .github/template.yml ]; then
147
155
  fi
148
156
  fi
149
157
  [ -n "$package_manager" ] || package_manager=auto
158
+ if [ -z "$runtime_repository" ]; then
159
+ source_repository="$source"
160
+ if [ -d "$source" ]; then
161
+ source_repository="$(git -C "$source" remote get-url origin 2>/dev/null || true)"
162
+ fi
163
+ runtime_repository="$(printf '%s\n' "$source_repository" | sed -nE 's#.*github\.com[:/]([^/]+/[^/.]+)(\.git)?$#\1#p')"
164
+ fi
165
+ [ -n "$runtime_repository" ] || runtime_repository="0xPlayerOne/code-foundry"
166
+ case "$runtime_repository" in
167
+ */*) ;;
168
+ *) printf 'Runtime repository must be OWNER/REPO: %s\n' "$runtime_repository" >&2; exit 2 ;;
169
+ esac
150
170
  case "$package_manager" in
151
171
  auto|bun|pnpm|yarn|npm) ;;
152
172
  *) printf 'Unsupported package manager: %s\n' "$package_manager" >&2; exit 2 ;;
@@ -185,6 +205,7 @@ if [ -f "$template_root/.github/scripts/profile.sh" ]; then
185
205
  REPO_FOUNDRY_LANGUAGES="$languages" \
186
206
  REPO_FOUNDRY_FEATURES="$features" \
187
207
  REPO_FOUNDRY_PACKAGE_MANAGER="$package_manager" \
208
+ REPO_FOUNDRY_RUNTIME_REPOSITORY="$runtime_repository" \
188
209
  REPO_FOUNDRY_RELEASE_TYPE="$release_type" \
189
210
  REPO_FOUNDRY_NPM_PUBLISH="$npm_publish" \
190
211
  bash "$template_root/.github/scripts/profile.sh" detect --root "$PWD"
@@ -354,6 +375,23 @@ for file in "${files[@]}"; do
354
375
  fi
355
376
  done
356
377
 
378
+ # Reusable workflow callers must use a literal repository/ref. Render the
379
+ # selected runtime repository while leaving custom workflows untouched.
380
+ for file in .github/workflows/ci.yml .github/workflows/test.yml; do
381
+ [ -f "$file" ] || continue
382
+ if grep -q '0xPlayerOne/code-foundry' "$file"; then
383
+ changed=$((changed + 1))
384
+ if [ "$mode" = "check" ]; then
385
+ printf 'Would render runtime repository in %s\n' "$file"
386
+ else
387
+ rendered_workflow="$(mktemp)"
388
+ sed "s#0xPlayerOne/code-foundry#$runtime_repository#g" "$file" > "$rendered_workflow"
389
+ mv "$rendered_workflow" "$file"
390
+ printf 'Rendered runtime repository in %s\n' "$file"
391
+ fi
392
+ fi
393
+ done
394
+
357
395
  write_license() {
358
396
  local owner license_source
359
397
  [ "$license" != preserve ] || return 0
@@ -526,6 +564,7 @@ if [ "$mode" = "apply" ]; then
526
564
  if [ -n "$package_manager" ]; then
527
565
  printf 'package_manager: %s\n' "$package_manager"
528
566
  fi
567
+ printf 'runtime_repository: %s\n' "$runtime_repository"
529
568
  printf 'release_type: %s\n' "$release_type"
530
569
  printf 'npm_publish: %s\n' "$npm_publish"
531
570
  printf 'license: %s\n' "$license"
@@ -4,6 +4,7 @@ profile: auto
4
4
  languages: typescript
5
5
  features: all
6
6
  package_manager: bun
7
+ runtime_repository: 0xPlayerOne/code-foundry
7
8
  release_type: node
8
9
  npm_publish: true
9
10
  license: agpl-3.0-or-later
@@ -5,6 +5,7 @@ profile: auto
5
5
  languages: auto
6
6
  features: all
7
7
  package_manager: auto
8
+ runtime_repository: 0xPlayerOne/code-foundry
8
9
  release_type: auto
9
10
  npm_publish: false
10
11
  license: preserve
@@ -0,0 +1,291 @@
1
+ name: Code Foundry Security
2
+
3
+ on:
4
+ workflow_call:
5
+ inputs:
6
+ runtime-repository:
7
+ description: Repository containing the Code Foundry runtime.
8
+ required: false
9
+ type: string
10
+ default: 0xPlayerOne/code-foundry
11
+ runtime-ref:
12
+ description: Code Foundry runtime tag or ref.
13
+ required: false
14
+ type: string
15
+ default: v0.9.0
16
+
17
+ permissions:
18
+ contents: read
19
+
20
+ env:
21
+ REPO_FOUNDRY_PROFILE: ${{ vars.REPO_FOUNDRY_PROFILE }}
22
+ REPO_FOUNDRY_LANGUAGES: ${{ vars.REPO_FOUNDRY_LANGUAGES }}
23
+ REPO_FOUNDRY_FEATURES: ${{ vars.REPO_FOUNDRY_FEATURES }}
24
+ REPO_FOUNDRY_PACKAGE_MANAGER: ${{ vars.REPO_FOUNDRY_PACKAGE_MANAGER }}
25
+ REPO_FOUNDRY_CACHE_PACKAGES: ${{ vars.REPO_FOUNDRY_CACHE_PACKAGES || 'auto' }}
26
+ REPO_FOUNDRY_BASE_SHA: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event.before || '' }}
27
+
28
+ concurrency:
29
+ group: ${{ github.workflow }}-${{ github.event.pull_request.head.repo.full_name || github.repository }}-${{ github.event.pull_request.head.ref || github.ref_name }}
30
+ cancel-in-progress: true
31
+
32
+ jobs:
33
+ profile:
34
+ name: Profile
35
+ runs-on: ubuntu-slim
36
+ timeout-minutes: 10
37
+ outputs:
38
+ javascript: ${{ steps.profile.outputs.javascript }}
39
+ rust: ${{ steps.profile.outputs.rust }}
40
+ python: ${{ steps.profile.outputs.python }}
41
+ python_requirements: ${{ steps.profile.outputs.python_requirements }}
42
+ steps:
43
+ - name: Checkout
44
+ uses: actions/checkout@v7
45
+ with:
46
+ fetch-depth: 2
47
+ filter: blob:none
48
+ sparse-checkout: |
49
+ .github
50
+ .mise.toml
51
+ mise.lock
52
+ .npmrc
53
+ .pnpmfile.cjs
54
+ .yarnrc*
55
+ **/package.json
56
+ **/bun.lock
57
+ **/bun.lockb
58
+ **/pnpm-lock.yaml
59
+ **/yarn.lock
60
+ **/package-lock.json
61
+ **/Cargo.toml
62
+ **/Cargo.lock
63
+ **/.cargo/**
64
+ **/pyproject.toml
65
+ **/requirements*.txt
66
+ **/setup.py
67
+ **/setup.cfg
68
+ **/Pipfile
69
+ **/Pipfile.lock
70
+ **/poetry.lock
71
+ **/uv.lock
72
+ sparse-checkout-cone-mode: false
73
+ - name: Runtime
74
+ uses: actions/checkout@v7
75
+ with:
76
+ repository: ${{ inputs.runtime-repository }}
77
+ ref: ${{ inputs.runtime-ref }}
78
+ path: .code-foundry
79
+ sparse-checkout: |
80
+ .github/actions
81
+ .github/scripts
82
+ - name: Install runtime
83
+ run: |
84
+ mkdir -p .github/actions .github/scripts
85
+ cp -R .code-foundry/.github/actions/. .github/actions/
86
+ cp -R .code-foundry/.github/scripts/. .github/scripts/
87
+ - name: Detect
88
+ id: profile
89
+ run: bash .github/scripts/security.sh profile >> "$GITHUB_OUTPUT"
90
+
91
+ dependency-audit-javascript:
92
+ name: Dependency Audit (JavaScript)
93
+ runs-on: ubuntu-slim
94
+ timeout-minutes: 20
95
+ steps:
96
+ - name: Checkout
97
+ uses: actions/checkout@v7
98
+ with:
99
+ filter: blob:none
100
+ sparse-checkout: |
101
+ .github
102
+ .mise.toml
103
+ mise.lock
104
+ .npmrc
105
+ .pnpmfile.cjs
106
+ .yarnrc*
107
+ **/package.json
108
+ **/bun.lock
109
+ **/bun.lockb
110
+ **/pnpm-lock.yaml
111
+ **/yarn.lock
112
+ **/package-lock.json
113
+ sparse-checkout-cone-mode: false
114
+ - name: Runtime
115
+ uses: actions/checkout@v7
116
+ with:
117
+ repository: ${{ inputs.runtime-repository }}
118
+ ref: ${{ inputs.runtime-ref }}
119
+ path: .code-foundry
120
+ sparse-checkout: |
121
+ .github/actions
122
+ .github/scripts
123
+ - name: Install runtime
124
+ run: |
125
+ mkdir -p .github/actions .github/scripts
126
+ cp -R .code-foundry/.github/actions/. .github/actions/
127
+ cp -R .code-foundry/.github/scripts/. .github/scripts/
128
+ - name: Detect
129
+ id: applicability
130
+ run: bash .github/scripts/security.sh should_run javascript >> "$GITHUB_OUTPUT"
131
+ - name: Setup
132
+ if: steps.applicability.outputs.applicable == 'true'
133
+ uses: ./.github/actions/setup
134
+ with:
135
+ mise-scope: javascript
136
+ cache-save: ${{ github.event_name != 'pull_request' }}
137
+ - name: Audit dependencies
138
+ if: steps.applicability.outputs.applicable == 'true'
139
+ run: bash .github/scripts/security.sh audit javascript
140
+
141
+ dependency-audit-rust:
142
+ name: Dependency Audit (Rust)
143
+ runs-on: ${{ vars.REPO_FOUNDRY_RUST_AUDIT_RUNNER || 'ubuntu-latest' }}
144
+ timeout-minutes: 20
145
+ steps:
146
+ - name: Checkout
147
+ uses: actions/checkout@v7
148
+ with:
149
+ filter: blob:none
150
+ sparse-checkout: |
151
+ .github
152
+ .mise.toml
153
+ mise.lock
154
+ **/Cargo.toml
155
+ **/Cargo.lock
156
+ **/.cargo/**
157
+ sparse-checkout-cone-mode: false
158
+ - name: Runtime
159
+ uses: actions/checkout@v7
160
+ with:
161
+ repository: ${{ inputs.runtime-repository }}
162
+ ref: ${{ inputs.runtime-ref }}
163
+ path: .code-foundry
164
+ sparse-checkout: |
165
+ .github/actions
166
+ .github/scripts
167
+ - name: Install runtime
168
+ run: |
169
+ mkdir -p .github/actions .github/scripts
170
+ cp -R .code-foundry/.github/actions/. .github/actions/
171
+ cp -R .code-foundry/.github/scripts/. .github/scripts/
172
+ - name: Detect
173
+ id: applicability
174
+ run: bash .github/scripts/security.sh should_run rust >> "$GITHUB_OUTPUT"
175
+ - name: Check Rust
176
+ id: system-rust
177
+ if: steps.applicability.outputs.applicable == 'true'
178
+ shell: bash
179
+ run: |
180
+ if command -v cargo >/dev/null 2>&1 && command -v rustc >/dev/null 2>&1; then
181
+ cargo --version
182
+ rustc --version
183
+ echo 'available=true' >> "$GITHUB_OUTPUT"
184
+ else
185
+ echo 'available=false' >> "$GITHUB_OUTPUT"
186
+ fi
187
+ - name: Setup
188
+ if: >-
189
+ steps.applicability.outputs.applicable == 'true' &&
190
+ steps.system-rust.outputs.available != 'true'
191
+ uses: ./.github/actions/setup
192
+ with:
193
+ mise-scope: rust
194
+ cache-save: ${{ github.event_name != 'pull_request' }}
195
+ - name: Install cargo-audit
196
+ if: steps.applicability.outputs.applicable == 'true'
197
+ uses: taiki-e/install-action@v2
198
+ with:
199
+ tool: cargo-audit
200
+ - name: Audit dependencies
201
+ if: steps.applicability.outputs.applicable == 'true'
202
+ run: bash .github/scripts/security.sh audit rust
203
+
204
+ dependency-audit-python:
205
+ name: Dependency Audit (Python) / ${{ matrix.requirement }}
206
+ needs: profile
207
+ if: >-
208
+ ${{ needs.profile.result == 'success' &&
209
+ needs.profile.outputs.python == 'true' &&
210
+ needs.profile.outputs.python_requirements != '["none"]' }}
211
+ strategy:
212
+ fail-fast: false
213
+ max-parallel: 8
214
+ matrix:
215
+ requirement: ${{ fromJSON(needs.profile.outputs.python_requirements) }}
216
+ runs-on: ubuntu-slim
217
+ timeout-minutes: 20
218
+ env:
219
+ REPO_FOUNDRY_PYTHON_REQUIREMENT: ${{ matrix.requirement }}
220
+ steps:
221
+ - name: Checkout
222
+ uses: actions/checkout@v7
223
+ with:
224
+ filter: blob:none
225
+ sparse-checkout: |
226
+ .github
227
+ .mise.toml
228
+ mise.lock
229
+ **/pyproject.toml
230
+ **/requirements*.txt
231
+ **/setup.py
232
+ **/setup.cfg
233
+ **/Pipfile
234
+ **/Pipfile.lock
235
+ **/poetry.lock
236
+ **/uv.lock
237
+ sparse-checkout-cone-mode: false
238
+ - name: Runtime
239
+ uses: actions/checkout@v7
240
+ with:
241
+ repository: ${{ inputs.runtime-repository }}
242
+ ref: ${{ inputs.runtime-ref }}
243
+ path: .code-foundry
244
+ sparse-checkout: |
245
+ .github/actions
246
+ .github/scripts
247
+ - name: Install runtime
248
+ run: |
249
+ mkdir -p .github/actions .github/scripts
250
+ cp -R .code-foundry/.github/actions/. .github/actions/
251
+ cp -R .code-foundry/.github/scripts/. .github/scripts/
252
+ - name: Setup
253
+ uses: ./.github/actions/setup
254
+ with:
255
+ mise-scope: python
256
+ cache-save: ${{ github.event_name != 'pull_request' }}
257
+ - name: Audit dependencies
258
+ run: bash .github/scripts/security.sh audit python
259
+
260
+ dependency-audit-python-gate:
261
+ name: Dependency Audit (Python)
262
+ needs: [profile, dependency-audit-python]
263
+ if: always()
264
+ runs-on: ubuntu-slim
265
+ timeout-minutes: 5
266
+ steps:
267
+ - name: Gate
268
+ env:
269
+ PROFILE_RESULT: ${{ needs.profile.result }}
270
+ AUDIT_RESULT: ${{ needs.dependency-audit-python.result }}
271
+ run: |
272
+ if [ "$PROFILE_RESULT" != success ]; then
273
+ echo "Python audit profile failed: $PROFILE_RESULT" >&2
274
+ exit 1
275
+ fi
276
+ case "$AUDIT_RESULT" in
277
+ success|skipped) exit 0 ;;
278
+ *) echo "Python dependency audit failed: $AUDIT_RESULT" >&2; exit 1 ;;
279
+ esac
280
+
281
+ dependency-review:
282
+ name: Dependency Review
283
+ if: ${{ github.event_name == 'pull_request' && !github.event.repository.private }}
284
+ runs-on: ubuntu-slim
285
+ timeout-minutes: 10
286
+ steps:
287
+ - name: Review
288
+ uses: actions/dependency-review-action@v5
289
+ with:
290
+ fail-on-severity: high
291
+ license-check: true
@@ -10,172 +10,8 @@ on:
10
10
  permissions:
11
11
  contents: read
12
12
 
13
- env:
14
- TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
15
- TURBO_TEAM: ${{ vars.TURBO_TEAM }}
16
- REPO_FOUNDRY_PROFILE: ${{ vars.REPO_FOUNDRY_PROFILE }}
17
- REPO_FOUNDRY_LANGUAGES: ${{ vars.REPO_FOUNDRY_LANGUAGES }}
18
- REPO_FOUNDRY_FEATURES: ${{ vars.REPO_FOUNDRY_FEATURES }}
19
- REPO_FOUNDRY_PACKAGE_MANAGER: ${{ vars.REPO_FOUNDRY_PACKAGE_MANAGER }}
20
- REPO_FOUNDRY_CACHE_PACKAGES: ${{ vars.REPO_FOUNDRY_CACHE_PACKAGES || 'auto' }}
21
- REPO_FOUNDRY_CACHE_BUILD: ${{ vars.REPO_FOUNDRY_CACHE_BUILD || 'auto' }}
22
- REPO_FOUNDRY_BASE_SHA: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event.before || '' }}
23
-
24
- concurrency:
25
- group: ${{ github.workflow }}-${{ github.event.pull_request.head.repo.full_name || github.repository }}-${{ github.event.pull_request.head.ref || github.ref_name }}
26
- cancel-in-progress: true
27
-
28
13
  jobs:
29
- unit:
30
- name: Unit
31
- # Keep ordinary suites on the lean image. Set the repository variable
32
- # REPO_FOUNDRY_UNIT_RUNNER=ubuntu-latest for native/system-dependent tests.
33
- runs-on: ${{ vars.REPO_FOUNDRY_UNIT_RUNNER || 'ubuntu-slim' }}
34
- timeout-minutes: 30
35
- steps:
36
- - name: Checkout
37
- uses: actions/checkout@v7
38
- with:
39
- fetch-depth: 2
40
- - name: Detect
41
- id: applicability
42
- run: bash .github/scripts/ci.sh task_profile unit >> "$GITHUB_OUTPUT"
43
- - name: Setup
44
- if: steps.applicability.outputs.applicable == 'true'
45
- uses: ./.github/actions/setup
46
- with:
47
- install: true
48
- install-javascript: ${{ steps.applicability.outputs.javascript == 'true' }}
49
- install-python: ${{ steps.applicability.outputs.python == 'true' }}
50
- install-rust: ${{ steps.applicability.outputs.rust == 'true' }}
51
- cache-build: false
52
- cache-environment: false
53
- cache-packages: ${{ vars.REPO_FOUNDRY_CACHE_PACKAGES || 'auto' }}
54
- task: unit
55
- task-javascript: ${{ steps.applicability.outputs.javascript }}
56
- task-python: ${{ steps.applicability.outputs.python }}
57
- task-rust: ${{ steps.applicability.outputs.rust }}
58
- - name: Unit
59
- if: steps.applicability.outputs.applicable == 'true'
60
- run: bash .github/scripts/ci.sh unit
61
- - name: Upload coverage
62
- if: >-
63
- always() &&
64
- steps.applicability.outputs.applicable == 'true' &&
65
- hashFiles('coverage/**', 'htmlcov/**', '.coverage*', 'target/llvm-cov/**') != ''
66
- uses: actions/upload-artifact@v7
67
- with:
68
- name: coverage-unit-${{ github.run_id }}
69
- path: |
70
- coverage/**
71
- htmlcov/**
72
- .coverage*
73
- target/llvm-cov/**
74
- compression-level: 1
75
- if-no-files-found: ignore
76
- retention-days: 14
77
-
78
- integration:
79
- name: Integration
80
- runs-on: ubuntu-latest
81
- timeout-minutes: 30
82
- steps:
83
- - name: Checkout
84
- uses: actions/checkout@v7
85
- with:
86
- fetch-depth: 2
87
- - name: Detect
88
- id: applicability
89
- run: bash .github/scripts/ci.sh task_profile integration >> "$GITHUB_OUTPUT"
90
- - name: Setup
91
- if: steps.applicability.outputs.applicable == 'true'
92
- uses: ./.github/actions/setup
93
- with:
94
- install: true
95
- install-javascript: ${{ steps.applicability.outputs.javascript == 'true' }}
96
- install-python: ${{ steps.applicability.outputs.python == 'true' }}
97
- install-rust: ${{ steps.applicability.outputs.rust == 'true' }}
98
- cache-build: ${{ steps.applicability.outputs.rust == 'true' }}
99
- cache-environment: false
100
- cache-save: ${{ github.event_name == 'push' }}
101
- task: integration
102
- task-javascript: ${{ steps.applicability.outputs.javascript }}
103
- task-python: ${{ steps.applicability.outputs.python }}
104
- task-rust: ${{ steps.applicability.outputs.rust }}
105
- - name: Integration
106
- if: steps.applicability.outputs.applicable == 'true'
107
- run: bash .github/scripts/ci.sh integration
108
-
109
- e2e:
110
- name: E2E
111
- runs-on: ubuntu-latest
112
- timeout-minutes: 45
113
- steps:
114
- - name: Checkout
115
- uses: actions/checkout@v7
116
- with:
117
- fetch-depth: 2
118
- - name: Detect
119
- id: applicability
120
- run: bash .github/scripts/ci.sh task_profile e2e >> "$GITHUB_OUTPUT"
121
- - name: Cache browser binaries
122
- if: steps.applicability.outputs.applicable == 'true' && steps.applicability.outputs.browser == 'true'
123
- uses: ./.github/actions/cache
124
- with:
125
- save: ${{ github.event_name == 'push' }}
126
- path: |
127
- ~/.cache/ms-playwright
128
- ~/.cache/Cypress
129
- ~/.cache/puppeteer
130
- key: ${{ runner.os }}-e2e-browsers-${{ hashFiles('**/package.json', '**/bun.lock', '**/bun.lockb', '**/pnpm-lock.yaml', '**/yarn.lock', '**/package-lock.json', '**/playwright.config.*', '**/cypress.config.*') }}
131
- restore-keys: |
132
- ${{ runner.os }}-e2e-browsers-
133
- - name: Setup
134
- if: steps.applicability.outputs.applicable == 'true'
135
- uses: ./.github/actions/setup
136
- with:
137
- install: true
138
- install-javascript: ${{ steps.applicability.outputs.javascript == 'true' }}
139
- install-python: ${{ steps.applicability.outputs.python == 'true' }}
140
- install-rust: ${{ steps.applicability.outputs.rust == 'true' }}
141
- cache-build: false
142
- cache-environment: false
143
- cache-save: ${{ github.event_name == 'push' }}
144
- task: e2e
145
- task-javascript: ${{ steps.applicability.outputs.javascript }}
146
- task-python: ${{ steps.applicability.outputs.python }}
147
- task-rust: ${{ steps.applicability.outputs.rust }}
148
- - name: E2E
149
- if: steps.applicability.outputs.applicable == 'true'
150
- run: bash .github/scripts/ci.sh e2e
151
-
152
- smoke:
153
- name: Smoke
154
- runs-on: ubuntu-latest
155
- timeout-minutes: 15
156
- steps:
157
- - name: Checkout
158
- uses: actions/checkout@v7
159
- with:
160
- fetch-depth: 2
161
- - name: Detect
162
- id: applicability
163
- run: bash .github/scripts/ci.sh task_profile smoke >> "$GITHUB_OUTPUT"
164
- - name: Setup
165
- if: steps.applicability.outputs.applicable == 'true'
166
- uses: ./.github/actions/setup
167
- with:
168
- install: true
169
- install-javascript: ${{ steps.applicability.outputs.javascript == 'true' }}
170
- install-python: ${{ steps.applicability.outputs.python == 'true' }}
171
- install-rust: ${{ steps.applicability.outputs.rust == 'true' }}
172
- cache-build: false
173
- cache-environment: false
174
- cache-save: ${{ github.event_name == 'push' }}
175
- task: smoke
176
- task-javascript: ${{ steps.applicability.outputs.javascript }}
177
- task-python: ${{ steps.applicability.outputs.python }}
178
- task-rust: ${{ steps.applicability.outputs.rust }}
179
- - name: Smoke
180
- if: steps.applicability.outputs.applicable == 'true'
181
- run: bash .github/scripts/ci.sh smoke
14
+ test:
15
+ name: Test
16
+ uses: 0xPlayerOne/code-foundry/.github/workflows/reusable-test.yml@v0.8.0
17
+ secrets: inherit
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.10.0](https://github.com/0xPlayerOne/code-foundry/compare/v0.9.0...v0.10.0) (2026-07-28)
4
+
5
+
6
+ ### Features
7
+
8
+ * **security:** add reusable security workflow runtime ([b21d014](https://github.com/0xPlayerOne/code-foundry/commit/b21d014e85cfcdef4181d488b1df91e3c950503b))
9
+
10
+ ## [0.9.0](https://github.com/0xPlayerOne/code-foundry/compare/v0.8.0...v0.9.0) (2026-07-28)
11
+
12
+
13
+ ### Features
14
+
15
+ * **init:** configure reusable workflow repository ([95d17e9](https://github.com/0xPlayerOne/code-foundry/commit/95d17e9a4af2e2075fcdc2c357af414876655fb3))
16
+
3
17
  ## [0.8.0](https://github.com/0xPlayerOne/code-foundry/compare/v0.7.0...v0.8.0) (2026-07-28)
4
18
 
5
19
 
package/README.md CHANGED
@@ -36,6 +36,12 @@ npx code-foundry init --license agpl-3.0-or-later
36
36
  npx code-foundry init --license-file ./legal/LICENSE.txt
37
37
  ```
38
38
 
39
+ Reusable workflow callers default to this package's public runtime. Use
40
+ `--runtime-repository OWNER/REPO` when initializing from an organization fork;
41
+ the selected repository is saved in `.github/template.yml` and rendered into
42
+ the small `ci.yml` and `test.yml` wrappers automatically. The equivalent
43
+ environment variable is `REPO_FOUNDRY_RUNTIME_REPOSITORY`.
44
+
39
45
  Initialization defaults to AGPL for new repositories. Synchronization defaults
40
46
  to `--license preserve`, so an existing repository's license is never replaced
41
47
  unless you explicitly select a license or provide `--license-file`.
@@ -84,7 +90,7 @@ bash .github/scripts/init-repo.sh \
84
90
 
85
91
  Supported profiles are `application`, `monorepo`, and `minimal`; use `auto` to detect one. Supported languages are `typescript`, `rust`, `python`, and `solidity`. Supported feature flags are `ci`, `codeql`, `security`, `test`, `draft-pr`, `release-pr`, `release`, and `dependabot`. Use `--prune` only when you explicitly want disabled standard workflows removed; custom workflows are always preserved. The selected profile is stored in `.github/template.yml`, which makes later syncs repeatable and lets workflows consume repository-specific settings without duplicating the template scripts.
86
92
 
87
- Profile precedence is consistent everywhere: explicit CLI flags, then `REPO_FOUNDRY_*` GitHub repository variables/environment values, then `.github/template.yml`, then automatic detection and standard defaults. Useful repository variables include `REPO_FOUNDRY_PROFILE`, `REPO_FOUNDRY_LANGUAGES`, `REPO_FOUNDRY_FEATURES`, `REPO_FOUNDRY_PACKAGE_MANAGER`, `REPO_FOUNDRY_RUNNER`, `REPO_FOUNDRY_UNIT_RUNNER`, `REPO_FOUNDRY_CACHE_PACKAGES`, `REPO_FOUNDRY_CACHE_BUILD`, `REPO_FOUNDRY_COVERAGE_MINIMUM`, and `REPO_FOUNDRY_TURBO_REMOTE`. Use CLI flags for one-off initialization; use repository variables for local overrides that should not be committed.
93
+ Profile precedence is consistent everywhere: explicit CLI flags, then `REPO_FOUNDRY_*` GitHub repository variables/environment values, then `.github/template.yml`, then automatic detection and standard defaults. Useful repository variables include `REPO_FOUNDRY_PROFILE`, `REPO_FOUNDRY_LANGUAGES`, `REPO_FOUNDRY_FEATURES`, `REPO_FOUNDRY_PACKAGE_MANAGER`, `REPO_FOUNDRY_RUNTIME_REPOSITORY`, `REPO_FOUNDRY_RUNNER`, `REPO_FOUNDRY_UNIT_RUNNER`, `REPO_FOUNDRY_CACHE_PACKAGES`, `REPO_FOUNDRY_CACHE_BUILD`, `REPO_FOUNDRY_COVERAGE_MINIMUM`, and `REPO_FOUNDRY_TURBO_REMOTE`. Use CLI flags for one-off initialization; use repository variables for local overrides that should not be committed.
88
94
 
89
95
  Inspect the resolved profile at any time with `bash .github/scripts/profile.sh detect`; use `profile.sh get KEY` when another script needs one setting.
90
96
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "code-foundry",
3
- "version": "0.8.0",
3
+ "version": "0.10.0",
4
4
  "description": "A fast, language-aware repository factory for agent-ready workflows, testing, security, and release automation.",
5
5
  "type": "module",
6
6
  "license": "AGPL-3.0-or-later",
package/src/cli.mjs CHANGED
@@ -22,6 +22,7 @@ Init/sync options:
22
22
  --languages LIST auto or typescript,rust,python,solidity
23
23
  --features LIST all or ci,codeql,security,test,draft-pr,release-pr,release,dependabot
24
24
  --package-manager NAME auto, bun, pnpm, yarn, or npm
25
+ --runtime-repository OWNER/REPO Reusable workflow runtime repository
25
26
  --release-type NAME auto, node, python, rust, simple, or none
26
27
  --license NAME agpl-3.0-or-later, mit, preserve, or none
27
28
  --license-file PATH Use an exact custom license file
@@ -49,6 +50,7 @@ function parseArgs(argv) {
49
50
  languages: process.env.REPO_FOUNDRY_LANGUAGES || 'auto',
50
51
  features: process.env.REPO_FOUNDRY_FEATURES || 'all',
51
52
  packageManager: process.env.REPO_FOUNDRY_PACKAGE_MANAGER || 'auto',
53
+ runtimeRepository: process.env.REPO_FOUNDRY_RUNTIME_REPOSITORY || '0xPlayerOne/code-foundry',
52
54
  releaseType: process.env.REPO_FOUNDRY_RELEASE_TYPE || 'auto',
53
55
  license: process.env.REPO_FOUNDRY_LICENSE || (command === 'init' ? 'agpl-3.0-or-later' : 'preserve'),
54
56
  licenseFile: process.env.REPO_FOUNDRY_LICENSE_FILE || '',
@@ -69,6 +71,7 @@ function parseArgs(argv) {
69
71
  ['--languages', 'languages'],
70
72
  ['--features', 'features'],
71
73
  ['--package-manager', 'packageManager'],
74
+ ['--runtime-repository', 'runtimeRepository'],
72
75
  ['--release-type', 'releaseType'],
73
76
  ['--license', 'license'],
74
77
  ['--license-file', 'licenseFile'],
@@ -120,6 +123,7 @@ function main() {
120
123
  if (options.licenseFile) common.push('--license-file', options.licenseFile)
121
124
  if (options.languagesSet) common.push('--languages', options.languages)
122
125
  if (options.featuresSet) common.push('--features', options.features)
126
+ common.push('--runtime-repository', options.runtimeRepository)
123
127
  if (options.prune) common.push('--prune')
124
128
  if (options.force) common.push('--force')
125
129
  if (options.dryRun) common.push('--check')
@@ -133,6 +137,7 @@ function main() {
133
137
  '--languages', options.languages,
134
138
  '--features', options.features,
135
139
  '--package-manager', options.packageManager,
140
+ '--runtime-repository', options.runtimeRepository,
136
141
  '--release-type', options.releaseType,
137
142
  '--license', options.license,
138
143
  ]