Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 4 additions & 85 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,93 +58,12 @@ jobs:
shell: bash
run: |
set -euo pipefail
package_dir="dist/release/package"
rm -rf "$package_dir"
mkdir -p "$package_dir"

if [[ "${{ matrix.platform }}" == "linux" ]]; then
cp dist/sea/ai "$package_dir/.ai-real"
chmod 755 "$package_dir/.ai-real"
mkdir -p "$package_dir/.ai-lib"

for lib_name in libatomic.so.1 libstdc++.so.6 libgcc_s.so.1; do
lib_path="$(ldconfig -p | awk -v lib="$lib_name" '$1 == lib { print $NF; exit }')"
if [[ -z "$lib_path" ]]; then
echo "Could not find $lib_name for Linux release packaging" >&2
exit 1
fi
cp -L "$lib_path" "$package_dir/.ai-lib/$lib_name"
done

case "${{ matrix.arch }}" in
x64)
interpreter_candidates=(/lib64/ld-linux-x86-64.so.2 /lib/ld-linux-x86-64.so.2)
;;
arm64)
interpreter_candidates=(/lib/ld-linux-aarch64.so.1 /lib64/ld-linux-aarch64.so.1)
;;
*)
echo "Unsupported Linux release arch: ${{ matrix.arch }}" >&2
exit 1
;;
esac

cat > "$package_dir/ai" <<EOF
#!/bin/sh
set -eu

case "\$0" in
*/*) self="\$0" ;;
*) self="\$(command -v "\$0" 2>/dev/null || printf '%s' "\$0")" ;;
esac

dir="\$(CDPATH= cd -- "\$(dirname -- "\$self")" && pwd -P)"
real="\$dir/.ai-real"
libdir="\$dir/.ai-lib"

# Normal Linux distributions provide the requested ELF interpreter under /lib
# or /lib64. The bundled GCC runtime libraries cover hosts that do not install
# libatomic/libstdc++ by default.
for interpreter in ${interpreter_candidates[*]}; do
if [ -e "\$interpreter" ]; then
export LD_LIBRARY_PATH="\$libdir\${LD_LIBRARY_PATH:+:\$LD_LIBRARY_PATH}"
exec "\$real" "\$@"
fi
done

# NixOS intentionally does not provide /lib*/ld-linux. If Nix is available,
# invoke the release binary through Nixpkgs' dynamic linker instead.
if command -v nix >/dev/null 2>&1; then
nix_linker="\$(nix --extra-experimental-features 'nix-command flakes' eval --raw nixpkgs#stdenv.cc.bintools.dynamicLinker 2>/dev/null || true)"
if [ -n "\$nix_linker" ] && [ -x "\$nix_linker" ]; then
nix_glibc_lib="\${nix_linker%/*}"
exec "\$nix_linker" --library-path "\$libdir:\$nix_glibc_lib" "\$real" "\$@"
fi
fi

export LD_LIBRARY_PATH="\$libdir\${LD_LIBRARY_PATH:+:\$LD_LIBRARY_PATH}"
exec "\$real" "\$@"
EOF
chmod 755 "$package_dir/ai"
else
cp dist/sea/ai "$package_dir/ai"
chmod 755 "$package_dir/ai"
fi

tar -czf "dist/release/${{ matrix.asset_name }}.tar.gz" -C "$package_dir" .
mkdir -p dist/release/package
cp dist/sea/ai dist/release/package/ai
chmod 755 dist/release/package/ai
tar -czf "dist/release/${{ matrix.asset_name }}.tar.gz" -C dist/release/package ai
(cd dist/release && shasum -a 256 "${{ matrix.asset_name }}.tar.gz" > "${{ matrix.asset_name }}.tar.gz.sha256")

- name: Smoke test release asset
shell: bash
run: |
set -euo pipefail
expected_version="$(node -p "require('./package.json').version")"
test_dir="$(mktemp -d)"
tar -xzf "dist/release/${{ matrix.asset_name }}.tar.gz" -C "$test_dir"
actual_version="$($test_dir/ai --version)"
test "$actual_version" = "$expected_version"
"$test_dir/ai" shell init bash --name ai >/dev/null

- name: Upload release asset
if: github.event_name == 'release'
uses: softprops/action-gh-release@v2
Expand Down
10 changes: 0 additions & 10 deletions docs/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,6 @@ Install a specific release:
curl -fsSL https://raw.githubusercontent.com/b4fun/ai/main/install.sh | sh -s -- v0.1.2
```

Linux release archives include the `ai` launcher plus hidden runtime payload
files used to make the prebuilt binary work on hosts that do not provide every
Node/GCC runtime library by default. Prefer `install.sh` or copy the entire
extracted archive contents together; copying only the hidden `.ai-real` binary
can fail with missing libraries such as `libatomic.so.1`.

On NixOS, the Linux launcher falls back to Nixpkgs' dynamic linker when the
usual `/lib*/ld-linux*` path is absent. If you manage `ai` declaratively, prefer
a Nix/Home Manager package so upgrades are pinned and reproducible.

Customize the shell wrapper name:

```bash
Expand Down
24 changes: 0 additions & 24 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,9 @@ else
echo "No sha256 digest found; skipping digest verification" >&2
fi

tmp_package_dir=""
case "$download_path" in
*.tar.gz)
tar -xzf "$download_path" -C "$TMP_DIR"
tmp_package_dir="$TMP_DIR"
tmp_bin="$TMP_DIR/ai"
;;
*)
Expand All @@ -105,28 +103,6 @@ case "$download_path" in
esac

chmod 755 "$tmp_bin"

# Linux release archives may include hidden runtime payload files next to the
# public `ai` launcher. Install those first so the final launcher rename is the
# only visible switch to the new version.
if [ -n "$tmp_package_dir" ] && [ -f "$tmp_package_dir/.ai-real" ]; then
tmp_real_path="$INSTALL_DIR/.ai-real.tmp.$$"
rm -f "$tmp_real_path"
cp "$tmp_package_dir/.ai-real" "$tmp_real_path"
chmod 755 "$tmp_real_path"
rm -f "$INSTALL_DIR/.ai-real"
mv "$tmp_real_path" "$INSTALL_DIR/.ai-real"
fi

if [ -n "$tmp_package_dir" ] && [ -d "$tmp_package_dir/.ai-lib" ]; then
tmp_lib_path="$INSTALL_DIR/.ai-lib.tmp.$$"
rm -rf "$tmp_lib_path"
mkdir -p "$tmp_lib_path"
cp -R "$tmp_package_dir/.ai-lib/." "$tmp_lib_path/"
rm -rf "$INSTALL_DIR/.ai-lib"
mv "$tmp_lib_path" "$INSTALL_DIR/.ai-lib"
fi

# Replace the executable with a fresh inode instead of overwriting in place.
# On macOS, in-place replacement of an ad-hoc signed SEA binary can leave stale
# assessment/provenance state behind and cause the upgraded binary to be killed
Expand Down
Loading