code-foundry 0.16.0 → 0.18.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,7 +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
+ runtime_repository="${REPO_FOUNDRY_RUNTIME_REPOSITORY:-}"
15
15
  bootstrap=true
16
16
  release_type="${REPO_FOUNDRY_RELEASE_TYPE:-auto}"
17
17
  npm_publish="${REPO_FOUNDRY_NPM_PUBLISH:-false}"
@@ -38,7 +38,7 @@ Options:
38
38
  --features LIST all or comma-separated optional features:
39
39
  ci,codeql,security,test,draft-pr,release-pr,release,dependabot
40
40
  --package-manager NAME auto, bun, pnpm, yarn, or npm
41
- --runtime-repository OWNER/REPO Reusable workflow runtime repository
41
+ --runtime-repository OWNER/REPO Reusable workflow runtime repository (auto from source)
42
42
  --release-type NAME auto, node, python, rust, or simple
43
43
  --license NAME agpl-3.0-or-later, mit, preserve, or none
44
44
  --license-file PATH Use an exact custom license file
@@ -111,9 +111,9 @@ sync_args=(
111
111
  --languages "$languages"
112
112
  --features "$features"
113
113
  --package-manager "$package_manager"
114
- --runtime-repository "$runtime_repository"
115
114
  --license "$license"
116
115
  )
116
+ if [ -n "$runtime_repository" ]; then sync_args+=(--runtime-repository "$runtime_repository"); fi
117
117
  if [ -n "$license_file" ]; then sync_args+=(--license-file "$license_file"); fi
118
118
  if [ "$dry_run" = true ]; then sync_args+=(--check); else sync_args+=(--apply); fi
119
119
  if [ "$prune" = true ]; then sync_args+=(--prune); fi
@@ -370,16 +370,22 @@ for file in "${files[@]}"; do
370
370
  done
371
371
 
372
372
  # Reusable workflow callers must use a literal repository/ref. Render the
373
- # selected runtime repository while leaving custom workflows untouched.
373
+ # selected runtime repository while leaving custom workflows untouched. Read
374
+ # the source's configured runtime first so forks remain self-contained.
375
+ source_runtime_repository=""
376
+ if [ -f "$template_root/.github/template.yml" ]; then
377
+ source_runtime_repository="$(awk -F': ' '/^runtime_repository:/ {print $2; exit}' "$template_root/.github/template.yml")"
378
+ fi
379
+ [ -n "$source_runtime_repository" ] || source_runtime_repository="0xPlayerOne/code-foundry"
374
380
  for file in .github/workflows/ci.yml .github/workflows/test.yml .github/workflows/security.yml .github/workflows/codeql.yml; do
375
381
  [ -f "$file" ] || continue
376
- if grep -q '0xPlayerOne/code-foundry' "$file"; then
382
+ if grep -qF "$source_runtime_repository" "$file" && [ "$source_runtime_repository" != "$runtime_repository" ]; then
377
383
  changed=$((changed + 1))
378
384
  if [ "$mode" = "check" ]; then
379
385
  printf 'Would render runtime repository in %s\n' "$file"
380
386
  else
381
387
  rendered_workflow="$(mktemp)"
382
- sed "s#0xPlayerOne/code-foundry#$runtime_repository#g" "$file" > "$rendered_workflow"
388
+ sed "s#${source_runtime_repository}#${runtime_repository}#g" "$file" > "$rendered_workflow"
383
389
  mv "$rendered_workflow" "$file"
384
390
  printf 'Rendered runtime repository in %s\n' "$file"
385
391
  fi
@@ -9,107 +9,10 @@ permissions:
9
9
  contents: write
10
10
  issues: write
11
11
  pull-requests: write
12
-
13
- env:
14
- REPO_FOUNDRY_PROFILE: ${{ vars.REPO_FOUNDRY_PROFILE }}
15
- REPO_FOUNDRY_LANGUAGES: ${{ vars.REPO_FOUNDRY_LANGUAGES }}
16
- REPO_FOUNDRY_FEATURES: ${{ vars.REPO_FOUNDRY_FEATURES }}
17
- REPO_FOUNDRY_PACKAGE_MANAGER: ${{ vars.REPO_FOUNDRY_PACKAGE_MANAGER }}
18
- REPO_FOUNDRY_RELEASE_TYPE: ${{ vars.REPO_FOUNDRY_RELEASE_TYPE }}
19
- REPO_FOUNDRY_NPM_PUBLISH: ${{ vars.REPO_FOUNDRY_NPM_PUBLISH }}
12
+ id-token: write
20
13
 
21
14
  jobs:
22
15
  release:
