Skip to content

UniFFI CI improvements (#1244) #1130

UniFFI CI improvements (#1244)

UniFFI CI improvements (#1244) #1130

Workflow file for this run

# Copyright 2023 LiveKit, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
name: FFI
on:
push:
branches: ["main"]
workflow_dispatch:
inputs:
tag_name:
description: "Release tag (e.g. livekit-ffi/v0.12.49). Takes precedence over draft release lookup and creates a draft release."
required: false
type: string
dry_run:
description: "Dry run: build artifacts but skip release upload/publish."
required: false
type: boolean
default: false
build_profile:
description: "Build profile"
type: choice
options:
- release
- debug
default: release
env:
CARGO_TERM_COLOR: always
jobs:
get-tag:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- name: "Resolve tag"
run: |
MANUAL_TAG="${{ inputs.tag_name }}"
if [ -n "$MANUAL_TAG" ]; then
echo "Using manually provided tag: '${MANUAL_TAG}'"
gh release create "$MANUAL_TAG" --draft --title "$MANUAL_TAG" --generate-notes
echo "tag_name=${MANUAL_TAG}" >> $GITHUB_OUTPUT
else
TAG=$(gh release list --repo ${{ github.repository }} --json 'isDraft,tagName' --jq '[.[] | select(.isDraft and (.tagName | startswith("livekit-ffi/")))] | first | .tagName // empty')
echo "Resolved FFI draft release tag: '${TAG:-}'"
echo "tag_name=${TAG:-}" >> $GITHUB_OUTPUT
fi
env:
GH_TOKEN: ${{ github.token }}
id: get-tag
outputs:
tag_name: ${{ steps.get-tag.outputs.tag_name }}
build:
env:
CARGO_PROFILE_DIR: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.build_profile == 'debug' && 'debug' || 'release' }}
CARGO_RUST_PROFILE: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.build_profile == 'debug' && 'dev' || 'release' }}
strategy:
fail-fast: false
matrix:
include:
- os: windows-latest
platform: windows
dylib: livekit_ffi.dll
target: x86_64-pc-windows-msvc
name: ffi-windows-x86_64
- os: windows-latest
platform: windows
dylib: livekit_ffi.dll
buildargs: --no-default-features --features "native-tls" # ring 0.16 is incompatible with win aarch64
target: aarch64-pc-windows-msvc
name: ffi-windows-arm64
- os: macos-latest
platform: macos
dylib: liblivekit_ffi.dylib
target: x86_64-apple-darwin
macosx_deployment_target: "10.15"
name: ffi-macos-x86_64
- os: macos-latest
platform: macos
dylib: liblivekit_ffi.dylib
target: aarch64-apple-darwin
macosx_deployment_target: "11.0" # aarch64 requires 11
name: ffi-macos-arm64
- os: macos-latest
platform: ios
dylib: liblivekit_ffi.a
target: aarch64-apple-ios
iphoneos_deployment_target: "13.0"
name: ffi-ios-arm64
buildargs: --no-default-features --features "rustls-tls-webpki-roots"
- os: macos-latest
platform: ios
dylib: liblivekit_ffi.a
target: aarch64-apple-ios-sim
iphoneos_deployment_target: "13.0"
name: ffi-ios-sim-arm64
buildargs: --no-default-features --features "rustls-tls-webpki-roots"
- os: ubuntu-latest
platform: linux
build_image: sameli/manylinux_2_28_x86_64_cuda_12.3
dylib: liblivekit_ffi.so
target: x86_64-unknown-linux-gnu
name: ffi-linux-x86_64
- os: ubuntu-24.04-arm
platform: linux
build_image: quay.io/pypa/manylinux_2_28_aarch64
dylib: liblivekit_ffi.so
target: aarch64-unknown-linux-gnu
name: ffi-linux-arm64
- os: ubuntu-latest
platform: android
dylib: liblivekit_ffi.so
jar: libwebrtc.jar
target: aarch64-linux-android
name: ffi-android-arm64
buildargs: --no-default-features --features "rustls-tls-webpki-roots"
- os: ubuntu-latest
platform: android
dylib: liblivekit_ffi.so
jar: libwebrtc.jar
target: armv7-linux-androideabi
name: ffi-android-armv7
buildargs: --no-default-features --features "rustls-tls-webpki-roots"
- os: ubuntu-latest
platform: android
dylib: liblivekit_ffi.so
jar: libwebrtc.jar
target: x86_64-linux-android
name: ffi-android-x86_64
buildargs: --no-default-features --features "rustls-tls-webpki-roots"
name: Build (${{ matrix.target }}${{ github.event_name == 'workflow_dispatch' && format(' [{0}]', github.event.inputs.build_profile) || '' }})
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
with:
submodules: true
- name: Setup Rust toolchain
uses: actions-rust-lang/setup-rust-toolchain@46268bd060767258de96ed93c1251119784f2ab6 # v1.16.1
with:
target: ${{ matrix.target }}
cache: false
rustflags: ""
- name: Cache cargo registry
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: |
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-registry-
- name: Cache cargo target
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: target/
key: ${{ runner.os }}-cargo-target-${{ matrix.target }}-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-target-${{ matrix.target }}-
- name: Install Protoc
uses: arduino/setup-protoc@a8b67ba40b37d35169e222f3bb352603327985b6 # v2.1.0
with:
version: "25.2"
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Set up QEMU
if: ${{ matrix.target == 'aarch64-unknown-linux-gnu' }}
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
- name: Build (macOS)
if: ${{ matrix.platform == 'macos' }}
env:
MACOSX_DEPLOYMENT_TARGET: ${{ matrix.macosx_deployment_target }}
run: |
cd livekit-ffi
cargo build --profile "$CARGO_RUST_PROFILE" --target ${{ matrix.target }} ${{ matrix.buildargs }}
- name: Build (iOS)
if: ${{ matrix.platform == 'ios' }}
# TODO(theomonnom): Seems like this is causing issues with the linker (let’s ignore for now)
#env:
# IPHONEOS_DEPLOYMENT_TARGET: ${{ matrix.iphoneos_deployment_target }}
# run: cd livekit-ffi && cargo build --release --target ${{ matrix.target }} ${{ matrix.buildargs }}
run: |
cd livekit-ffi
cargo rustc --crate-type staticlib --profile "$CARGO_RUST_PROFILE" --target ${{ matrix.target }} ${{ matrix.buildargs }}
- name: Build (Windows)
if: ${{ matrix.platform == 'windows' }}
run: |
cd livekit-ffi
cargo build --profile $env:CARGO_RUST_PROFILE --target ${{ matrix.target }} ${{ matrix.buildargs }}
# Use Docker on linux, so we can use manylinux images (ensure maximum mcompatibility)
- name: Build (Linux)
if: ${{ matrix.platform == 'linux' }}
run: |
docker run --rm -e CARGO_RUST_PROFILE="$CARGO_RUST_PROFILE" -v $PWD:/workspace -w /workspace ${{ matrix.build_image }} bash -c "\
uname -a; \
export PATH=/root/.cargo/bin:\$PATH; \
yum install llvm llvm-libs lld -y; \
yum install clang -y; \
yum install protobuf-compiler -y; \
yum groupinstall 'Development Tools' -y; \
clang --version; \
yum install openssl-devel libX11-devel mesa-libGL-devel libXext-devel libva-devel libdrm-devel libgbm-devel libXdamage-devel libXrandr-devel libXfixes-devel libXcomposite-devel -y; \
curl --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y; \
cd livekit-ffi && cargo build --profile \"\$CARGO_RUST_PROFILE\" --target ${{ matrix.target }} ${{ matrix.buildargs }}"
sudo chown -R $USER:$USER "target/${{ matrix.target }}/$CARGO_PROFILE_DIR/"
# on android use cargo ndk
- name: Build (Android)
if: ${{ matrix.platform == 'android' }}
run: |
cd livekit-ffi/
cargo install cargo-ndk
cargo ndk --target ${{ matrix.target }} build --profile "$CARGO_RUST_PROFILE" ${{ matrix.buildargs }}
- name: Copy/Build licenses
run: |
echo "# livekit" > TEMP_LICENSE.md
echo "```" >> TEMP_LICENSE.md
cat LICENSE >> TEMP_LICENSE.md
echo "```" >> TEMP_LICENSE.md
cat livekit-ffi/WEBRTC_LICENSE.md >> TEMP_LICENSE.md
mv TEMP_LICENSE.md "target/${{ matrix.target }}/$CARGO_PROFILE_DIR/LICENSE.md"
shell: bash
# zip the files
- name: Zip artifact (Unix)
if: ${{ matrix.os != 'windows-latest' && matrix.platform != 'android'}}
run: |
cp livekit-ffi/include/livekit_ffi.h "target/${{ matrix.target }}/$CARGO_PROFILE_DIR/"
cd "target/${{ matrix.target }}/$CARGO_PROFILE_DIR/"
zip ${{ github.workspace }}/${{ matrix.name }}.zip ${{ matrix.dylib }} livekit_ffi.h LICENSE.md
- name: Zip artifact (Unix for Android)
if: ${{ matrix.os != 'windows-latest' && matrix.platform == 'android'}}
run: |
cp livekit-ffi/include/livekit_ffi.h "target/${{ matrix.target }}/$CARGO_PROFILE_DIR/"
cd "target/${{ matrix.target }}/$CARGO_PROFILE_DIR/"
zip ${{ github.workspace }}/${{ matrix.name }}.zip ${{ matrix.dylib }} ${{ matrix.jar }} livekit_ffi.h LICENSE.md
- name: Zip artifact (Windows)
if: ${{ matrix.os == 'windows-latest' }}
run: |
cp livekit-ffi/include/livekit_ffi.h "target/${{ matrix.target }}/$env:CARGO_PROFILE_DIR/"
cd "target/${{ matrix.target }}/$env:CARGO_PROFILE_DIR/"
Get-ChildItem -Path ${{ matrix.dylib }}, livekit_ffi.h, LICENSE.md | Compress-Archive -DestinationPath ${{ github.workspace }}\${{ matrix.name }}.zip
- name: Upload artifacts
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: ffi-builds-${{ matrix.target }}
path: ${{ matrix.name }}.zip
release:
name: Upload artifacts and publish GH release
runs-on: ubuntu-latest
needs: [get-tag, build]
permissions:
contents: write
if: needs.get-tag.outputs.tag_name != '' && inputs.dry_run != true
env:
GH_TOKEN: ${{ github.token }}
steps:
- uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- name: Download artifacts
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
pattern: ffi-builds-*
merge-multiple: true
path: ${{ github.workspace }}/ffi-builds
- name: Upload artifacts and publish release
run: |
gh release upload ${{ needs.get-tag.outputs.tag_name }} ${{ github.workspace }}/ffi-builds/*
gh release edit ${{ needs.get-tag.outputs.tag_name }} --draft=false