code-foundry 1.46.6 → 1.47.1
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 -15
- package/docs/CONFIGURATION.md +2 -0
- package/package.json +1 -1
- package/src/commands/sync.mjs +126 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.47.1](https://github.com/0xPlayerOne/code-foundry/compare/v1.47.0...v1.47.1) (2026-10-08)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Tests
|
|
7
|
+
|
|
8
|
+
* **doctor:** pin the machine-hook shadow warning ([#753](https://github.com/0xPlayerOne/code-foundry/issues/753)) ([f634269](https://github.com/0xPlayerOne/code-foundry/commit/f634269424580d8d34323319288747587b6d6ae3))
|
|
9
|
+
|
|
10
|
+
## [1.47.0](https://github.com/0xPlayerOne/code-foundry/compare/v1.46.6...v1.47.0) (2026-10-08)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
* **release:** configurable dev channel on top of batched releases ([#749](https://github.com/0xPlayerOne/code-foundry/issues/749)) ([8fd8556](https://github.com/0xPlayerOne/code-foundry/commit/8fd85567a1a89735ab0db589649741253fbbeb21)), closes [#699](https://github.com/0xPlayerOne/code-foundry/issues/699)
|
|
16
|
+
|
|
3
17
|
## [1.46.6](https://github.com/0xPlayerOne/code-foundry/compare/v1.46.5...v1.46.6) (2026-10-08)
|
|
4
18
|
|
|
5
19
|
|
|
@@ -126,23 +140,9 @@
|
|
|
126
140
|
|
|
127
141
|
* **ci:** declare the e2e shard inputs on the no-codeql orchestrator ([#714](https://github.com/0xPlayerOne/code-foundry/issues/714)) ([7500208](https://github.com/0xPlayerOne/code-foundry/commit/7500208f3b25dfe55c41ea45b382e021cf804012))
|
|
128
142
|
|
|
129
|
-
## [1.44.3](https://github.com/0xPlayerOne/code-foundry/compare/v1.44.2...v1.44.3) (2026-10-03)
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
### Tests
|
|
133
|
-
|
|
134
|
-
* **cli:** assert expected doctor warnings ([#712](https://github.com/0xPlayerOne/code-foundry/issues/712)) ([d036bee](https://github.com/0xPlayerOne/code-foundry/commit/d036beee79a9b200315cdbee5509fc3c2a6c4a04))
|
|
135
|
-
|
|
136
|
-
## [1.44.2](https://github.com/0xPlayerOne/code-foundry/compare/v1.44.1...v1.44.2) (2026-10-03)
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
### Bug Fixes
|
|
140
|
-
|
|
141
|
-
* **ci:** cancel only superseded pull-request runs in managed workflows ([#710](https://github.com/0xPlayerOne/code-foundry/issues/710)) ([f5fead6](https://github.com/0xPlayerOne/code-foundry/commit/f5fead677c032d253f2e1a2a256da4f207ddfa2a))
|
|
142
|
-
|
|
143
143
|
<!-- code-foundry: packaged changelog -->
|
|
144
144
|
|
|
145
145
|
---
|
|
146
146
|
|
|
147
|
-
This packaged changelog lists the 20 most recent releases;
|
|
147
|
+
This packaged changelog lists the 20 most recent releases; 243 older releases are omitted to keep the package small.
|
|
148
148
|
See the [full changelog](https://github.com/0xPlayerOne/code-foundry/blob/main/CHANGELOG.md) for the complete history.
|
package/docs/CONFIGURATION.md
CHANGED
|
@@ -141,6 +141,8 @@ See [Merge queue validation](merge-queues.md) before enabling it.
|
|
|
141
141
|
| `release_batching_prerelease` | `true`, `false` | Defaults to `true` with a schedule. Sync enables `draft` and `force-tag-creation` in Release Please; the producer publishes the draft with the selected visibility. `false` keeps scheduled releases stable-visible. |
|
|
142
142
|
| `release_batching_soak_hours` | `1`–`336` | Generate a daily promoter that promotes the newest prerelease when the oldest candidate since the last stable has soaked this many hours, stitching batch notes. Requires a batching schedule and prerelease publication. Set `STABLE_PROMOTION_HELD=true` in repository Actions variables to hold scheduled and manual promotion; `force` overrides the hold or soak, and `version` selects a plain semantic version. |
|
|
143
143
|
| `release_batching_qualification_workflow` | workflow filename (for example `release-assets.yml`) | Require the latest release-event run of this workflow for the candidate tag’s exact source commit to succeed before stable promotion. Requires a batching soak. Running, missing, failed, or cancelled runs hold promotion, including named and forced promotions; `force` only bypasses hold and soak. The promoter receives read-only Actions access. |
|
|
144
|
+
| `release_batching_dev_channel` | `true`, `false` | Publish a dev channel: every push to main tags a `v<stable>-dev.<run>` pre-release on top of the newest stable and dispatches the configured asset lane. Dev builds are never promoted to stable, auto builds pause with `CI_BILLING_PAUSED`, and manual dispatches accept a `version` input for repairs. Defaults to `false`. |
|
|
145
|
+
| `release_batching_dev_workflow` | workflow filename | The `workflow_dispatch` asset lane the dev channel dispatches with a `version` input; the lane and its version injection stay app-provided because packaging differs per app. Required by `release_batching_dev_channel`. |
|
|
144
146
|
|
|
145
147
|
Supported task capabilities are `format`, `lint`, `type_check`, `build`, `unit`,
|
|
146
148
|
`integration`, `e2e`, `smoke`, `eval`, and `performance`. `coverage` is a policy
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "code-foundry",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.47.1",
|
|
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
|
@@ -308,6 +308,13 @@ function synchronize(options) {
|
|
|
308
308
|
const promoterPath = join(target, '.github/workflows/promote-stable.yml')
|
|
309
309
|
if (promoter) writeOrReport(promoterPath, promoter, dryRun)
|
|
310
310
|
else if (existsSync(promoterPath) && !dryRun) rmSync(promoterPath)
|
|
311
|
+
// The dev channel rides along the same way: rendered from
|
|
312
|
+
// release_batching_dev_channel, removed when the key is gone so a
|
|
313
|
+
// disabled channel stops tagging dev builds on every push.
|
|
314
|
+
const devChannel = renderDevChannel(config)
|
|
315
|
+
const devChannelPath = join(target, '.github/workflows/dev-channel.yml')
|
|
316
|
+
if (devChannel) writeOrReport(devChannelPath, devChannel, dryRun)
|
|
317
|
+
else if (existsSync(devChannelPath) && !dryRun) rmSync(devChannelPath)
|
|
311
318
|
}
|
|
312
319
|
if (file === '.github/dependabot.yml') {
|
|
313
320
|
content = Buffer.from(renderDependabot(content.toString('utf8'), config, languages))
|
|
@@ -936,6 +943,29 @@ function validateReleaseBatchingConfig(config) {
|
|
|
936
943
|
)
|
|
937
944
|
}
|
|
938
945
|
}
|
|
946
|
+
if (
|
|
947
|
+
config.release_batching_dev_channel &&
|
|
948
|
+
!['true', 'false'].includes(config.release_batching_dev_channel)
|
|
949
|
+
) {
|
|
950
|
+
throw new Error(
|
|
951
|
+
`Unsupported release_batching_dev_channel: ${config.release_batching_dev_channel}; use true or false.`
|
|
952
|
+
)
|
|
953
|
+
}
|
|
954
|
+
if (configured(config.release_batching_dev_channel, 'false') === 'true') {
|
|
955
|
+
if (
|
|
956
|
+
!config.release_batching_dev_workflow ||
|
|
957
|
+
!/^[A-Za-z0-9_.-]+\.ya?ml$/.test(config.release_batching_dev_workflow)
|
|
958
|
+
) {
|
|
959
|
+
throw new Error(
|
|
960
|
+
'Unsupported release_batching_dev_workflow: use the filename of the workflow_dispatch asset lane the dev build should dispatch.'
|
|
961
|
+
)
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
if (config.release_batching_dev_workflow && config.release_batching_dev_channel !== 'true') {
|
|
965
|
+
throw new Error(
|
|
966
|
+
'Unsupported release_batching_dev_workflow: requires release_batching_dev_channel: true.'
|
|
967
|
+
)
|
|
968
|
+
}
|
|
939
969
|
}
|
|
940
970
|
|
|
941
971
|
/** Render the batch-soak promoter for a repository, or null when the
|
|
@@ -953,6 +983,102 @@ export function renderPromoteStable(config) {
|
|
|
953
983
|
)
|
|
954
984
|
}
|
|
955
985
|
|
|
986
|
+
/**
|
|
987
|
+
* The dev channel for repositories with `release_batching_dev_channel`. Every
|
|
988
|
+
* push to main tags a `v<stable>-dev.<run>` pre-release on top of the newest
|
|
989
|
+
* stable and dispatches the repository's own asset lane with a `version`
|
|
990
|
+
* input; the oldest dev builds are pruned so the channel stays bounded. Dev
|
|
991
|
+
* builds are never promoted: the batch-soak promoter's batch selector already
|
|
992
|
+
* excludes `-dev.` tags, so the channel lives beside stable forever.
|
|
993
|
+
* `__DEV_WORKFLOW__` is replaced with the configured asset lane at render
|
|
994
|
+
* time; the lane stays app-provided because packaging differs per app.
|
|
995
|
+
*/
|
|
996
|
+
const DEV_CHANNEL_TEMPLATE = `# Generated by Code Foundry sync from release_batching_dev_channel; rerun sync after changing or removing the key.
|
|
997
|
+
|
|
998
|
+
name: Publish dev channel
|
|
999
|
+
|
|
1000
|
+
on:
|
|
1001
|
+
push:
|
|
1002
|
+
branches: [main]
|
|
1003
|
+
workflow_dispatch:
|
|
1004
|
+
inputs:
|
|
1005
|
+
version:
|
|
1006
|
+
description: Publish this dev version now (for example v0.75.1-dev.42). Leave empty to derive it from the newest stable.
|
|
1007
|
+
required: false
|
|
1008
|
+
type: string
|
|
1009
|
+
|
|
1010
|
+
permissions:
|
|
1011
|
+
contents: write
|
|
1012
|
+
actions: write
|
|
1013
|
+
|
|
1014
|
+
concurrency:
|
|
1015
|
+
group: dev-channel
|
|
1016
|
+
cancel-in-progress: false
|
|
1017
|
+
|
|
1018
|
+
jobs:
|
|
1019
|
+
publish:
|
|
1020
|
+
name: Tag the dev build and dispatch the asset lane
|
|
1021
|
+
# Auto dev builds pause with the shared billing pause; the manual dispatch
|
|
1022
|
+
# (the repair path) still runs.
|
|
1023
|
+
if: github.event_name == 'workflow_dispatch' || vars.CI_BILLING_PAUSED != 'true'
|
|
1024
|
+
runs-on: ubuntu-latest
|
|
1025
|
+
timeout-minutes: 10
|
|
1026
|
+
steps:
|
|
1027
|
+
- name: Publish the dev prerelease and dispatch the asset lane
|
|
1028
|
+
env:
|
|
1029
|
+
GH_TOKEN: \${{ github.token }}
|
|
1030
|
+
DEV_WORKFLOW: '__DEV_WORKFLOW__'
|
|
1031
|
+
REQUESTED: \${{ inputs.version }}
|
|
1032
|
+
run: |
|
|
1033
|
+
set -euo pipefail
|
|
1034
|
+
repo="$GITHUB_REPOSITORY"
|
|
1035
|
+
if [ -n "$REQUESTED" ]; then
|
|
1036
|
+
tag="$REQUESTED"
|
|
1037
|
+
else
|
|
1038
|
+
stable="$(gh api --paginate --slurp "repos/$repo/releases?per_page=100" | jq -r '
|
|
1039
|
+
[ .[] | select(.draft == false and .prerelease == false)
|
|
1040
|
+
| select(.tag_name | test("^v[0-9]+[.][0-9]+[.][0-9]+$")) ]
|
|
1041
|
+
| sort_by(.published_at) | .[-1].tag_name // empty')"
|
|
1042
|
+
if [ -z "$stable" ]; then
|
|
1043
|
+
echo "No stable release exists yet; a dev channel needs a stable baseline." | tee "$GITHUB_STEP_SUMMARY"
|
|
1044
|
+
exit 0
|
|
1045
|
+
fi
|
|
1046
|
+
tag="\${stable}-dev.\${GITHUB_RUN_NUMBER}"
|
|
1047
|
+
fi
|
|
1048
|
+
if gh release view "$tag" --repo "$repo" >/dev/null 2>&1; then
|
|
1049
|
+
echo "$tag already exists; nothing to do." | tee "$GITHUB_STEP_SUMMARY"
|
|
1050
|
+
exit 0
|
|
1051
|
+
fi
|
|
1052
|
+
gh release create "$tag" --repo "$repo" --prerelease --target "$GITHUB_SHA" \
|
|
1053
|
+
--title "$tag" --notes "Dev build of \${GITHUB_SHA::7}; a dev-channel build is never promoted to stable."
|
|
1054
|
+
gh workflow run "$DEV_WORKFLOW" --repo "$repo" --ref main -f version="$tag"
|
|
1055
|
+
echo "Dispatched $DEV_WORKFLOW for $tag." | tee "$GITHUB_STEP_SUMMARY"
|
|
1056
|
+
|
|
1057
|
+
# Keep the channel bounded: the newest dev builds stay, the rest go.
|
|
1058
|
+
gh api --paginate --slurp "repos/$repo/releases?per_page=100" | jq -r '
|
|
1059
|
+
[ .[] | select(.draft == false and .prerelease == true)
|
|
1060
|
+
| select(.tag_name | test("^v[0-9]+[.][0-9]+[.][0-9]+-dev[.][0-9]+$")) ]
|
|
1061
|
+
| sort_by(.created_at) | reverse | .[3:] | .[].tag_name' | while read -r stale; do
|
|
1062
|
+
echo "Pruning $stale."
|
|
1063
|
+
gh release delete "$stale" --repo "$repo" --yes --cleanup-tag
|
|
1064
|
+
done
|
|
1065
|
+
`
|
|
1066
|
+
|
|
1067
|
+
/**
|
|
1068
|
+
* Render the dev channel workflow for a repository, or null when the
|
|
1069
|
+
* repository has not opted in.
|
|
1070
|
+
*
|
|
1071
|
+
* @param {Record<string, string>} config
|
|
1072
|
+
* @returns {string | null}
|
|
1073
|
+
*/
|
|
1074
|
+
export function renderDevChannel(config) {
|
|
1075
|
+
if (configured(config.release_batching_dev_channel, 'false') !== 'true') return null
|
|
1076
|
+
return DEV_CHANNEL_TEMPLATE.replaceAll(
|
|
1077
|
+
'__DEV_WORKFLOW__',
|
|
1078
|
+
config.release_batching_dev_workflow ?? ''
|
|
1079
|
+
)
|
|
1080
|
+
}
|
|
1081
|
+
|
|
956
1082
|
/**
|
|
957
1083
|
* @param {string} content
|
|
958
1084
|
* @param {Record<string,string>} config
|