Skip to content

Commit fdac09b

Browse files
authored
Merge pull request #5292 from Hmbown/codex/v095-release-contract-fix
chore(release): prepare v0.9.5
2 parents c20386d + cd4bf73 commit fdac09b

288 files changed

Lines changed: 35751 additions & 23149 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.cnb.yml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,12 @@
6060
set -eu
6161
# The release profile uses full LTO and one codegen unit. Bound Cargo's
6262
# parallelism so the final links cannot exhaust a shared CNB runner.
63-
cargo build --jobs 2 --release --locked -p codewhale-cli -p codewhale-tui
63+
cargo build --jobs 2 --release --locked -p codewhale-cli
64+
cp target/release/codewhale target/release/codew
6465
export PATH="$PWD/target/release:$PATH"
6566
node scripts/release/npm-wrapper-smoke.js
6667
./target/release/codewhale --version
6768
./target/release/codew --version
68-
./target/release/codewhale-tui --version
6969
7070
.linux_release_preflight: &linux_release_preflight
7171
name: linux release preflight
@@ -100,12 +100,12 @@
100100
set -eu
101101
# Keep the production release profile intact while avoiding a burst of
102102
# concurrent rustc/linker processes on the shared release runner.
103-
cargo build --jobs 2 --release --locked -p codewhale-cli -p codewhale-tui
103+
cargo build --jobs 2 --release --locked -p codewhale-cli
104+
cp target/release/codewhale target/release/codew
104105
export PATH="$PWD/target/release:$PATH"
105106
node scripts/release/npm-wrapper-smoke.js
106107
./target/release/codewhale --version
107108
./target/release/codew --version
108-
./target/release/codewhale-tui --version
109109
110110
main:
111111
push:
@@ -141,13 +141,13 @@ $:
141141
./scripts/release/check-ohos-deps.sh
142142
cargo build --jobs 2 --release --locked \
143143
--target x86_64-unknown-linux-musl \
144-
-p codewhale-cli -p codewhale-tui
144+
-p codewhale-cli # single binary
145145
146146
mkdir -p target/cnb-release
147147
BIN_DIR="target/x86_64-unknown-linux-musl/release"
148148
cp "$BIN_DIR/codewhale" target/cnb-release/codewhale-linux-x64
149-
cp "$BIN_DIR/codew" target/cnb-release/codew-linux-x64
150-
cp "$BIN_DIR/codewhale-tui" target/cnb-release/codewhale-tui-linux-x64
149+
cp "$BIN_DIR/codewhale" target/cnb-release/codew-linux-x64
150+
cp "$BIN_DIR/codewhale" target/cnb-release/codewhale-tui-linux-x64
151151
strip \
152152
target/cnb-release/codewhale-linux-x64 \
153153
target/cnb-release/codew-linux-x64 \
@@ -188,7 +188,7 @@ $:
188188
echo "Assets:"
189189
echo "- codewhale-linux-x64"
190190
echo "- codew-linux-x64"
191-
echo "- codewhale-tui-linux-x64"
191+
echo "- codewhale-tui-linux-x64 (v0.9.4 compatibility alias)"
192192
echo "- codewhale-artifacts-sha256.txt"
193193
} > target/cnb-release/CNB_RELEASE.md
194194

.github/AUTHOR_MAP

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,9 @@ heloanc = heloanc <61081755+heloanc@users.noreply.github.com>
183183
heloanc@users.noreply.github.com = heloanc <61081755+heloanc@users.noreply.github.com>
184184
bistack = Sun Zhenyuan <9128763+bistack@users.noreply.github.com>
185185
zhenyuan.sun@163.com = Sun Zhenyuan <9128763+bistack@users.noreply.github.com>
186+
skyzhao1223 = SKY ZHAO <15373810+skyzhao1223@users.noreply.github.com>
187+
zhaotian1 = SKY ZHAO <15373810+skyzhao1223@users.noreply.github.com>
188+
zhaotian1@wps.cn = SKY ZHAO <15373810+skyzhao1223@users.noreply.github.com>
186189
vFONGv = Matthew.Fong <21223725+vFONGv@users.noreply.github.com>
187190
fangb0987612345@gmail.com = Matthew.Fong <21223725+vFONGv@users.noreply.github.com>
188191
luismateusvargas = Luis Mateus Vargas <289766246+luismateusvargas@users.noreply.github.com>