23
- name: Release / Version
24
- runs-on: ubuntu-slim
25
- timeout-minutes: 20
26
- concurrency:
27
- group: ${{ github.workflow }}-${{ github.ref }}
28
- cancel-in-progress: false
29
- outputs:
30
- release_created: ${{ steps.release.outputs.release_created || 'false' }}
31
- tag_name: ${{ steps.release.outputs.tag_name }}
32
- npm_publish: ${{ steps.profile.outputs.npm_publish }}
33
- steps:
34
- - name: Checkout
35
- uses: actions/checkout@v7
36
- with:
37
- # Release Please reads release metadata and manifests; defer source
38
- # blob transfer until a package file is actually needed.
39
- filter: blob:none
40
- - name: Detect release profile
41
- id: profile
42
- shell: bash
43
- run: |
44
- if [ -x .github/scripts/profile.sh ]; then
45
- release_type="$(bash .github/scripts/profile.sh get release_type)"
46
- npm_publish="$(bash .github/scripts/profile.sh get npm_publish)"
47
- else
48
- release_type="$(awk -F': ' '/^release_type:/ {print $2; exit}' .github/template.yml 2>/dev/null || true)"
49
- npm_publish="$(awk -F': ' '/^npm_publish:/ {print $2; exit}' .github/template.yml 2>/dev/null || true)"
50
- fi
51
- [ -n "$release_type" ] || release_type=auto
52
- [ -n "$npm_publish" ] || npm_publish=false
53
-
54
- if [ "$release_type" = auto ]; then
55
- if [ -f package.json ]; then release_type=node
56
- elif [ -f pyproject.toml ]; then release_type=python
57
- elif [ -f Cargo.toml ]; then release_type=rust
58
- elif [ -f version.txt ]; then release_type=simple
59
- else release_type=none
60
- fi
61
- fi
62
-
63
- case "$release_type" in
64
- node|python|rust|simple) ;;
65
- none) npm_publish=false ;;
66
- *) echo "Unsupported release_type: $release_type" >&2; exit 2 ;;
67
- esac
68
- if [ ! -f package.json ]; then npm_publish=false; fi
69
- printf 'release_type=%s\n' "$release_type" >> "$GITHUB_OUTPUT"
70
- printf 'npm_publish=%s\n' "$npm_publish" >> "$GITHUB_OUTPUT"
71
- - name: Release Please
72
- id: release
73
- if: steps.profile.outputs.release_type != 'none'
74
- uses: googleapis/release-please-action@v5
75
- with:
76
- # Use a PAT or GitHub App token when GITHUB_TOKEN cannot create PRs.
77
- token: ${{ secrets.RELEASE_PLEASE_TOKEN || github.token }}
78
- config-file: release-please-config.json
79
- release-type: ${{ steps.profile.outputs.release_type }}
80
-
81
- npm:
82
- name: Release / Publish npm
83
- needs: release
84
- if: needs.release.outputs.release_created == 'true' && needs.release.outputs.npm_publish == 'true'
85
- runs-on: ubuntu-slim
86
- timeout-minutes: 15
87
- permissions:
88
- contents: read
89
- id-token: write
90
- env:
91
- NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
92
- steps:
93
- - name: Checkout release
94
- uses: actions/checkout@v7
95
- with:
96
- ref: ${{ needs.release.outputs.tag_name }}
97
- - name: Setup Node (trusted)
98
- if: env.NPM_TOKEN == ''
99
- uses: actions/setup-node@v5
100
- with:
101
- node-version: 24
102
- - name: Setup Node (token)
103
- if: env.NPM_TOKEN != ''
104
- uses: actions/setup-node@v5
105
- with:
106
- node-version: 24
107
- registry-url: https://registry.npmjs.org
108
- - name: Publish npm with token
109
- if: env.NPM_TOKEN != ''
110
- env:
111
- NODE_AUTH_TOKEN: ${{ env.NPM_TOKEN }}
112
- run: npm publish --provenance --access public
113
- - name: Publish npm with trusted publishing
114
- if: env.NPM_TOKEN == ''
115
- run: npm publish --provenance --access public
16
+ name: Release
17
+ uses: 0xPlayerOne/code-foundry/.github/workflows/reusable-release.yml@v0.16.0
18
+ secrets: inherit
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.18.0](https://github.com/0xPlayerOne/code-foundry/compare/v0.17.0...v0.18.0) (2026-07-28)
4
+
5
+
6
+ ### Features
7
+
8
+ * **init:** infer runtime from source template ([81a545b](https://github.com/0xPlayerOne/code-foundry/commit/81a545bc6a2d89c31be51a711e477c4e4ceca7dd))
9
+
10
+ ## [0.17.0](https://github.com/0xPlayerOne/code-foundry/compare/v0.16.0...v0.17.0) (2026-07-28)
11
+
12
+
13
+ ### Features
14
+
15
+ * **release:** document centralized release runtime ([3e2a3f9](https://github.com/0xPlayerOne/code-foundry/commit/3e2a3f9b5e71bf5003819aa177afd265d989bb34))
16
+
17
+
18
+ ### Bug Fixes
19
+
20
+ * **release:** grant trusted publishing permission ([025f78e](https://github.com/0xPlayerOne/code-foundry/commit/025f78e851d44a60e2e4e17d3718b0b2fbe147ae))
21
+
3
22
  ## [0.16.0](https://github.com/0xPlayerOne/code-foundry/compare/v0.15.0...v0.16.0) (2026-07-28)
4
23
 
5
24
 
package/README.md CHANGED
@@ -36,11 +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`.
39
+ Reusable workflow callers use the source template's runtime automatically. For
40
+ example, initializing from `NiftyLeague/template-repo` selects that fork's
41
+ runtime without extra flags. Use `--runtime-repository OWNER/REPO` (or
42
+ `REPO_FOUNDRY_RUNTIME_REPOSITORY`) only when you want to override it. The
43
+ selected repository is saved in `.github/template.yml` and rendered into the
44
+ small CI, Test, Security, and CodeQL wrappers automatically.
44
45
 
45
46
  Normal synchronization imports only the local hook, agent-facing command,
46
47
  profile/release, initializer, doctor, ownership, and protection entrypoints.
@@ -55,6 +56,11 @@ CodeQL is also independently reusable through the same contract. It retains
55
56
  GitHub's native security-event permissions and language-specific analysis while
56
57
  keeping CodeQL separate from CI and dependency security checks.
57
58
 
59
+ Release automation follows the same model: the consumer keeps a short
60
+ main-branch wrapper while the shared runtime handles Release Please, GitHub
61
+ release metadata, optional npm publication, provenance, and token/trusted
62
+ publishing fallback.
63
+
58
64
  Initialization defaults to AGPL for new repositories. Synchronization defaults
59
65
  to `--license preserve`, so an existing repository's license is never replaced
60
66
  unless you explicitly select a license or provide `--license-file`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "code-foundry",
3
- "version": "0.16.0",
3
+ "version": "0.18.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
@@ -50,7 +50,10 @@ function parseArgs(argv) {
50
50
  languages: process.env.REPO_FOUNDRY_LANGUAGES || 'auto',
51
51
  features: process.env.REPO_FOUNDRY_FEATURES || 'all',
52
52
  packageManager: process.env.REPO_FOUNDRY_PACKAGE_MANAGER || 'auto',
53
- runtimeRepository: process.env.REPO_FOUNDRY_RUNTIME_REPOSITORY || '0xPlayerOne/code-foundry',
53
+ // Leave this empty unless the caller explicitly selects a runtime. The
54
+ // initializer can then derive the runtime from --source, which keeps
55
+ // organization forks plug-and-play.
56
+ runtimeRepository: process.env.REPO_FOUNDRY_RUNTIME_REPOSITORY || '',
54
57
  releaseType: process.env.REPO_FOUNDRY_RELEASE_TYPE || 'auto',
55
58
  license: process.env.REPO_FOUNDRY_LICENSE || (command === 'init' ? 'agpl-3.0-or-later' : 'preserve'),
56
59
  licenseFile: process.env.REPO_FOUNDRY_LICENSE_FILE || '',
@@ -123,7 +126,7 @@ function main() {
123
126
  if (options.licenseFile) common.push('--license-file', options.licenseFile)
124
127
  if (options.languagesSet) common.push('--languages', options.languages)
125
128
  if (options.featuresSet) common.push('--features', options.features)
126
- common.push('--runtime-repository', options.runtimeRepository)
129
+ if (options.runtimeRepository) common.push('--runtime-repository', options.runtimeRepository)
127
130
  if (options.prune) common.push('--prune')
128
131
  if (options.force) common.push('--force')
129
132
  if (options.dryRun) common.push('--check')
@@ -137,10 +140,10 @@ function main() {
137
140
  '--languages', options.languages,
138
141
  '--features', options.features,
139
142
  '--package-manager', options.packageManager,
140
- '--runtime-repository', options.runtimeRepository,
141
143
  '--release-type', options.releaseType,
142
144
  '--license', options.license,
143
145
  ]
146
+ if (options.runtimeRepository) initArgs.push('--runtime-repository', options.runtimeRepository)
144
147
  if (options.licenseFile) initArgs.push('--license-file', options.licenseFile)
145
148
  if (options.protection) initArgs.push('--protection')
146
149
  if (options.dryRun) initArgs.push('--dry-run')