release: slimmer assets + zstd fallback (.zst/.tar.gz)\n\n- Dual-format artifacts for macOS and Linux (.zst + .tar.gz)\n- Postinstall picks one: prefers .zst when zstd available, else .tar.gz\n- Windows stays .zip\n- Trim npm package (no embedded natives)\n- release-prod strips debuginfo; warning cleanup

This commit is contained in:
James Peter
2025-08-27 10:33:56 +10:00
parent b13312f79a
commit f5f2fd099e
12 changed files with 116 additions and 267 deletions
+40 -8
View File
@@ -60,15 +60,10 @@ jobs:
- os: ubuntu-24.04
target: x86_64-unknown-linux-musl
artifact: code-x86_64-unknown-linux-musl
- os: ubuntu-24.04
target: x86_64-unknown-linux-gnu
artifact: code-x86_64-unknown-linux-gnu
- os: ubuntu-24.04-arm
target: aarch64-unknown-linux-musl
artifact: code-aarch64-unknown-linux-musl
- os: ubuntu-24.04-arm
target: aarch64-unknown-linux-gnu
artifact: code-aarch64-unknown-linux-gnu
# (GNU variants omitted to reduce asset duplication; npm defaults to musl)
# macOS builds
- os: macos-14
target: x86_64-apple-darwin
@@ -250,7 +245,44 @@ jobs:
cp codex-rs/target/${{ matrix.target }}/release/code-exec artifacts/code-exec-${{ matrix.target }}
fi
- name: Upload binaries (no compression)
- name: Compress artifacts (Windows)
if: matrix.os == 'windows-latest'
shell: pwsh
run: |
Get-ChildItem artifacts -File | ForEach-Object {
$src = $_.FullName
$dst = "$src.zip"
Compress-Archive -Path $src -DestinationPath $dst -Force
Remove-Item $src -Force
}
- name: Compress artifacts (Linux dual-format)
if: contains(matrix.os, 'ubuntu')
shell: bash
run: |
for f in artifacts/*; do
base=$(basename "$f")
# .zst (size-optimized)
zstd -T0 -19 --force -o "artifacts/${base}.zst" "$f"
# .tar.gz fallback for users without zstd
tar -C artifacts -czf "artifacts/${base}.tar.gz" "$base"
rm -f "$f"
done
- name: Compress artifacts (macOS dual-format)
if: startsWith(matrix.os, 'macos-')
shell: bash
run: |
for f in artifacts/*; do
base=$(basename "$f")
# .zst (size-optimized)
zstd -T0 -19 --force -o "artifacts/${base}.zst" "$f"
# .tar.gz fallback for users without zstd
tar -C artifacts -czf "artifacts/${base}.tar.gz" "$base"
rm -f "$f"
done
- name: Upload binaries (compressed)
uses: actions/upload-artifact@v4
with:
name: binaries-${{ matrix.target }}
@@ -378,4 +410,4 @@ jobs:
files: |
release-assets/*
env:
GITHUB_TOKEN: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }}
+10 -24
View File
@@ -63,12 +63,8 @@ jobs:
target: x86_64-apple-darwin
- runner: ubuntu-24.04
target: x86_64-unknown-linux-musl
- runner: ubuntu-24.04
target: x86_64-unknown-linux-gnu
- runner: ubuntu-24.04-arm
target: aarch64-unknown-linux-musl
- runner: ubuntu-24.04-arm
target: aarch64-unknown-linux-gnu
- runner: windows-latest
target: x86_64-pc-windows-msvc
@@ -196,35 +192,25 @@ jobs:
# ${{ matrix.target }}
dest="dist/${{ matrix.target }}"
# For compatibility with environments that lack the `zstd` tool we
# additionally create a `.tar.gz` alongside every single binary that
# we publish. The end result is:
# code-<target>.zst (zstd compressed)
# code-<target>.tar.gz (fallback for envs without zstd)
# Use single format per OS:
# - Linux/macOS: .zst (smaller, well-supported)
# - Windows: .zip (standard for Windows)
# 1. Produce a .tar.gz for every file in the directory *before* we
# run `zstd --rm`, because that flag deletes the original files.
for f in "$dest"/*; do
base="$(basename "$f")"
# Skip files that are already archives (shouldn't happen, but be
# safe).
if [[ "$base" == *.tar.gz || "$base" == *.zip ]]; then
# Skip files that are already archives
if [[ "$base" == *.tar.gz || "$base" == *.zip || "$base" == *.zst ]]; then
continue
fi
# Create per-binary tar.gz
tar -C "$dest" -czf "$dest/${base}.tar.gz" "$base"
# Create zip archive for Windows binaries
# Must run from inside the dest dir so 7z won't
# embed the directory path inside the zip.
if [[ "${{ matrix.runner }}" == windows* ]]; then
# Windows: Create only .zip
(cd "$dest" && 7z a "${base}.zip" "$base")
rm "$dest/$base"
else
# Linux/macOS: Create only .zst
zstd -T0 -19 --rm "$dest/$base"
fi
# Also create .zst (existing behaviour) *and* remove the original
# uncompressed binary to keep the directory small.
zstd -T0 -19 --rm "$dest/$base"
done
- uses: actions/upload-artifact@v4
+55 -8
View File
@@ -186,7 +186,7 @@ async function main() {
const packageJson = JSON.parse(readFileSync(join(__dirname, 'package.json'), 'utf8'));
const version = packageJson.version;
// Binary names to download (new naming is 'code*')
// Binary names to download (standardized 'code-*' naming)
const binaries = ['code', 'code-tui', 'code-exec'];
console.log(`Installing @just-every/code v${version} for ${targetTriple}...`);
@@ -211,11 +211,58 @@ async function main() {
continue;
}
const downloadUrl = `https://github.com/just-every/code/releases/download/v${version}/${binaryName}`;
console.log(`Downloading ${binaryName}...`);
// Decide archive format per OS with fallback on macOS/Linux:
// - Windows: .zip
// - macOS/Linux: prefer .zst if `zstd` CLI is available; otherwise use .tar.gz
const isWin = isWindows;
let useZst = false;
if (!isWin) {
try {
execSync('zstd --version', { stdio: 'ignore', shell: true });
useZst = true;
} catch {
useZst = false;
}
}
const archiveName = isWin ? `${binaryName}.zip` : (useZst ? `${binaryName}.zst` : `${binaryName}.tar.gz`);
const downloadUrl = `https://github.com/just-every/code/releases/download/v${version}/${archiveName}`;
console.log(`Downloading ${archiveName}...`);
try {
await downloadBinary(downloadUrl, localPath);
const tmpPath = join(binDir, `.${archiveName}.part`);
await downloadBinary(downloadUrl, tmpPath);
if (isWin) {
// Unzip the single-file archive using PowerShell (built-in)
try {
const psCmd = `powershell -NoProfile -NonInteractive -Command "Expand-Archive -Path '${tmpPath}' -DestinationPath '${binDir}' -Force"`;
execSync(psCmd, { stdio: 'ignore' });
} catch (e) {
throw new Error(`failed to unzip archive: ${e.message}`);
} finally {
try { unlinkSync(tmpPath); } catch {}
}
} else {
if (useZst) {
// Decompress .zst via system zstd
try {
execSync(`zstd -d '${tmpPath}' -o '${localPath}'`, { stdio: 'ignore', shell: true });
} catch (e) {
try { unlinkSync(tmpPath); } catch {}
throw new Error(`failed to decompress .zst (need zstd CLI): ${e.message}`);
}
try { unlinkSync(tmpPath); } catch {}
} else {
// Extract .tar.gz using system tar
try {
execSync(`tar -xzf '${tmpPath}' -C '${binDir}'`, { stdio: 'ignore', shell: true });
} catch (e) {
try { unlinkSync(tmpPath); } catch {}
throw new Error(`failed to extract .tar.gz: ${e.message}`);
}
try { unlinkSync(tmpPath); } catch {}
}
}
// Validate header to avoid corrupt binaries causing spawn EFTYPE/ENOEXEC
const valid = validateDownloadedBinary(localPath);
@@ -229,10 +276,10 @@ async function main() {
chmodSync(localPath, 0o755);
}
console.log(`✓ Downloaded ${binaryName}`);
console.log(`✓ Installed ${binaryName}`);
} catch (error) {
console.error(`✗ Failed to download ${binaryName}: ${error.message}`);
console.error(` URL: ${downloadUrl}`);
console.error(`✗ Failed to install ${binaryName}: ${error.message}`);
console.error(` Downloaded from: ${downloadUrl}`);
// Continue with other binaries even if one fails
}
}
+3 -3
View File
@@ -104,9 +104,9 @@ jq --arg version "$VERSION" \
'.version = $version' \
package.json > "$TMPDIR/package.json"
# 2. Native runtime deps (sandbox plus optional Rust binaries)
./scripts/install_native_deps.sh --workflow-url "$WORKFLOW_URL" "$TMPDIR"
# 2. Native runtime deps - SKIPPED
# Binaries are now fetched on-demand via postinstall.js to reduce npm package size
# ./scripts/install_native_deps.sh --workflow-url "$WORKFLOW_URL" "$TMPDIR"
popd >/dev/null
+1 -211
View File
@@ -856,7 +856,6 @@ dependencies = [
"maplit",
"mcp-types",
"mime_guess",
"openssl-sys",
"os_info",
"portable-pty",
"predicates",
@@ -1223,16 +1222,6 @@ dependencies = [
"unicode-segmentation",
]
[[package]]
name = "core-foundation"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "core-foundation"
version = "0.10.1"
@@ -1671,15 +1660,6 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0"
[[package]]
name = "encoding_rs"
version = "0.8.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3"
dependencies = [
"cfg-if",
]
[[package]]
name = "endian-type"
version = "0.1.2"
@@ -1917,21 +1897,6 @@ version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
[[package]]
name = "foreign-types"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
dependencies = [
"foreign-types-shared",
]
[[package]]
name = "foreign-types-shared"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
[[package]]
name = "form_urlencoded"
version = "1.2.2"
@@ -2321,22 +2286,6 @@ dependencies = [
"webpki-roots",
]
[[package]]
name = "hyper-tls"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0"
dependencies = [
"bytes",
"http-body-util",
"hyper",
"hyper-util",
"native-tls",
"tokio",
"tokio-native-tls",
"tower-service",
]
[[package]]
name = "hyper-util"
version = "0.1.16"
@@ -2356,11 +2305,9 @@ dependencies = [
"percent-encoding",
"pin-project-lite",
"socket2 0.6.0",
"system-configuration",
"tokio",
"tower-service",
"tracing",
"windows-registry",
]
[[package]]
@@ -3133,23 +3080,6 @@ dependencies = [
"serde",
]
[[package]]
name = "native-tls"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e"
dependencies = [
"libc",
"log",
"openssl",
"openssl-probe",
"openssl-sys",
"schannel",
"security-framework",
"security-framework-sys",
"tempfile",
]
[[package]]
name = "ndk-context"
version = "0.1.1"
@@ -3457,60 +3387,6 @@ dependencies = [
"pkg-config",
]
[[package]]
name = "openssl"
version = "0.10.73"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8"
dependencies = [
"bitflags 2.9.3",
"cfg-if",
"foreign-types",
"libc",
"once_cell",
"openssl-macros",
"openssl-sys",
]
[[package]]
name = "openssl-macros"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.106",
]
[[package]]
name = "openssl-probe"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
[[package]]
name = "openssl-src"
version = "300.5.2+3.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d270b79e2926f5150189d475bc7e9d2c69f9c4697b185fa917d5a32b792d21b4"
dependencies = [
"cc",
]
[[package]]
name = "openssl-sys"
version = "0.9.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571"
dependencies = [
"cc",
"libc",
"openssl-src",
"pkg-config",
"vcpkg",
]
[[package]]
name = "option-ext"
version = "0.2.0"
@@ -4215,22 +4091,17 @@ checksum = "d429f34c8092b2d42c7c93cec323bb4adeb7c67698f70839adec842ec10c7ceb"
dependencies = [
"base64 0.22.1",
"bytes",
"encoding_rs",
"futures-channel",
"futures-core",
"futures-util",
"h2",
"http",
"http-body",
"http-body-util",
"hyper",
"hyper-rustls",
"hyper-tls",
"hyper-util",
"js-sys",
"log",
"mime",
"native-tls",
"percent-encoding",
"pin-project-lite",
"quinn",
@@ -4241,7 +4112,6 @@ dependencies = [
"serde_urlencoded",
"sync_wrapper",
"tokio",
"tokio-native-tls",
"tokio-rustls",
"tokio-util",
"tower",
@@ -4452,15 +4322,6 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "schannel"
version = "0.1.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d"
dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "schemafy"
version = "0.5.2"
@@ -4566,29 +4427,6 @@ dependencies = [
"libc",
]
[[package]]
name = "security-framework"
version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
dependencies = [
"bitflags 2.9.3",
"core-foundation 0.9.4",
"core-foundation-sys",
"libc",
"security-framework-sys",
]
[[package]]
name = "security-framework-sys"
version = "2.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "semver"
version = "1.0.26"
@@ -5143,27 +4981,6 @@ dependencies = [
"yaml-rust",
]
[[package]]
name = "system-configuration"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b"
dependencies = [
"bitflags 2.9.3",
"core-foundation 0.9.4",
"system-configuration-sys",
]
[[package]]
name = "system-configuration-sys"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "system-deps"
version = "6.2.2"
@@ -5422,16 +5239,6 @@ dependencies = [
"syn 2.0.106",
]
[[package]]
name = "tokio-native-tls"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
dependencies = [
"native-tls",
"tokio",
]
[[package]]
name = "tokio-rustls"
version = "0.26.2"
@@ -5944,12 +5751,6 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
[[package]]
name = "vcpkg"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "version-compare"
version = "0.2.0"
@@ -6142,7 +5943,7 @@ version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aaf4f3c0ba838e82b4e5ccc4157003fb8c324ee24c058470ffb82820becbde98"
dependencies = [
"core-foundation 0.10.1",
"core-foundation",
"jni",
"log",
"ndk-context",
@@ -6313,17 +6114,6 @@ version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
[[package]]
name = "windows-registry"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e"
dependencies = [
"windows-link",
"windows-result 0.3.4",
"windows-strings 0.4.2",
]
[[package]]
name = "windows-result"
version = "0.2.0"
+1
View File
@@ -61,6 +61,7 @@ inherits = "release"
incremental = false # Disable for production builds
codegen-units = 1 # Single codegen unit for best optimization
lto = "fat" # Maximum link-time optimization
strip = "debuginfo" # Fully strip debug info in production artifacts
[patch.crates-io]
# ratatui = { path = "../../ratatui" }
+1 -1
View File
@@ -12,7 +12,7 @@ clap = { version = "4", features = ["derive"] }
codex-common = { path = "../common", features = ["cli"] }
codex-core = { path = "../core" }
codex-login = { path = "../login" }
reqwest = { version = "0.12", features = ["json", "stream"] }
reqwest = { version = "0.12", default-features = false, features = ["json", "stream", "rustls-tls"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
tokio = { version = "1", features = ["full"] }
+2 -8
View File
@@ -36,7 +36,7 @@ os_info = "3.12.0"
portable-pty = "0.9.0"
rand = "0.9"
regex-lite = "0.1.6"
reqwest = { version = "0.12", features = ["json", "stream"] }
reqwest = { version = "0.12", default-features = false, features = ["json", "stream", "rustls-tls"] }
serde = { version = "1", features = ["derive"] }
serde_bytes = "0.11"
serde_json = "1"
@@ -70,13 +70,7 @@ wildmatch = "2.4.0"
landlock = "0.4.1"
seccompiler = "0.5.0"
# Build OpenSSL from source for musl builds.
[target.x86_64-unknown-linux-musl.dependencies]
openssl-sys = { version = "*", features = ["vendored"] }
# Build OpenSSL from source for musl builds.
[target.aarch64-unknown-linux-musl.dependencies]
openssl-sys = { version = "*", features = ["vendored"] }
# OpenSSL vendoring removed - using rustls-tls instead for all targets
[target.'cfg(target_os = "windows")'.dependencies]
which = "6"
+1 -1
View File
@@ -11,7 +11,7 @@ base64 = "0.22"
chrono = { version = "0.4", features = ["serde"] }
codex-protocol = { path = "../protocol" }
rand = "0.8"
reqwest = { version = "0.12", features = ["json", "blocking"] }
reqwest = { version = "0.12", default-features = false, features = ["json", "blocking", "rustls-tls"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
sha2 = "0.10"
+1 -1
View File
@@ -15,7 +15,7 @@ async-stream = "0.3"
bytes = "1.10.1"
codex-core = { path = "../core" }
futures = "0.3"
reqwest = { version = "0.12", features = ["json", "stream"] }
reqwest = { version = "0.12", default-features = false, features = ["json", "stream", "rustls-tls"] }
serde_json = "1"
tokio = { version = "1", features = [
"io-std",
+1 -1
View File
@@ -55,7 +55,7 @@ ratatui = { version = "0.29.0", features = [
] }
ratatui-image = "8.0.0"
regex-lite = "0.1"
reqwest = { version = "0.12", features = ["json"] }
reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] }
serde = { version = "1", features = ["derive"] }
serde_json = { version = "1", features = ["preserve_order"] }
shlex = "1.3.0"
-1
View File
@@ -1,7 +1,6 @@
#![cfg(any(not(debug_assertions), test))]
use chrono::DateTime;
use chrono::Duration;
use chrono::Utc;
use serde::Deserialize;
use serde::Serialize;