code-foundry 0.32.2 → 0.32.4
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/code-foundry.yml +8 -2
- package/CHANGELOG.md +17 -0
- package/docs/RELEASES.md +12 -10
- package/package.json +1 -1
- package/src/commands/release.mjs +1 -0
- package/src/commands/sync.mjs +18 -3
- package/src/lib/release-manifest.mjs +1 -1
package/.github/code-foundry.yml
CHANGED
|
@@ -11,13 +11,13 @@ dependency_review: auto
|
|
|
11
11
|
package_manager: bun
|
|
12
12
|
toolchain: auto
|
|
13
13
|
runtime_repository: 0xPlayerOne/code-foundry
|
|
14
|
-
runtime_ref: v0.
|
|
14
|
+
runtime_ref: v0.32.3
|
|
15
15
|
release_type: node
|
|
16
16
|
npm_publish: true
|
|
17
17
|
license: agpl-3.0-or-later
|
|
18
18
|
git_workflow: staging-release
|
|
19
19
|
merge_strategy: rebase
|
|
20
|
-
release_merge_strategy:
|
|
20
|
+
release_merge_strategy: squash
|
|
21
21
|
runner: ubuntu-latest
|
|
22
22
|
unit_runner: ubuntu-slim
|
|
23
23
|
cache_packages: auto
|
|
@@ -31,3 +31,9 @@ codeql_runner: ubuntu-latest
|
|
|
31
31
|
pr_runner: ubuntu-slim
|
|
32
32
|
release_runner: ubuntu-slim
|
|
33
33
|
prune_standard: false
|
|
34
|
+
post_release: false
|
|
35
|
+
post_release_workflow:
|
|
36
|
+
post_release_mode: auto
|
|
37
|
+
opencode_security: false
|
|
38
|
+
sync_mode: overlay
|
|
39
|
+
custom_workflows: preserve
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.32.4](https://github.com/0xPlayerOne/code-foundry/compare/v0.32.3...v0.32.4) (2026-08-01)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* **sync:** never leak runtime release-type into consumer configs ([b7c51f3](https://github.com/0xPlayerOne/code-foundry/commit/b7c51f3e465e048be933292e0db9ca08d5420c9a))
|
|
9
|
+
* **sync:** quote collection-like config values so prettier accepts them ([b0d4fea](https://github.com/0xPlayerOne/code-foundry/commit/b0d4fea815b6417de23cf577cba525e2017004dc))
|
|
10
|
+
* **sync:** satisfy JSDoc type-check for baseline merge ([ce54339](https://github.com/0xPlayerOne/code-foundry/commit/ce54339b2092722e4d0d4e43afdb7ab5bacd2bc1))
|
|
11
|
+
|
|
12
|
+
## [0.32.3](https://github.com/0xPlayerOne/code-foundry/compare/v0.32.2...v0.32.3) (2026-07-31)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
* **release:** no-op when staging already points at main's commit ([a47180a](https://github.com/0xPlayerOne/code-foundry/commit/a47180a16ae8b9fd66548aba284939b3cdfaeba8))
|
|
18
|
+
* **release:** squash Release Please PRs for release-please compatibility ([41c808b](https://github.com/0xPlayerOne/code-foundry/commit/41c808b8c2502ca78e271cb6702334daf90169da))
|
|
19
|
+
|
|
3
20
|
## [0.32.2](https://github.com/0xPlayerOne/code-foundry/compare/v0.32.1...v0.32.2) (2026-07-31)
|
|
4
21
|
|
|
5
22
|
|
package/docs/RELEASES.md
CHANGED
|
@@ -36,15 +36,17 @@ release_merge_strategy: rebase # merge, squash, or rebase; used for Release Plea
|
|
|
36
36
|
|
|
37
37
|
`merge_strategy` applies to promotion PRs (`staging` into `main`) and
|
|
38
38
|
`release_merge_strategy` to Release Please version PRs; both default to
|
|
39
|
-
`merge` when unset. Use **rebase** for
|
|
40
|
-
linear, which is what makes the
|
|
41
|
-
`staging` requires linear history, and
|
|
42
|
-
uncrossable barrier for `staging` (the
|
|
43
|
-
whose new commits contain merge commits).
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
39
|
+
`merge` when unset. Use **rebase** for promotion PRs and **squash** for
|
|
40
|
+
Release Please PRs. Both keep `main` fully linear, which is what makes the
|
|
41
|
+
post-release reconciliation possible: `staging` requires linear history, and
|
|
42
|
+
any merge commit on `main` becomes an uncrossable barrier for `staging` (the
|
|
43
|
+
linear-history rule rejects pushes whose new commits contain merge commits).
|
|
44
|
+
Release Please itself also requires squash merges for its version PRs (rebase
|
|
45
|
+
merges rewrite commit SHAs and break its merged-PR detection). With a linear
|
|
46
|
+
`main`, the release workflow mirrors `staging` onto `main`'s tip after every
|
|
47
|
+
release — a verified fast-forward when possible, otherwise a forced linear
|
|
48
|
+
update, otherwise a single-parent synchronization commit — so `staging` is
|
|
49
|
+
never left behind and never needs a manual rebase.
|
|
48
50
|
|
|
49
51
|
`auto` selects a supported manifest. Use `simple` with `version.txt` for a
|
|
50
52
|
repository without a package manifest and `none` for a repository that should
|
|
@@ -76,6 +78,6 @@ the generated version pull request before using the token to merge it.
|
|
|
76
78
|
|
|
77
79
|
1. Merge tested changes from `staging` into `main`.
|
|
78
80
|
2. Review the generated Release Please PR and changelog.
|
|
79
|
-
3. Merge the release PR with the repository
|
|
81
|
+
3. Merge the release PR with the repository.s configured `release_merge_strategy` (default `merge`, recommended `squash`).
|
|
80
82
|
4. Confirm the GitHub Release and any package publication.
|
|
81
83
|
5. Synchronize `staging` with the new `main` release commit.
|
package/package.json
CHANGED
package/src/commands/release.mjs
CHANGED
|
@@ -40,6 +40,7 @@ export function reconcileRelease(root, options) {
|
|
|
40
40
|
console.log(JSON.stringify({ base, head, ...plan }, null, 2))
|
|
41
41
|
if (plan.action === 'fail') throw new Error(plan.reason + (plan.unexpected?.length ? ` Unexpected paths: ${plan.unexpected.join(', ')}` : ''))
|
|
42
42
|
if (!['fast-forward', 'pull-request', 'aligned'].includes(plan.action) || !options.github || options.dryRun) return plan
|
|
43
|
+
if (!plan.targetSha) return plan
|
|
43
44
|
if (!process.env.GITHUB_REPOSITORY) throw new Error('GITHUB_REPOSITORY is required for --github reconciliation.')
|
|
44
45
|
const token = process.env.GH_TOKEN || process.env.GITHUB_TOKEN
|
|
45
46
|
if (!token) throw new Error('GH_TOKEN or GITHUB_TOKEN is required for --github reconciliation.')
|
package/src/commands/sync.mjs
CHANGED
|
@@ -182,18 +182,27 @@ export function syncRepository(options) {
|
|
|
182
182
|
return { changed, config }
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
+
/**
|
|
186
|
+
* Baseline keys that are safe to merge into a repository's release config.
|
|
187
|
+
* Package and release-type policy is detected from the repository itself and
|
|
188
|
+
* must never leak from the runtime template.
|
|
189
|
+
*/
|
|
190
|
+
const RELEASE_BASELINE_KEYS = ['$schema', 'bump-minor-pre-major', 'changelog-sections', 'include-component-in-tag']
|
|
191
|
+
|
|
185
192
|
/** @param {string} target @param {string} sourceFile @returns {Record<string, any>} */
|
|
186
193
|
function mergeReleaseConfig(target, sourceFile) {
|
|
194
|
+
/** @type {Record<string, any>} */
|
|
187
195
|
let baseline = {}
|
|
188
196
|
try { baseline = JSON.parse(readFileSync(sourceFile, 'utf8')) }
|
|
189
197
|
catch { baseline = {} }
|
|
198
|
+
const safeBaseline = Object.fromEntries(RELEASE_BASELINE_KEYS.filter((key) => key in baseline).map((key) => [key, baseline[key]]))
|
|
190
199
|
const destination = join(target, 'release-please-config.json')
|
|
191
200
|
let existing = baseline
|
|
192
201
|
if (existsSync(destination)) {
|
|
193
202
|
try { existing = JSON.parse(readFileSync(destination, 'utf8')) }
|
|
194
203
|
catch { existing = baseline }
|
|
195
204
|
}
|
|
196
|
-
return buildReleaseConfig(target, { ...
|
|
205
|
+
return buildReleaseConfig(target, { ...safeBaseline, ...existing })
|
|
197
206
|
}
|
|
198
207
|
|
|
199
208
|
/** @param {string} target @param {string} sourceFile @returns {string} */
|
|
@@ -364,14 +373,20 @@ function createDefaultConfig(root, source) {
|
|
|
364
373
|
post_release: 'false', post_release_workflow: '', post_release_mode: 'auto',
|
|
365
374
|
opencode_security: 'false',
|
|
366
375
|
sync_mode: 'overlay', custom_workflows: 'preserve',
|
|
367
|
-
license: existsSync(join(root, 'LICENSE')) ? 'preserve' : 'gpl-3.0-or-later', git_workflow: 'staging-release', merge_strategy: 'rebase', release_merge_strategy: '
|
|
376
|
+
license: existsSync(join(root, 'LICENSE')) ? 'preserve' : 'gpl-3.0-or-later', git_workflow: 'staging-release', merge_strategy: 'rebase', release_merge_strategy: 'squash',
|
|
368
377
|
}
|
|
369
378
|
}
|
|
370
379
|
|
|
371
380
|
/** @param {Record<string,string>} config */
|
|
372
381
|
function renderConfig(config) { return `${Object.entries(config).map(([key, value]) => renderConfigLine(key, value)).join('\n')}\n` }
|
|
373
382
|
/** @param {string} key @param {string} value */
|
|
374
|
-
function renderConfigLine(key, value) {
|
|
383
|
+
function renderConfigLine(key, value) {
|
|
384
|
+
if (value === '') return `${key}:`
|
|
385
|
+
// Quote values that YAML would parse as collections or that would trip
|
|
386
|
+
// prettier's formatter (e.g. codeql_rust_shards: '["all"]').
|
|
387
|
+
const needsQuotes = /^[\[\]{]|[:,#]\s|\s#/.test(value)
|
|
388
|
+
return needsQuotes ? `${key}: '${value.replace(/'/g, "''")}'` : `${key}: ${value}`
|
|
389
|
+
}
|
|
375
390
|
/** @param {string} root */
|
|
376
391
|
function readPackageVersion(root) {
|
|
377
392
|
try { return JSON.parse(readFileSync(join(root, 'package.json'), 'utf8')).version ?? '0.0.0' } catch { return '0.0.0' }
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { existsSync, readFileSync, readdirSync } from 'node:fs'
|
|
4
4
|
import { join } from 'node:path'
|
|
5
5
|
|
|
6
|
-
const ignored = new Set(['.git', '.code-foundry', '.venv', 'node_modules', 'target', 'vendor', 'dist', 'build'])
|
|
6
|
+
const ignored = new Set(['.git', '.code-foundry', '.venv', 'node_modules', 'target', 'vendor', 'dist', 'build', '.next', '.kilo', '.turbo', '.cache', '.vercel', '.output', '.nuxt', '.svelte-kit', '.parcel-cache', 'out', 'coverage'])
|
|
7
7
|
|
|
8
8
|
/** @typedef {{ directory: string, manifest: string, releaseType: 'node'|'python'|'rust', packageName?: string, extraFiles: string[] }} ReleasePackage */
|
|
9
9
|
|