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
62 changes: 62 additions & 0 deletions .github/scripts/build-v8-archive.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#!/bin/bash
set -euo pipefail

# Build a prebuilt rusty_v8 static library archive for reuse by wheel builds.
#
# Runs inside the manylinux builder containers (.github/docker/Dockerfile.*)
# with the repository mounted at the working directory. Produces the same
# artifact layout as denoland's rusty_v8 releases:
# librusty_v8_release_{target}.a.gz
# src_binding_release_{target}.rs
#
# Usage: ./build-v8-archive.sh TARGET_TRIPLE [OUTPUT_DIR]
# TARGET_TRIPLE: x86_64-unknown-linux-gnu or aarch64-unknown-linux-gnu
# OUTPUT_DIR: dist-v8 (default)

TARGET_ARCH="${1:?Usage: build-v8-archive.sh TARGET_TRIPLE [OUTPUT_DIR]}"
OUTPUT_DIR="${2:-dist-v8}"

V8_VERSION=$(sed -n '/^name = "v8"$/{n;s/^version = "\(.*\)"/\1/p;}' Cargo.lock)
if [ -z "${V8_VERSION}" ]; then
echo "Failed to determine v8 crate version from Cargo.lock" >&2
exit 1
fi

echo "=== Building rusty_v8 v${V8_VERSION} from source for ${TARGET_ARCH} ==="
rustc --version
cargo --version

# The crates.io package is missing files required for from-source builds,
# so patch v8 to the matching git tag.
if ! grep -q "\[patch.crates-io\]" Cargo.toml; then
cat >> Cargo.toml <<EOF

# Patched by build script: use V8 from git (crates.io package lacks files
# needed for from-source builds)
[patch.crates-io]
v8 = { git = "https://github.com/denoland/rusty_v8", tag = "v${V8_VERSION}" }
EOF
echo "Applied V8 git patch (tag v${V8_VERSION}) to Cargo.toml"
fi

export V8_FROM_SOURCE=1

cargo build --release -p v8 --target "${TARGET_ARCH}"

BUILD_DIR="target/${TARGET_ARCH}/release"
STATIC_LIB="${BUILD_DIR}/gn_out/obj/librusty_v8.a"
SRC_BINDING="${BUILD_DIR}/gn_out/src_binding.rs"

for artifact in "${STATIC_LIB}" "${SRC_BINDING}"; do
if [ ! -f "${artifact}" ]; then
echo "Expected build artifact not found: ${artifact}" >&2
exit 1
fi
done

mkdir -p "${OUTPUT_DIR}"
gzip -9c "${STATIC_LIB}" > "${OUTPUT_DIR}/librusty_v8_release_${TARGET_ARCH}.a.gz"
cp "${SRC_BINDING}" "${OUTPUT_DIR}/src_binding_release_${TARGET_ARCH}.rs"

echo "=== Archive artifacts for v${V8_VERSION} (${TARGET_ARCH}) ==="
ls -lh "${OUTPUT_DIR}"
83 changes: 83 additions & 0 deletions .github/workflows/build-v8-archive.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
name: Build V8 archive

# Builds rusty_v8 from source inside the manylinux_2_28 containers and
# publishes the static library + src binding as GitHub release assets.
# The wheel CI consumes these via RUSTY_V8_ARCHIVE/RUSTY_V8_SRC_BINDING_PATH,
# so V8 only needs to be compiled when the v8 crate version in Cargo.lock
# changes (run this workflow manually after such a bump).
#
# Why from source: denoland's prebuilt archives require glibc >= 2.30
# (e.g. pthread_cond_clockwait), but manylinux_2_28 wheels must link
# against glibc 2.28.

on:
workflow_dispatch:

permissions:
contents: write # Required for uploading release assets

jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 360
strategy:
fail-fast: false
matrix:
arch:
- name: x86_64
target: x86_64-unknown-linux-gnu
dockerfile: Dockerfile.x86_64
- name: aarch64
target: aarch64-unknown-linux-gnu
dockerfile: Dockerfile.aarch64
steps:
- uses: actions/checkout@v5

# V8 needs ~25GB; free runners start with ~14GB available.
- name: Free disk space
run: |
sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /opt/hostedtoolcache/CodeQL
sudo docker image prune -af
df -h /

- name: Read v8 version from Cargo.lock
id: v8
run: |
VERSION=$(sed -n '/^name = "v8"$/{n;s/^version = "\(.*\)"/\1/p;}' Cargo.lock)
if [ -z "$VERSION" ]; then
echo "::error::Failed to determine v8 crate version from Cargo.lock"
exit 1
fi
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "Building archive for rusty_v8 v$VERSION"

- name: Build builder image
run: |
docker build \
-t jsrun-v8-builder:${{ matrix.arch.name }} \
-f .github/docker/${{ matrix.arch.dockerfile }} \
.github/docker/

- name: Build V8 from source
run: |
mkdir -p dist-v8
docker run --rm \
-v "$(pwd):/workdir" \
-w /workdir \
jsrun-v8-builder:${{ matrix.arch.name }} \
bash .github/scripts/build-v8-archive.sh ${{ matrix.arch.target }} dist-v8

- name: Upload artifacts to release
env:
GH_TOKEN: ${{ github.token }}
run: |
TAG="librusty_v8-v${{ steps.v8.outputs.version }}"
# Prerelease so archive tags never show up as the "latest" jsrun release.
# The tag deliberately does not match the v* pattern that triggers CI.
gh release view "$TAG" >/dev/null 2>&1 || \
gh release create "$TAG" \
--prerelease \
--title "librusty_v8 v${{ steps.v8.outputs.version }} (manylinux_2_28)" \
--notes "Prebuilt rusty_v8 static libraries compiled inside manylinux_2_28 containers (glibc 2.28 compatible). Consumed by the wheel CI via RUSTY_V8_ARCHIVE." \
|| true
gh release upload "$TAG" dist-v8/* --clobber
Loading
Loading