Skip to content

Commit 60d533f

Browse files
committed
Add macOS and Linux install script
1 parent 448fb6a commit 60d533f

File tree

2 files changed

+248
-0
lines changed

2 files changed

+248
-0
lines changed

.github/workflows/rust-release.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,10 @@ jobs:
488488
--package codex-responses-api-proxy \
489489
--package codex-sdk
490490
491+
- name: Stage macOS and Linux installer script
492+
run: |
493+
cp scripts/install/install.sh dist/install.sh
494+
491495
- name: Create GitHub Release
492496
uses: softprops/action-gh-release@v2
493497
with:

scripts/install/install.sh

Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
#!/bin/sh
2+
3+
set -eu
4+
5+
VERSION="${1:-latest}"
6+
INSTALL_DIR="${CODEX_INSTALL_DIR:-$HOME/.local/bin}"
7+
path_action="already"
8+
path_profile=""
9+
10+
step() {
11+
printf '==> %s\n' "$1"
12+
}
13+
14+
normalize_version() {
15+
case "$1" in
16+
"" | latest)
17+
printf 'latest\n'
18+
;;
19+
rust-v*)
20+
printf '%s\n' "${1#rust-v}"
21+
;;
22+
v*)
23+
printf '%s\n' "${1#v}"
24+
;;
25+
*)
26+
printf '%s\n' "$1"
27+
;;
28+
esac
29+
}
30+
31+
download_file() {
32+
url="$1"
33+
output="$2"
34+
35+
if command -v curl >/dev/null 2>&1; then
36+
curl -fsSL "$url" -o "$output"
37+
return
38+
fi
39+
40+
if command -v wget >/dev/null 2>&1; then
41+
wget -q -O "$output" "$url"
42+
return
43+
fi
44+
45+
echo "curl or wget is required to install Codex." >&2
46+
exit 1
47+
}
48+
49+
download_text() {
50+
url="$1"
51+
52+
if command -v curl >/dev/null 2>&1; then
53+
curl -fsSL "$url"
54+
return
55+
fi
56+
57+
if command -v wget >/dev/null 2>&1; then
58+
wget -q -O - "$url"
59+
return
60+
fi
61+
62+
echo "curl or wget is required to install Codex." >&2
63+
exit 1
64+
}
65+
66+
add_to_path() {
67+
path_action="already"
68+
path_profile=""
69+
70+
case ":$PATH:" in
71+
*":$INSTALL_DIR:"*)
72+
return
73+
;;
74+
esac
75+
76+
profile="$HOME/.profile"
77+
case "${SHELL:-}" in
78+
*/zsh)
79+
profile="$HOME/.zshrc"
80+
;;
81+
*/bash)
82+
profile="$HOME/.bashrc"
83+
;;
84+
esac
85+
86+
path_profile="$profile"
87+
path_line="export PATH=\"$INSTALL_DIR:\$PATH\""
88+
if [ -f "$profile" ] && grep -F "$path_line" "$profile" >/dev/null 2>&1; then
89+
path_action="configured"
90+
return
91+
fi
92+
93+
{
94+
printf '\n# Added by Codex installer\n'
95+
printf '%s\n' "$path_line"
96+
} >>"$profile"
97+
path_action="added"
98+
}
99+
100+
release_url_for_asset() {
101+
asset="$1"
102+
resolved_version="$2"
103+
104+
printf 'https://github.com/openai/codex/releases/download/rust-v%s/%s\n' "$resolved_version" "$asset"
105+
}
106+
107+
require_command() {
108+
if ! command -v "$1" >/dev/null 2>&1; then
109+
echo "$1 is required to install Codex." >&2
110+
exit 1
111+
fi
112+
}
113+
114+
require_command mktemp
115+
require_command tar
116+
117+
resolve_version() {
118+
normalized_version="$(normalize_version "$VERSION")"
119+
120+
if [ "$normalized_version" != "latest" ]; then
121+
printf '%s\n' "$normalized_version"
122+
return
123+
fi
124+
125+
release_json="$(download_text "https://api.github.com/repos/openai/codex/releases/latest")"
126+
resolved="$(printf '%s\n' "$release_json" | sed -n 's/.*"tag_name":[[:space:]]*"rust-v\([^"]*\)".*/\1/p' | head -n 1)"
127+
128+
if [ -z "$resolved" ]; then
129+
echo "Failed to resolve the latest Codex release version." >&2
130+
exit 1
131+
fi
132+
133+
printf '%s\n' "$resolved"
134+
}
135+
136+
case "$(uname -s)" in
137+
Darwin)
138+
os="darwin"
139+
;;
140+
Linux)
141+
os="linux"
142+
;;
143+
*)
144+
echo "install.sh supports macOS and Linux. Use install.ps1 on Windows." >&2
145+
exit 1
146+
;;
147+
esac
148+
149+
case "$(uname -m)" in
150+
x86_64 | amd64)
151+
arch="x86_64"
152+
;;
153+
arm64 | aarch64)
154+
arch="aarch64"
155+
;;
156+
*)
157+
echo "Unsupported architecture: $(uname -m)" >&2
158+
exit 1
159+
;;
160+
esac
161+
162+
if [ "$os" = "darwin" ] && [ "$arch" = "x86_64" ]; then
163+
if [ "$(sysctl -n sysctl.proc_translated 2>/dev/null || true)" = "1" ]; then
164+
arch="aarch64"
165+
fi
166+
fi
167+
168+
if [ "$os" = "darwin" ]; then
169+
if [ "$arch" = "aarch64" ]; then
170+
npm_tag="darwin-arm64"
171+
vendor_target="aarch64-apple-darwin"
172+
platform_label="macOS (Apple Silicon)"
173+
else
174+
npm_tag="darwin-x64"
175+
vendor_target="x86_64-apple-darwin"
176+
platform_label="macOS (Intel)"
177+
fi
178+
else
179+
if [ "$arch" = "aarch64" ]; then
180+
npm_tag="linux-arm64"
181+
vendor_target="aarch64-unknown-linux-musl"
182+
platform_label="Linux (ARM64)"
183+
else
184+
npm_tag="linux-x64"
185+
vendor_target="x86_64-unknown-linux-musl"
186+
platform_label="Linux (x64)"
187+
fi
188+
fi
189+
190+
if [ -x "$INSTALL_DIR/codex" ]; then
191+
install_mode="Updating"
192+
else
193+
install_mode="Installing"
194+
fi
195+
196+
step "$install_mode Codex CLI"
197+
step "Detected platform: $platform_label"
198+
199+
resolved_version="$(resolve_version)"
200+
asset="codex-npm-$npm_tag-$resolved_version.tgz"
201+
download_url="$(release_url_for_asset "$asset" "$resolved_version")"
202+
203+
step "Resolved version: $resolved_version"
204+
205+
tmp_dir="$(mktemp -d)"
206+
cleanup() {
207+
rm -rf "$tmp_dir"
208+
}
209+
trap cleanup EXIT INT TERM
210+
211+
archive_path="$tmp_dir/$asset"
212+
213+
step "Downloading Codex CLI"
214+
download_file "$download_url" "$archive_path"
215+
216+
tar -xzf "$archive_path" -C "$tmp_dir"
217+
218+
step "Installing to $INSTALL_DIR"
219+
mkdir -p "$INSTALL_DIR"
220+
cp "$tmp_dir/package/vendor/$vendor_target/codex/codex" "$INSTALL_DIR/codex"
221+
cp "$tmp_dir/package/vendor/$vendor_target/path/rg" "$INSTALL_DIR/rg"
222+
chmod 0755 "$INSTALL_DIR/codex"
223+
chmod 0755 "$INSTALL_DIR/rg"
224+
225+
add_to_path
226+
227+
case "$path_action" in
228+
added)
229+
step "PATH updated for future shells in $path_profile"
230+
step "Run now: export PATH=\"$INSTALL_DIR:\$PATH\" && codex"
231+
step "Or open a new terminal and run: codex"
232+
;;
233+
configured)
234+
step "PATH is already configured for future shells in $path_profile"
235+
step "Run now: export PATH=\"$INSTALL_DIR:\$PATH\" && codex"
236+
step "Or open a new terminal and run: codex"
237+
;;
238+
*)
239+
step "$INSTALL_DIR is already on PATH"
240+
step "Run: codex"
241+
;;
242+
esac
243+
244+
printf 'Codex CLI %s installed successfully.\n' "$resolved_version"

0 commit comments

Comments
 (0)