.github/scripts/release-workflows.test.js

Lines changed: 101 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const {
99
allAssetNames,
1010
allReleaseAssetNames,
1111
BUNDLE_ASSET_NAMES,
12+
LEGACY_TUI_BRIDGE_ASSET_NAMES,
1213
} = require(path.join(repoRoot, "npm", "codewhale", "scripts", "artifacts"));
1314

1415
function read(relativePath) {
@@ -21,10 +22,14 @@ function valuesForKey(source, key) {
2122
}
2223

2324
const ci = read(".github/workflows/ci.yml");
25+
const nightly = read(".github/workflows/nightly.yml");
2426
const candidate = read(".github/workflows/release-candidate.yml");
2527
const artifacts = read(".github/workflows/release-artifacts.yml");
2628
const release = read(".github/workflows/release.yml");
29+
const cnb = read(".cnb.yml");
2730
const bundles = read("scripts/release/create-release-bundles.sh");
31+
const archiveInstaller = read("scripts/release/install.sh");
32+
const cliDispatcher = read("crates/cli/src/lib.rs");
2833
const runbook = read("docs/RELEASE_RUNBOOK.md");
2934

3035
assert.match(ci, /^ workflow_dispatch:\n inputs:\n expected_sha:/m);
@@ -37,6 +42,53 @@ for (const output of ["heavy", "workflow", "mobile", "actions"]) {
3742
}
3843
assert.match(manualForceBlock[1], /#EXPECTED_SHA.*-ne 40/s);
3944
assert.match(manualForceBlock[1], /actual.*EXPECTED_SHA/s);
45+
assert.match(
46+
ci,
47+
/run: cargo test -p codewhale-tui --test pty qa_pty::skills_opens_manager_owned_then_compatible -- --ignored --exact/,
48+
"CI must run the isolated Skills Manager acceptance from the consolidated PTY target",
49+
);
50+
assert.doesNotMatch(ci, /--test qa_pty\b/, "CI must not name the removed qa_pty target");
51+
52+
const expectedNightlyTargets = [
53+
"x86_64-unknown-linux-gnu",
54+
"aarch64-unknown-linux-gnu",
55+
"x86_64-apple-darwin",
56+
"aarch64-apple-darwin",
57+
"x86_64-pc-windows-msvc",
58+
"aarch64-pc-windows-msvc",
59+
].sort();
60+
assert.deepEqual([...new Set(valuesForKey(nightly, "target"))].sort(), expectedNightlyTargets);
61+
assert.deepEqual(
62+
[
63+
...valuesForKey(nightly, "primary_artifact"),
64+
...valuesForKey(nightly, "alias_artifact"),
65+
].sort(),
66+
[
67+
"codewhale-linux-x64",
68+
"codew-linux-x64",
69+
"codewhale-linux-arm64",
70+
"codew-linux-arm64",
71+
"codewhale-macos-x64",
72+
"codew-macos-x64",
73+
"codewhale-macos-arm64",
74+
"codew-macos-arm64",
75+
"codewhale-windows-x64.exe",
76+
"codew-windows-x64.exe",
77+
"codewhale-windows-arm64.exe",
78+
"codew-windows-arm64.exe",
79+
].sort(),
80+
);
81+
assert.match(
82+
nightly,
83+
/cargo build --release --locked --target \$\{\{ matrix\.target \}\} -p codewhale-cli/,
84+
);
85+
assert.match(nightly, /startsWith\(matrix\.target, 'x86_64-'\).*runner\.arch == 'X64'/s);
86+
assert.match(nightly, /startsWith\(matrix\.target, 'aarch64-'\).*runner\.arch == 'ARM64'/s);
87+
assert.doesNotMatch(nightly, /codewhale-tui/);
88+
assert.doesNotMatch(nightly, /target\/[^\n]*\/codew(?:\.exe)?/);
89+
assert.match(nightly, /cp "\$\{bin_path\}" "\$\{dir\}\/\$\{artifact\}"/);
90+
assert.match(nightly, /cmp -s[\s\S]*nightly-primary[\s\S]*nightly-alias/);
91+
assert.equal((nightly.match(/retention-days: 14/g) || []).length, 2);
4092

4193
assert.match(candidate, /^ workflow_dispatch:\n inputs:\n expected_sha:/m);
4294
assert.doesNotMatch(candidate, /^ (push|pull_request|schedule):/m);
@@ -118,10 +170,18 @@ const builtAssetNames = [
118170
assert.equal(builtAssetNames.length, 21);
119171
assert.deepEqual(
120172
[...new Set(builtAssetNames)].sort(),
121-
allAssetNames().filter((name) => name !== "codewhale.bat").sort(),
173+
[
174+
...allAssetNames().filter((name) => name !== "codewhale.bat"),
175+
...LEGACY_TUI_BRIDGE_ASSET_NAMES,
176+
].sort(),
177+
);
178+
assert.match(
179+
artifacts,
180+
/stage_binary "\$\{\{ matrix\.cli_binary \}\}" "\$\{\{ matrix\.tui_artifact \}\}"/,
181+
"legacy TUI bridge assets must be staged from the one compiled codewhale binary",
122182
);
123183
const bundleInvocations = [...bundles.matchAll(
124-
/^bundle (\S+) \\\n\s+\S+ \S+ \S+ (tar\.gz|zip) (""|portable)$/gm,
184+
/^bundle (\S+) \\\n\s+\S+ \S+ (tar\.gz|zip) (""|portable)$/gm,
125185
)].map((match) => {
126186
const variant = match[3] === "portable" ? "-portable" : "";
127187
return `codewhale-${match[1]}${variant}.${match[2]}`;
@@ -154,4 +214,42 @@ assert.match(runbook, /34/);
154214
assert.match(runbook, /does not create a tag/i);
155215
assert.match(runbook, /explicit.*approval/i);
156216

157-
console.log("Release workflow contracts OK: exact-head full CI and 7-target/34-asset non-publishing candidate.");
217+
const cnbPreflight = cnb.match(
218+
/\.linux_release_preflight: &linux_release_preflight([\s\S]*?)\nmain:/,
219+
);
220+
assert.ok(cnbPreflight, "CNB must retain a dedicated release preflight");
221+
const cnbBuild = cnbPreflight[1].indexOf(
222+
"cargo build --jobs 2 --release --locked -p codewhale-cli",
223+
);
224+
const cnbAlias = cnbPreflight[1].indexOf(
225+
"cp target/release/codewhale target/release/codew",
226+
);
227+
const cnbSmoke = cnbPreflight[1].indexOf("node scripts/release/npm-wrapper-smoke.js");
228+
assert.ok(cnbBuild >= 0, "CNB release preflight must build the consolidated runtime");
229+
assert.ok(cnbAlias > cnbBuild, "CNB release preflight must materialize codew after the build");
230+
assert.ok(cnbSmoke > cnbAlias, "CNB release preflight must materialize codew before smoke");
231+
232+
assert.doesNotMatch(
233+
archiveInstaller,
234+
/cargo install codewhale --locked/,
235+
"glibc recovery must name the published codewhale-cli crate",
236+
);
237+
assert.equal(
238+
(archiveInstaller.match(/cargo install codewhale-cli --locked/g) || []).length,
239+
2,
240+
"both glibc recovery branches must name codewhale-cli",
241+
);
242+
assert.match(
243+
archiveInstaller,
244+
/legacy_tui="\$BIN_DIR\/codewhale-tui"[\s\S]*install_binary "\$SCRIPT_DIR\/codewhale" "\$legacy_tui"/,
245+
"archive upgrades must refresh the retired TUI path from consolidated bytes",
246+
);
247+
assert.doesNotMatch(
248+
cliDispatcher,
249+
/codewhale_config::auto_model::classify/,
250+
"the CLI dispatcher must leave auto routing to the provider-aware runtime",
251+
);
252+
253+
console.log(
254+
"Workflow contracts OK: 6-target/12-asset single-runtime nightly and exact-head 7-target/34-asset release candidate.",
255+
);

.github/scripts/update-homebrew-tap.sh

Lines changed: 5 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -35,23 +35,19 @@ sha() {
3535

3636
# --- read checksums ---------------------------------------------------
3737

38-
# Canonical dispatcher and TUI
38+
# One compiled runtime exposed under the two supported command names.
3939
SHA_COD_MACOS_ARM="$(sha codewhale-macos-arm64)"
4040
SHA_CODEW_MACOS_ARM="$(sha codew-macos-arm64)"
41-
SHA_TUI_MACOS_ARM="$(sha codewhale-tui-macos-arm64)"
4241
SHA_COD_MACOS_X64="$(sha codewhale-macos-x64)"
4342
SHA_CODEW_MACOS_X64="$(sha codew-macos-x64)"
44-
SHA_TUI_MACOS_X64="$(sha codewhale-tui-macos-x64)"
4543
SHA_COD_LINUX_ARM="$(sha codewhale-linux-arm64)"
4644
SHA_CODEW_LINUX_ARM="$(sha codew-linux-arm64)"
47-
SHA_TUI_LINUX_ARM="$(sha codewhale-tui-linux-arm64)"
4845
SHA_COD_LINUX_X64="$(sha codewhale-linux-x64)"
4946
SHA_CODEW_LINUX_X64="$(sha codew-linux-x64)"
50-
SHA_TUI_LINUX_X64="$(sha codewhale-tui-linux-x64)"
51-
readonly SHA_COD_MACOS_ARM SHA_CODEW_MACOS_ARM SHA_TUI_MACOS_ARM
52-
readonly SHA_COD_MACOS_X64 SHA_CODEW_MACOS_X64 SHA_TUI_MACOS_X64
53-
readonly SHA_COD_LINUX_ARM SHA_CODEW_LINUX_ARM SHA_TUI_LINUX_ARM
54-
readonly SHA_COD_LINUX_X64 SHA_CODEW_LINUX_X64 SHA_TUI_LINUX_X64
47+
readonly SHA_COD_MACOS_ARM SHA_CODEW_MACOS_ARM
48+
readonly SHA_COD_MACOS_X64 SHA_CODEW_MACOS_X64
49+
readonly SHA_COD_LINUX_ARM SHA_CODEW_LINUX_ARM
50+
readonly SHA_COD_LINUX_X64 SHA_CODEW_LINUX_X64
5551

5652
# --- temp dirs --------------------------------------------------------
5753

@@ -78,21 +74,13 @@ class DeepseekTui < Formula
7874
url "${BASE_URL}/codew-macos-arm64", using: :nounzip
7975
sha256 "${SHA_CODEW_MACOS_ARM}"
8076
end
81-
resource "tui" do
82-
url "${BASE_URL}/codewhale-tui-macos-arm64", using: :nounzip
83-
sha256 "${SHA_TUI_MACOS_ARM}"
84-
end
8577
else
8678
url "${BASE_URL}/codewhale-macos-x64", using: :nounzip
8779
sha256 "${SHA_COD_MACOS_X64}"
8880
resource "codew" do
8981
url "${BASE_URL}/codew-macos-x64", using: :nounzip
9082
sha256 "${SHA_CODEW_MACOS_X64}"
9183
end
92-
resource "tui" do
93-
url "${BASE_URL}/codewhale-tui-macos-x64", using: :nounzip
94-
sha256 "${SHA_TUI_MACOS_X64}"
95-
end
9684
end
9785
end
9886
@@ -104,34 +92,24 @@ class DeepseekTui < Formula
10492
url "${BASE_URL}/codew-linux-arm64", using: :nounzip
10593
sha256 "${SHA_CODEW_LINUX_ARM}"
10694
end
107-
resource "tui" do
108-
url "${BASE_URL}/codewhale-tui-linux-arm64", using: :nounzip
109-
sha256 "${SHA_TUI_LINUX_ARM}"
110-
end
11195
else
11296
url "${BASE_URL}/codewhale-linux-x64", using: :nounzip
11397
sha256 "${SHA_COD_LINUX_X64}"
11498
resource "codew" do
11599
url "${BASE_URL}/codew-linux-x64", using: :nounzip
116100
sha256 "${SHA_CODEW_LINUX_X64}"
117101
end
118-
resource "tui" do
119-
url "${BASE_URL}/codewhale-tui-linux-x64", using: :nounzip
120-
sha256 "${SHA_TUI_LINUX_X64}"
121-
end
122102
end
123103
end
124104
125105
def install
126106
bin.install Dir["*"].first => "codewhale"
127107
resource("codew").stage { bin.install Dir["*"].first => "codew" }
128-
resource("tui").stage { bin.install Dir["*"].first => "codewhale-tui" }
129108
end
130109
131110
test do
132111
system "#{bin}/codewhale", "--version"
133112
system "#{bin}/codew", "--version"
134-
system "#{bin}/codewhale-tui", "--version"
135113
end
136114
end
137115
EOF

.github/scripts/update-homebrew-tap.test.sh

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,12 @@ formula="${tmp_dir}/deepseek-tui.rb"
1111
assets=(
1212
codewhale-macos-arm64
1313
codew-macos-arm64
14-
codewhale-tui-macos-arm64
1514
codewhale-macos-x64
1615
codew-macos-x64
17-
codewhale-tui-macos-x64
1816
codewhale-linux-arm64
1917
codew-linux-arm64
20-
codewhale-tui-linux-arm64
2118
codewhale-linux-x64
2219
codew-linux-x64
23-
codewhale-tui-linux-x64
2420
)
2521

2622
for asset in "${assets[@]}"; do
@@ -38,6 +34,9 @@ grep -Fq 'desc "Agentic terminal for open-source and open-weight coding models"'
3834
test "$(grep -Fc 'resource "codew" do' "${formula}")" -eq 4
3935
grep -Fq 'bin.install Dir["*"].first => "codew"' "${formula}"
4036
grep -Fq 'system "#{bin}/codew", "--version"' "${formula}"
41-
grep -Fq 'system "#{bin}/codewhale-tui", "--version"' "${formula}"
37+
if grep -Fq 'codewhale-tui' "${formula}"; then
38+
echo "Homebrew formula must not install the legacy TUI compatibility asset" >&2
39+
exit 1
40+
fi
4241

4342
echo "update-homebrew-tap tests passed"

.github/workflows/ci.yml

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,11 @@ jobs:
270270
- name: Check dead-code budget
271271
if: needs.changes.outputs.heavy == 'true'
272272
run: python3 scripts/check-dead-code-budget.py
273+
- name: Test runtime-contract measurement harness
274+
if: needs.changes.outputs.heavy == 'true'
275+
run: |
276+
python3 scripts/test_measure_runtime_contract.py
277+
python3 scripts/test_check_runtime_contract_budget.py
273278
# The offline runtime-contract measurement needs the full locked graph,
274279
# dev-dependencies included (e.g. wiremock -> assert-json-diff), but
275280
# clippy above builds no test targets and the rust-cache registry key
@@ -289,9 +294,11 @@ jobs:
289294
# Provider-free paused-consumer measurement of the production
290295
# persistence request channel. RSS is sampled only on macOS; every host
291296
# enforces the accepted/retained request and payload contract.
292-
- name: Test persistence-backlog checker
297+
- name: Test persistence-backlog measurement and checker harnesses
293298
if: needs.changes.outputs.heavy == 'true'
294-
run: python3 scripts/test_check_persistence_backlog_budget.py
299+
run: |
300+
python3 scripts/test_measure_persistence_backlog.py
301+
python3 scripts/test_check_persistence_backlog_budget.py
295302
- name: Check persistence-backlog budget
296303
if: needs.changes.outputs.heavy == 'true'
297304
run: python3 scripts/check-persistence-backlog-budget.py
@@ -451,10 +458,11 @@ jobs:
451458
- name: Run isolated Skills Manager PTY acceptance
452459
# This real-PTY scenario is deterministic in a fresh process (10/10
453460
# locally) but can inherit event starvation after the full qa_pty
454-
# suite on loaded Linux runners. Keep the assertion intact and run it
455-
# separately on Unix after the workspace suite has released its PTYs.
461+
# module suite on loaded Linux runners. Keep the assertion intact and
462+
# run it separately on Unix after the workspace suite has released its
463+
# PTYs.
456464
if: needs.changes.outputs.heavy == 'true' && matrix.os != 'windows-latest' && (matrix.os != 'ubuntu-latest' || github.event_name == 'workflow_dispatch')
457-
run: cargo test -p codewhale-tui --test qa_pty skills_opens_manager_owned_then_compatible -- --ignored --exact
465+
run: cargo test -p codewhale-tui --test pty qa_pty::skills_opens_manager_owned_then_compatible -- --ignored --exact
458466
- name: Lockfile drift guard
459467
if: needs.changes.outputs.heavy == 'true' && (matrix.os != 'ubuntu-latest' || github.event_name == 'workflow_dispatch')
460468
run: git diff --exit-code -- Cargo.lock

0 commit comments

Comments
 (0)