mirror of
https://github.com/hanzoai/dev.git
synced 2026-10-25 03:32:32 +00:00
fix(cli/windows): always print bootstrap error; remove debug gate
Also: - chore(release): delete legacy stage_release.sh and remove references - ci(release): add ESM integrity guard for bin/coder.js in npm pack tarball - docs(npm): clarify prepublishOnly guidance
This commit is contained in:
@@ -523,6 +523,28 @@ jobs:
|
||||
fi
|
||||
echo "tag=v${NEW_VERSION}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Verify ESM bin integrity (no require in coder.js)
|
||||
shell: bash
|
||||
working-directory: codex-cli
|
||||
run: |
|
||||
set -euo pipefail
|
||||
tgz=$(npm pack --json | jq -r '.[0].filename')
|
||||
mkdir -p .pack && tar -xzf "$tgz" -C .pack
|
||||
BIN=".pack/package/bin/coder.js"
|
||||
test -f "$BIN" || { echo "coder.js missing in packed tarball" >&2; exit 1; }
|
||||
if grep -q "require(\"fs\").createWriteStream" "$BIN"; then
|
||||
echo "Found CommonJS require in coder.js; expected ESM. Failing." >&2
|
||||
sed -n '1,60p' "$BIN" >&2 || true
|
||||
exit 1
|
||||
fi
|
||||
# Sanity: ensure ESM import of fs functions exists
|
||||
if ! grep -q "import .*from \"fs\"" "$BIN"; then
|
||||
echo "Missing ESM import from fs in coder.js; unexpected content." >&2
|
||||
sed -n '1,80p' "$BIN" >&2 || true
|
||||
exit 1
|
||||
fi
|
||||
echo "ESM integrity OK for coder.js"
|
||||
|
||||
# Generate CHANGELOG and release notes by running our own `code` CLI in headless mode.
|
||||
# It will:
|
||||
# - Review changes between the previous tag and the new version
|
||||
|
||||
@@ -132,6 +132,8 @@ const getCachedBinaryPath = (version) => {
|
||||
return path.join(cacheDir, `code-${targetTriple}${ext}`);
|
||||
};
|
||||
|
||||
let lastBootstrapError = null;
|
||||
|
||||
const httpsDownload = (url, dest) => new Promise((resolve, reject) => {
|
||||
const req = httpsGet(url, (res) => {
|
||||
const status = res.statusCode || 0;
|
||||
@@ -255,7 +257,7 @@ const tryBootstrapBinary = async () => {
|
||||
if (platform !== "win32") try { chmodSync(binaryPath, 0o755); } catch {}
|
||||
return true;
|
||||
})
|
||||
.catch((_e) => false);
|
||||
.catch((e) => { lastBootstrapError = e; return false; });
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
@@ -301,6 +303,10 @@ if (existsSync(binaryPath)) {
|
||||
}
|
||||
} else {
|
||||
console.error(`Binary not found: ${binaryPath}`);
|
||||
if (lastBootstrapError) {
|
||||
const msg = (lastBootstrapError && (lastBootstrapError.message || String(lastBootstrapError))) || 'unknown bootstrap error';
|
||||
console.error(`Bootstrap error: ${msg}`);
|
||||
}
|
||||
console.error(`Please try reinstalling the package:`);
|
||||
console.error(` npm uninstall -g @just-every/code`);
|
||||
console.error(` npm install -g @just-every/code`);
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
"scripts": {
|
||||
"preinstall": "node scripts/preinstall.js",
|
||||
"postinstall": "node postinstall.js",
|
||||
"prepublishOnly": "node -e \"const fs=require('fs'),path=require('path'); const repoGit=path.join(__dirname,'..','.git'); const inCi=process.env.GITHUB_ACTIONS==='true'||process.env.CI==='true'; if(fs.existsSync(repoGit) && !inCi){ console.error('Refusing to publish from codex-cli. Use codex-cli/scripts/stage_release.sh to stage a release.'); process.exit(1);} else { console.log(inCi ? 'CI publish detected.' : 'Publishing staged package...'); }\""
|
||||
"prepublishOnly": "node -e \"const fs=require('fs'),path=require('path'); const repoGit=path.join(__dirname,'..','.git'); const inCi=process.env.GITHUB_ACTIONS==='true'||process.env.CI==='true'; if(fs.existsSync(repoGit) && !inCi){ console.error('Refusing to publish from codex-cli. Publishing happens via release.yml.'); process.exit(1);} else { console.log(inCi ? 'CI publish detected.' : 'Publishing staged package...'); }\""
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -1,120 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# -----------------------------------------------------------------------------
|
||||
# stage_release.sh
|
||||
# -----------------------------------------------------------------------------
|
||||
# Stages an npm release for @openai/codex.
|
||||
#
|
||||
# Usage:
|
||||
#
|
||||
# --tmp <dir> : Use <dir> instead of a freshly created temp directory.
|
||||
# -h|--help : Print usage.
|
||||
#
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Helper - usage / flag parsing
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: $(basename "$0") [--tmp DIR] [--version VERSION]
|
||||
|
||||
Options
|
||||
--tmp DIR Use DIR to stage the release (defaults to a fresh mktemp dir)
|
||||
--version Specify the version to release (defaults to a timestamp-based version)
|
||||
-h, --help Show this help
|
||||
|
||||
Legacy positional argument: the first non-flag argument is still interpreted
|
||||
as the temporary directory (for backwards compatibility) but is deprecated.
|
||||
EOF
|
||||
exit "${1:-0}"
|
||||
}
|
||||
|
||||
TMPDIR=""
|
||||
# Default to a timestamp-based version (keep same scheme as before)
|
||||
VERSION="$(printf '0.1.%d' "$(date +%y%m%d%H%M)")"
|
||||
WORKFLOW_URL=""
|
||||
|
||||
# Manual flag parser - Bash getopts does not handle GNU long options well.
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--tmp)
|
||||
shift || { echo "--tmp requires an argument"; usage 1; }
|
||||
TMPDIR="$1"
|
||||
;;
|
||||
--tmp=*)
|
||||
TMPDIR="${1#*=}"
|
||||
;;
|
||||
--version)
|
||||
shift || { echo "--version requires an argument"; usage 1; }
|
||||
VERSION="$1"
|
||||
;;
|
||||
--workflow-url)
|
||||
shift || { echo "--workflow-url requires an argument"; exit 1; }
|
||||
WORKFLOW_URL="$1"
|
||||
;;
|
||||
-h|--help)
|
||||
usage 0
|
||||
;;
|
||||
--*)
|
||||
echo "Unknown option: $1" >&2
|
||||
usage 1
|
||||
;;
|
||||
*)
|
||||
echo "Unexpected extra argument: $1" >&2
|
||||
usage 1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# Fallback when the caller did not specify a directory.
|
||||
# If no directory was specified create a fresh temporary one.
|
||||
if [[ -z "$TMPDIR" ]]; then
|
||||
TMPDIR="$(mktemp -d)"
|
||||
fi
|
||||
|
||||
# Ensure the directory exists, then resolve to an absolute path.
|
||||
mkdir -p "$TMPDIR"
|
||||
TMPDIR="$(cd "$TMPDIR" && pwd)"
|
||||
|
||||
# Main build logic
|
||||
|
||||
echo "Staging release in $TMPDIR"
|
||||
|
||||
# The script lives in codex-cli/scripts/ - change into codex-cli root so that
|
||||
# relative paths keep working.
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
CODEX_CLI_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
|
||||
pushd "$CODEX_CLI_ROOT" >/dev/null
|
||||
|
||||
# 1. Build the JS artifacts ---------------------------------------------------
|
||||
|
||||
# Paths inside the staged package
|
||||
mkdir -p "$TMPDIR/bin"
|
||||
|
||||
cp -r bin/codex.js "$TMPDIR/bin/codex.js"
|
||||
cp ../README.md "$TMPDIR" || true # README is one level up - ignore if missing
|
||||
|
||||
# Modify package.json - bump version and optionally add the native directory to
|
||||
# the files array so that the binaries are published to npm.
|
||||
|
||||
jq --arg version "$VERSION" \
|
||||
'.version = $version' \
|
||||
package.json > "$TMPDIR/package.json"
|
||||
|
||||
# 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
|
||||
|
||||
echo "Staged version $VERSION for release in $TMPDIR"
|
||||
|
||||
echo "Verify the CLI:"
|
||||
echo " node ${TMPDIR}/bin/codex.js --version"
|
||||
echo " node ${TMPDIR}/bin/codex.js --help"
|
||||
|
||||
# Print final hint for convenience
|
||||
echo "Next: cd \"$TMPDIR\" && npm publish"
|
||||
@@ -14,17 +14,14 @@ def main() -> int:
|
||||
Run this after the GitHub Release has been created and use
|
||||
`--release-version` to specify the version to release.
|
||||
|
||||
Optionally pass `--tmp` to control the temporary staging directory that will be
|
||||
forwarded to stage_release.sh.
|
||||
Optionally pass `--tmp` to control the temporary staging directory used by
|
||||
release CI to build the npm package.
|
||||
"""
|
||||
)
|
||||
parser.add_argument(
|
||||
"--release-version", required=True, help="Version to release, e.g., 0.3.0"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--tmp",
|
||||
help="Optional path to stage the npm package; forwarded to stage_release.sh",
|
||||
)
|
||||
parser.add_argument("--tmp", help="Optional path to stage the npm package")
|
||||
args = parser.parse_args()
|
||||
version = args.release_version
|
||||
|
||||
@@ -49,19 +46,11 @@ forwarded to stage_release.sh.
|
||||
|
||||
print(f"should `git checkout {sha}`")
|
||||
|
||||
current_dir = Path(__file__).parent.resolve()
|
||||
cmd = [
|
||||
str(current_dir / "stage_release.sh"),
|
||||
"--version",
|
||||
version,
|
||||
"--workflow-url",
|
||||
workflow["url"],
|
||||
]
|
||||
if args.tmp:
|
||||
cmd.extend(["--tmp", args.tmp])
|
||||
|
||||
stage_release = subprocess.run(cmd)
|
||||
stage_release.check_returncode()
|
||||
# The release pipeline is handled by GitHub Actions (release.yml). This
|
||||
# helper now only locates the rust-release workflow run for the given
|
||||
# version and prints the checkout hint. Staging and npm publish are driven
|
||||
# by CI.
|
||||
print("Release staging is handled by release.yml; no local staging step.")
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
Reference in New Issue
Block a user