code-foundry 0.30.0 → 0.30.2
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/CHANGELOG.md +15 -0
- package/package.json +1 -1
- package/src/cli.mjs +5 -3
- package/src/commands/fleet.mjs +5 -1
- package/src/commands/release.mjs +9 -2
- package/src/commands/sync.mjs +4 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.30.2](https://github.com/0xPlayerOne/code-foundry/compare/v0.30.1...v0.30.2) (2026-07-29)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* **fleet:** support explicit repository exclusions ([2c3a641](https://github.com/0xPlayerOne/code-foundry/commit/2c3a641814de392457f94f3581f01e5b625056ee))
|
|
9
|
+
|
|
10
|
+
## [0.30.1](https://github.com/0xPlayerOne/code-foundry/compare/v0.30.0...v0.30.1) (2026-07-29)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* **release:** retry generated PR discovery ([dba7233](https://github.com/0xPlayerOne/code-foundry/commit/dba72337a04e73a2436d417b9e6f68d67bf54f83))
|
|
16
|
+
* **sync:** include Python formatter baseline ([c7ce208](https://github.com/0xPlayerOne/code-foundry/commit/c7ce2084dcc7a7a3372056b879f435276e31aaa0))
|
|
17
|
+
|
|
3
18
|
## [0.30.0](https://github.com/0xPlayerOne/code-foundry/compare/v0.29.0...v0.30.0) (2026-07-29)
|
|
4
19
|
|
|
5
20
|
|
package/package.json
CHANGED
package/src/cli.mjs
CHANGED
|
@@ -11,7 +11,7 @@ import { syncRepository } from './commands/sync.mjs'
|
|
|
11
11
|
|
|
12
12
|
const packageRoot = resolve(fileURLToPath(new URL('..', import.meta.url)))
|
|
13
13
|
|
|
14
|
-
/** @typedef {{ target: string, root: string, dryRun: boolean, force: boolean, github: boolean, createPr: boolean, base: string, head: string, tag: string, workflow: string, mode: string, version: string, releaseSubcommand?: string, fleetSubcommand?: string }} Options */
|
|
14
|
+
/** @typedef {{ target: string, root: string, dryRun: boolean, force: boolean, github: boolean, createPr: boolean, exclude: string[], base: string, head: string, tag: string, workflow: string, mode: string, version: string, releaseSubcommand?: string, fleetSubcommand?: string }} Options */
|
|
15
15
|
/** @typedef {{ command: string, options: Options }} ParsedArgs */
|
|
16
16
|
|
|
17
17
|
const usage = `code-foundry — initialize and maintain agent-ready repositories
|
|
@@ -42,6 +42,7 @@ Options:
|
|
|
42
42
|
--root PATH Fleet root containing repositories (default: current directory)
|
|
43
43
|
--create-pr Create isolated upgrade branches and pull requests
|
|
44
44
|
--version TAG Runtime tag to report in fleet upgrade branches
|
|
45
|
+
--exclude NAME Skip a repository path or owner/name in fleet operations
|
|
45
46
|
-h, --help Show this help
|
|
46
47
|
`
|
|
47
48
|
|
|
@@ -57,7 +58,7 @@ function parseArgs(argv) {
|
|
|
57
58
|
const hasCommand = Boolean(first && !first.startsWith('-'))
|
|
58
59
|
const command = hasCommand ? /** @type {string} */ (argv.shift()) : 'init'
|
|
59
60
|
/** @type {Options} */
|
|
60
|
-
const options = { target: process.cwd(), root: process.cwd(), dryRun: false, force: false, github: false, createPr: false, base: 'main', head: 'staging', tag: '', workflow: '', mode: 'auto', version: `v${readPackageVersion(packageRoot)}` }
|
|
61
|
+
const options = { target: process.cwd(), root: process.cwd(), dryRun: false, force: false, github: false, createPr: false, exclude: [], base: 'main', head: 'staging', tag: '', workflow: '', mode: 'auto', version: `v${readPackageVersion(packageRoot)}` }
|
|
61
62
|
|
|
62
63
|
if (command === 'release') {
|
|
63
64
|
const subcommand = argv.shift() ?? ''
|
|
@@ -90,6 +91,7 @@ function parseArgs(argv) {
|
|
|
90
91
|
else if (arg === '--root') options.root = argv.shift() ?? fail('--root requires a path')
|
|
91
92
|
else if (arg === '--create-pr') options.createPr = true
|
|
92
93
|
else if (arg === '--version') options.version = argv.shift() ?? fail('--version requires a tag')
|
|
94
|
+
else if (arg === '--exclude') options.exclude.push(argv.shift() ?? fail('--exclude requires a name'))
|
|
93
95
|
else fail(`unknown option: ${arg}; run --help for the supported options`)
|
|
94
96
|
}
|
|
95
97
|
|
|
@@ -132,7 +134,7 @@ function main() {
|
|
|
132
134
|
try {
|
|
133
135
|
const root = resolve(options.root)
|
|
134
136
|
if (options.fleetSubcommand === 'status') console.log(JSON.stringify(discoverRepositories(root), null, 2))
|
|
135
|
-
else upgradeFleet(root, packageRoot, { createPr: options.createPr, dryRun: options.dryRun, force: options.force, version: options.version })
|
|
137
|
+
else upgradeFleet(root, packageRoot, { createPr: options.createPr, dryRun: options.dryRun, force: options.force, version: options.version, exclude: options.exclude })
|
|
136
138
|
} catch (error) {
|
|
137
139
|
fail(error instanceof Error ? error.message : String(error))
|
|
138
140
|
}
|
package/src/commands/fleet.mjs
CHANGED
|
@@ -29,11 +29,15 @@ export function discoverRepositories(root) {
|
|
|
29
29
|
return result.sort((a, b) => a.path.localeCompare(b.path))
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
/** @param {string} root @param {string} source @param {{ createPr?: boolean, dryRun?: boolean, force?: boolean, version: string }} options */
|
|
32
|
+
/** @param {string} root @param {string} source @param {{ createPr?: boolean, dryRun?: boolean, force?: boolean, version: string, exclude?: string[] }} options */
|
|
33
33
|
export function upgradeFleet(root, source, options) {
|
|
34
34
|
const repositories = discoverRepositories(root)
|
|
35
35
|
const report = []
|
|
36
36
|
for (const repository of repositories) {
|
|
37
|
+
if ((options.exclude ?? []).some((value) => repository.path === value || repository.repository === value || repository.path.endsWith(`/${value}`))) {
|
|
38
|
+
report.push({ path: repository.path, status: 'skipped', reason: 'excluded by fleet policy' })
|
|
39
|
+
continue
|
|
40
|
+
}
|
|
37
41
|
if (!repository.configured) {
|
|
38
42
|
report.push({ path: repository.path, status: 'skipped', reason: 'missing .github/code-foundry.yml' })
|
|
39
43
|
continue
|
package/src/commands/release.mjs
CHANGED
|
@@ -82,7 +82,13 @@ export function dispatchPostReleaseHook(root, options) {
|
|
|
82
82
|
export function validateReleasePullRequestDiffs(root) {
|
|
83
83
|
const repository = process.env.GITHUB_REPOSITORY
|
|
84
84
|
if (!repository) throw new Error('GITHUB_REPOSITORY is required for release PR validation.')
|
|
85
|
-
|
|
85
|
+
let prs = []
|
|
86
|
+
for (let attempt = 0; attempt < 5; attempt += 1) {
|
|
87
|
+
const result = ghJson(root, ['pr', 'list', '--repo', repository, '--state', 'open', '--base', 'main', '--json', 'number,title,headRefName'])
|
|
88
|
+
prs = Array.isArray(result) ? result : []
|
|
89
|
+
if (selectGeneratedReleasePrs(prs).length) break
|
|
90
|
+
if (attempt < 4) spawnSync('sleep', ['2'])
|
|
91
|
+
}
|
|
86
92
|
const generated = selectGeneratedReleasePrs(Array.isArray(prs) ? prs : [])
|
|
87
93
|
/** @type {Map<number, string[]>} */
|
|
88
94
|
const paths = new Map()
|
|
@@ -130,7 +136,8 @@ function diffNames(root, from, to) {
|
|
|
130
136
|
|
|
131
137
|
/** @param {string} root @param {string[]} args @returns {unknown} */
|
|
132
138
|
function ghJson(root, args) {
|
|
133
|
-
const
|
|
139
|
+
const token = process.env.RELEASE_PLEASE_TOKEN || process.env.GH_TOKEN || process.env.GITHUB_TOKEN
|
|
140
|
+
const result = spawnSync('gh', args, { cwd: resolve(root), encoding: 'utf8', env: { ...process.env, ...(token ? { GH_TOKEN: token } : {}) } })
|
|
134
141
|
if (result.status !== 0) return []
|
|
135
142
|
try { return JSON.parse(result.stdout) }
|
|
136
143
|
catch { return [] }
|
package/src/commands/sync.mjs
CHANGED
|
@@ -56,7 +56,7 @@ export function syncRepository(options) {
|
|
|
56
56
|
const missing = Object.keys(defaults).filter((key) => !(key in existingConfig))
|
|
57
57
|
if (missing.length) {
|
|
58
58
|
const current = readFileSync(configPath, 'utf8').trimEnd()
|
|
59
|
-
const additions = missing.map((key) =>
|
|
59
|
+
const additions = missing.map((key) => renderConfigLine(key, defaults[key])).join('\n')
|
|
60
60
|
writeOrReport(configPath, `${current}\n${additions}\n`, dryRun)
|
|
61
61
|
}
|
|
62
62
|
}
|
|
@@ -259,7 +259,9 @@ function createDefaultConfig(root, source) {
|
|
|
259
259
|
}
|
|
260
260
|
|
|
261
261
|
/** @param {Record<string,string>} config */
|
|
262
|
-
function renderConfig(config) { return `${Object.entries(config).map(([key, value]) =>
|
|
262
|
+
function renderConfig(config) { return `${Object.entries(config).map(([key, value]) => renderConfigLine(key, value)).join('\n')}\n` }
|
|
263
|
+
/** @param {string} key @param {string} value */
|
|
264
|
+
function renderConfigLine(key, value) { return value === '' ? `${key}:` : `${key}: ${value}` }
|
|
263
265
|
/** @param {string} root */
|
|
264
266
|
function readPackageVersion(root) {
|
|
265
267
|
try { return JSON.parse(readFileSync(join(root, 'package.json'), 'utf8')).version ?? '0.0.0' } catch { return '0.0.0' }
|