From 1c37a0d71d921d13f05340ff6727255ba6074152 Mon Sep 17 00:00:00 2001 From: Samuel Lijin Date: Fri, 11 Oct 2024 16:30:50 -0700 Subject: [PATCH] feat: allow installing the TS library on node-alpine (#1029) > [!IMPORTANT] > Modularizes TypeScript build process with a reusable GitHub Actions workflow and updates Cargo and Node.js configurations for musl support. > > - **GitHub Actions**: > - Adds `build-typescript-release.reusable.yaml` for TypeScript builds supporting targets like `x86_64-unknown-linux-gnu` and `x86_64-unknown-linux-musl`. > - Updates `release.yml` to use the new reusable workflow for TypeScript builds. > - **Cargo Configuration**: > - Updates `Cargo.toml` to specify linkers for `x86_64-unknown-linux-musl` and `aarch64-unknown-linux-musl` targets. > - **Misc**: > - Updates Node.js version in `.mise.toml` to `20.14`. > - Adds `setup-cross-compile-env.sh` script for setting up cross-compilation environment in Docker. > > This description was created by [Ellipsis](https://www.ellipsis.dev?ref=BoundaryML%2Fbaml&utm_source=github&utm_medium=referral) for aa507546ebdbb67aec73bfc737c447bb595a8c49. It will automatically update as commits are pushed. --- .../build-typescript-release.reusable.yaml | 123 ++++++++++++++++++ .github/workflows/release.yml | 117 +---------------- .mise.toml | 2 +- engine/language_client_typescript/Cargo.toml | 6 + tools/setup-cross-compile-env.sh | 60 +++++++++ 5 files changed, 193 insertions(+), 115 deletions(-) create mode 100644 .github/workflows/build-typescript-release.reusable.yaml create mode 100755 tools/setup-cross-compile-env.sh diff --git a/.github/workflows/build-typescript-release.reusable.yaml b/.github/workflows/build-typescript-release.reusable.yaml new file mode 100644 index 000000000..323c28f29 --- /dev/null +++ b/.github/workflows/build-typescript-release.reusable.yaml @@ -0,0 +1,123 @@ +name: Release language_client_typescript + +on: + workflow_call: {} + push: + branches: [sam/alpine-builds] + +concurrency: + # suffix is important to prevent a concurrency deadlock with the calling workflow + group: ${{ github.workflow }}-${{ github.ref }}-build-typescript + cancel-in-progress: true + +env: + DEBUG: napi:* + APP_NAME: baml + MACOSX_DEPLOYMENT_TARGET: "10.13" + +jobs: + build: + strategy: + fail-fast: false + matrix: + _: + - target: aarch64-apple-darwin + host: macos-14 + node_build: pnpm build:napi-release --target aarch64-apple-darwin + + - target: aarch64-unknown-linux-gnu + host: ubuntu-latest + # from https://github.com/PyO3/maturin-action?tab=readme-ov-file#manylinux-docker-container + # need a new version of manylinux to build crates on arm64-linux + container: ghcr.io/rust-cross/manylinux_2_28-cross:aarch64 + node_build: pnpm build:napi-release --target aarch64-unknown-linux-gnu --use-napi-cross + cargo_args: -p baml-typescript-ffi -p baml-python-ffi + + - target: x86_64-apple-darwin + host: macos-latest + node_build: pnpm build:napi-release --target x86_64-apple-darwin + + - target: x86_64-pc-windows-msvc + host: windows-latest + node_build: pnpm build:napi-release --target x86_64-pc-windows-msvc + cargo_args: -p baml-typescript-ffi -p baml-python-ffi + + - target: x86_64-unknown-linux-gnu + host: ubuntu-latest + node_build: pnpm build:napi-release --target x86_64-unknown-linux-gnu --use-napi-cross + + - target: x86_64-unknown-linux-musl + host: ubuntu-latest + before: | + curl -LO https://musl.cc/x86_64-linux-musl-cross.tgz + tar -xzf x86_64-linux-musl-cross.tgz + echo "$PWD/x86_64-linux-musl-cross/bin" >> $GITHUB_PATH + + cat >>$GITHUB_ENV <> $GITHUB_PATH + node_build: pnpm build:napi-release --target aarch64-unknown-linux-musl --use-napi-cross + + name: Build ${{ matrix._.target }} + runs-on: ${{ matrix._.host }} + container: ${{ matrix._.container }} + steps: + - uses: actions/checkout@v4 + + # Install common toolchain dependencies + # NOTE: we can't use mise here because it doesn't support Windows + - uses: pnpm/action-setup@v3 + with: + version: 9.0.6 + run_install: false + - uses: actions/setup-node@v4 + with: + node-version: 20 + cache: pnpm + cache-dependency-path: | + engine/language_client_typescript/pnpm-lock.yaml + - uses: dtolnay/rust-toolchain@stable + with: + toolchain: stable + targets: ${{ matrix._.target }} + + # Set up build cache and dependencies + - uses: Swatinem/rust-cache@v2 + with: + workspaces: engine + shared-key: engine-${{ github.job }}-${{ matrix._.target }} + cache-on-failure: true + + - name: PNPM Install + run: pnpm install --frozen-lockfile + working-directory: engine/language_client_typescript + + # per-matrix-entry dependency setup + - name: Build tools setup + run: ${{ matrix._.before }} + + # Build the NAPI library and bindings + - name: PNPM Build + run: ${{ matrix._.node_build }} + working-directory: engine/language_client_typescript + + - name: Build TS + run: pnpm build:ts_build + working-directory: engine/language_client_typescript + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: bindings-${{ matrix._.target }} + path: engine/language_client_typescript/*.node + if-no-files-found: error \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7f38d2129..663a597a1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -2,6 +2,8 @@ name: BAML Release on: workflow_dispatch: {} + push: + branches: [sam/alpine-builds] # need to run this periodically on the default branch to populate the build cache schedule: # daily at 2am PST @@ -14,13 +16,6 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true -permissions: - contents: write - id-token: write -env: - DEBUG: napi:* - APP_NAME: baml - MACOSX_DEPLOYMENT_TARGET: "10.13" jobs: build-wasm: runs-on: ubuntu-latest @@ -99,114 +94,8 @@ jobs: build-ruby-release: uses: ./.github/workflows/build-ruby-release.reusable.yaml - # NB(sam): we should bring back release_language_client_typescript.yaml and make it another reusable workflow build-typescript-release: - strategy: - fail-fast: false - matrix: - _: - - target: aarch64-apple-darwin - host: macos-14 - node_build: pnpm build:napi-release --target aarch64-apple-darwin - baml_build_help: "off" - # mise: true - - # Disabled as python is not supported on aarch64 windows - # - target: aarch64-pc-windows-msvc - # host: windows-latest - # node_build: pnpm build --target aarch64-pc-windows-msvc - - - target: aarch64-unknown-linux-gnu - host: ubuntu-latest - # from https://github.com/PyO3/maturin-action?tab=readme-ov-file#manylinux-docker-container - # need a new version of manylinux to build crates on arm64-linux - container: ghcr.io/rust-cross/manylinux_2_28-cross:aarch64 - node_build: pnpm build:napi-release --target aarch64-unknown-linux-gnu --use-napi-cross - cargo_args: -p baml-typescript-ffi -p baml-python-ffi - baml_build_help: "off" - - - target: x86_64-apple-darwin - host: macos-latest - node_build: pnpm build:napi-release --target x86_64-apple-darwin - baml_build_help: "off" - # mise: true - - - target: x86_64-pc-windows-msvc - host: windows-latest - node_build: pnpm build:napi-release --target x86_64-pc-windows-msvc - setup-python-architecture: x64 - cargo_args: -p baml-typescript-ffi -p baml-python-ffi - baml_build_help: "off" - - - target: x86_64-unknown-linux-gnu - host: ubuntu-latest - # Using any of the manylinux containers breaks a bunch of stuff: actions/checkout here, pnpm build there - not worth it. - container: null - node_build: pnpm build:napi-release --target x86_64-unknown-linux-gnu --use-napi-cross - mise: true - - name: Build ${{ matrix._.target }} - runs-on: ${{ matrix._.host }} - container: ${{ matrix._.container }} - env: - BAML_BUILD_HELP: ${{ matrix._.baml_build_help }} - steps: - - uses: actions/checkout@v4 - - - uses: jdx/mise-action@v2 - if: ${{ matrix._.mise }} - - - uses: pnpm/action-setup@v3 - with: - version: 9.0.6 - run_install: false - - - uses: actions/setup-node@v4 - with: - node-version: 20 - cache: pnpm - cache-dependency-path: | - engine/language_client_typescript/pnpm-lock.yaml - - # Install rust - - uses: dtolnay/rust-toolchain@stable - with: - toolchain: stable - targets: ${{ matrix._.target }} - - # Install steps - - name: PNPM Install - run: pnpm install --frozen-lockfile - working-directory: engine/language_client_typescript - - # Rust caching - - uses: Swatinem/rust-cache@v2 - with: - workspaces: engine - shared-key: engine-${{ github.job }}-${{ matrix._.target }} - cache-on-failure: true - - - name: Build Rust - run: cargo build --release --target ${{ matrix._.target }} ${{ matrix._.cargo_args }} - working-directory: engine - - # Build NAPI release - - name: PNPM Build - run: ${{ matrix._.node_build }} - working-directory: engine/language_client_typescript - - # Build TS wrapper code and helpers as well - - name: Build TS - run: pnpm build:ts_build - working-directory: engine/language_client_typescript - - - - name: Upload artifact - uses: actions/upload-artifact@v4 - with: - name: bindings-${{ matrix._.target }} - path: engine/language_client_typescript/*.node - if-no-files-found: error + uses: ./.github/workflows/build-typescript-release.reusable.yaml # placeholder fan-in step assert-all-builds-passed: diff --git a/.mise.toml b/.mise.toml index e6bef5067..5fcb9cda1 100644 --- a/.mise.toml +++ b/.mise.toml @@ -1,4 +1,4 @@ [tools] -node = "latest" +node = "20.14" ruby = "3.1" pnpm = "9.9" diff --git a/engine/language_client_typescript/Cargo.toml b/engine/language_client_typescript/Cargo.toml index 3281d96c7..b8288e44e 100644 --- a/engine/language_client_typescript/Cargo.toml +++ b/engine/language_client_typescript/Cargo.toml @@ -7,6 +7,12 @@ version = "0.0.1" name = "baml" crate-type = ["cdylib"] +[target.x86_64-unknown-linux-musl] +linker = "x86_64-linux-musl-gcc" + +[target.aarch64-unknown-linux-musl] +linker = "aarch64-linux-musl-gcc" + [dependencies] anyhow.workspace = true baml-types = { path = "../baml-lib/baml-types" } diff --git a/tools/setup-cross-compile-env.sh b/tools/setup-cross-compile-env.sh new file mode 100755 index 000000000..ae15235c4 --- /dev/null +++ b/tools/setup-cross-compile-env.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env sh + +set -euxo pipefail + +cat <~/.bashrc <<'EOF' +eval "$(~/.local/bin/mise activate bash)" +. ~/.cargo/env +export PS1="[mise][rust] $PS1" +EOF + +echo "Starting bash shell - run 'exit' or press Ctrl-D to close session" + +bash \ No newline at end of file