From 3f5975ad5a5aaa1fb4054682e4f2dedfdf856abc Mon Sep 17 00:00:00 2001 From: Michael Bolin Date: Thu, 1 May 2025 08:36:07 -0700 Subject: [PATCH] chore: make build process a single script to run (#757) This introduces `./codex-cli/scripts/stage_release.sh`, which is a shell script that stages a release for the Node.js module in a temp directory. It updates the release to include these native binaries: ``` bin/codex-linux-sandbox-arm64 bin/codex-linux-sandbox-x64 ``` though this PR does not update Codex CLI to use them yet. When doing local development, run `./codex-cli/scripts/install_native_deps.sh` to install these in your own `bin/` folder. This PR also updates `README.md` to document the new workflow. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/757). * #763 * __->__ #757 --- .github/workflows/ci.yml | 6 +++ README.md | 32 ++++++++----- codex-cli/.gitignore | 3 ++ codex-cli/package.json | 5 +- codex-cli/scripts/install_native_deps.sh | 61 ++++++++++++++++++++++++ codex-cli/scripts/stage_release.sh | 28 +++++++++++ 6 files changed, 120 insertions(+), 15 deletions(-) create mode 100644 codex-cli/.gitignore create mode 100755 codex-cli/scripts/install_native_deps.sh create mode 100755 codex-cli/scripts/stage_release.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 508b5b9b..24697f2f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -68,6 +68,12 @@ jobs: - name: Build run: pnpm run build + - name: Ensure staging a release works. + working-directory: codex-cli + env: + GH_TOKEN: ${{ github.token }} + run: pnpm stage-release + - name: Ensure README.md contains only ASCII and certain Unicode code points run: ./scripts/asciicheck.py README.md - name: Check README ToC diff --git a/README.md b/README.md index cd447051..5053a6fb 100644 --- a/README.md +++ b/README.md @@ -308,6 +308,9 @@ corepack enable pnpm install pnpm build +# Linux-only: download prebuilt sandboxing binaries (requires gh and zstd). +./scripts/install_native_deps.sh + # Get the usage and the options node ./dist/cli.js --help @@ -633,18 +636,25 @@ The **DCO check** blocks merges until every commit in the PR carries the footer ### Releasing `codex` -To publish a new version of the CLI, run the release scripts defined in `codex-cli/package.json`: +To publish a new version of the CLI, run the following in the `codex-cli` folder to stage the release in a temporary directory: -1. Open the `codex-cli` directory -2. Make sure you're on a branch like `git checkout -b bump-version` -3. Bump the version and `CLI_VERSION` to current datetime: `pnpm release:version` -4. Commit the version bump (with DCO sign-off): - ```bash - git add codex-cli/package.json - git commit -s -m "chore(release): codex-cli v$(node -p \"require('./codex-cli/package.json').version\")" - ``` -5. Copy README, build, and publish to npm: `pnpm release` -6. Push to branch: `git push origin HEAD` +``` +pnpm stage-release +``` + +Note you can specify the folder for the staged release: + +``` +RELEASE_DIR=$(mktemp -d) +pnpm stage-release "$RELEASE_DIR" +``` + +Go to the folder where the release is staged and verify that it works as intended. If so, run the following from the temp folder: + +``` +cd "$RELEASE_DIR" +npm publish +``` ### Alternative Build Options diff --git a/codex-cli/.gitignore b/codex-cli/.gitignore new file mode 100644 index 00000000..49a5628d --- /dev/null +++ b/codex-cli/.gitignore @@ -0,0 +1,3 @@ +# Added by ./scripts/install_native_deps.sh +/bin/codex-linux-sandbox-arm64 +/bin/codex-linux-sandbox-x64 diff --git a/codex-cli/package.json b/codex-cli/package.json index bdf4ac3e..3068373f 100644 --- a/codex-cli/package.json +++ b/codex-cli/package.json @@ -20,10 +20,7 @@ "typecheck": "tsc --noEmit", "build": "node build.mjs", "build:dev": "NODE_ENV=development node build.mjs --dev && NODE_OPTIONS=--enable-source-maps node dist/cli-dev.js", - "release:readme": "cp ../README.md ./README.md", - "release:version": "TS=$(date +%y%m%d%H%M) && sed -E -i'' -e \"s/\\\"0\\.1\\.[0-9]{10}\\\"/\\\"0.1.${TS}\\\"/g\" package.json", - "release:build-and-publish": "pnpm run build && npm publish", - "release": "pnpm run release:readme && pnpm run release:version && pnpm install && pnpm run release:build-and-publish" + "stage-release": "./scripts/stage_release.sh" }, "files": [ "dist" diff --git a/codex-cli/scripts/install_native_deps.sh b/codex-cli/scripts/install_native_deps.sh new file mode 100755 index 00000000..2b2768af --- /dev/null +++ b/codex-cli/scripts/install_native_deps.sh @@ -0,0 +1,61 @@ +#!/bin/bash + +# Copy the Linux sandbox native binaries into the bin/ subfolder of codex-cli/. +# +# Usage: +# ./scripts/install_native_deps.sh [CODEX_CLI_ROOT] +# +# Arguments +# [CODEX_CLI_ROOT] – Optional. If supplied, it should be the codex-cli +# folder that contains the package.json for @openai/codex. +# +# When no argument is given we assume the script is being run directly from a +# development checkout. In that case we install the binaries into the +# repository’s own `bin/` directory so that the CLI can run locally. + +set -euo pipefail + +# ---------------------------------------------------------------------------- +# Determine where the binaries should be installed. +# ---------------------------------------------------------------------------- + +if [[ $# -gt 0 ]]; then + # The caller supplied a release root directory. + CODEX_CLI_ROOT="$1" + BIN_DIR="$CODEX_CLI_ROOT/bin" +else + # No argument; fall back to the repo’s own bin directory. + # Resolve the path of this script, then walk up to the repo root. + SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + CODEX_CLI_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" + BIN_DIR="$CODEX_CLI_ROOT/bin" +fi + +# Make sure the destination directory exists. +mkdir -p "$BIN_DIR" + +# ---------------------------------------------------------------------------- +# Download and decompress the artifacts from the GitHub Actions workflow. +# ---------------------------------------------------------------------------- + +# Until we start publishing stable GitHub releases, we have to grab the binaries +# from the GitHub Action that created them. Update the URL below to point to the +# appropriate workflow run: +WORKFLOW_URL="https://github.com/openai/codex/actions/runs/14763725716" +WORKFLOW_ID="${WORKFLOW_URL##*/}" + +ARTIFACTS_DIR="$(mktemp -d)" +trap 'rm -rf "$ARTIFACTS_DIR"' EXIT + +# NB: The GitHub CLI `gh` must be installed and authenticated. +gh run download --dir "$ARTIFACTS_DIR" --repo openai/codex "$WORKFLOW_ID" + +# Decompress the two target architectures. +zstd -d "$ARTIFACTS_DIR/x86_64-unknown-linux-musl/codex-linux-sandbox-x86_64-unknown-linux-musl.zst" \ + -o "$BIN_DIR/codex-linux-sandbox-x64" + +zstd -d "$ARTIFACTS_DIR/aarch64-unknown-linux-gnu/codex-linux-sandbox-aarch64-unknown-linux-gnu.zst" \ + -o "$BIN_DIR/codex-linux-sandbox-arm64" + +echo "Installed native dependencies into $BIN_DIR" + diff --git a/codex-cli/scripts/stage_release.sh b/codex-cli/scripts/stage_release.sh new file mode 100755 index 00000000..e92b1131 --- /dev/null +++ b/codex-cli/scripts/stage_release.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +set -euo pipefail + +# Change to the codex-cli directory. +cd "$(dirname "${BASH_SOURCE[0]}")/.." + +# First argument is where to stage the release. Creates a temporary directory +# if not provided. +RELEASE_DIR="${1:-$(mktemp -d)}" +[ -n "${1-}" ] && shift + +# Compile the JavaScript. +pnpm install +pnpm build +mkdir "$RELEASE_DIR/bin" +cp -r bin/codex.js "$RELEASE_DIR/bin/codex.js" +cp -r dist "$RELEASE_DIR/dist" +cp -r src "$RELEASE_DIR/src" # important if we want sourcemaps to continue to work +cp ../README.md "$RELEASE_DIR" +# TODO: Derive version from Git tag. +VERSION=$(printf '0.1.%d' "$(date +%y%m%d%H%M)") +jq --arg version "$VERSION" '.version = $version' package.json > "$RELEASE_DIR/package.json" + +# Copy the native dependencies. +./scripts/install_native_deps.sh "$RELEASE_DIR" + +echo "Staged version $VERSION for release in $RELEASE_DIR"