Skip to content

Tailor CI for Tuwunel. #3

Tailor CI for Tuwunel.

Tailor CI for Tuwunel. #3

Workflow file for this run

name: Coroutines build
on:
push:
branches:
- "**"
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
env:
CARGO_TERM_COLOR: always
jobs:
build-and-test:
name: ${{ matrix.build }} (coroutines)
strategy:
fail-fast: false
max-parallel: 2
matrix:
build: [Linux-x64, Linux-ARM]
include:
- build: Linux-x64
os: ubuntu-24.04
- build: Linux-ARM
os: ubuntu-24.04-arm
# The host runner just hosts the container; the actual build happens
# inside `ubuntu:26.04` (see `container:` below). We pin a specific host
# image rather than using `ubuntu-latest` so a GHA runner image rollover
# doesn't silently change anything visible to the build. The container
# image is multi-arch on Docker Hub, so the same `image:` works for
# both x86_64 and aarch64 hosts.
runs-on: ${{ matrix.os }}
container:
# The pinned folly commit (see librocksdb-sys/rocksdb/folly.mk) requires
# liburing >= 2.15 for the io_uring_zcrx_* zero-copy receive APIs used
# in folly/io/async/IoUringZeroCopyBufferPool.cpp. No distro packages
# that yet, so `build_folly.sh` builds it from source into the folly
# scratch dir and the step below puts it on the include and link paths
# for the cargo builds. The image still matters for the toolchain, and
# the cache key below encodes it so changing this invalidates the folly
# cache.
image: ubuntu:26.04
# Folly's getdeps build can take 30-60+ minutes on a cold cache on
# standard GHA runners (small core count, no parallelism flags). 90
# minutes is a comfortable upper bound. With a warm cache the whole
# job finishes in ~15 minutes.
timeout-minutes: 90
steps:
# Containers start minimal. `actions/checkout` needs git + ca-certs and
# the rust toolchain installer needs curl, so install bootstrap tooling
# before any subsequent action runs. Done in a single apt invocation to
# avoid hitting apt-get's lock or paying for two `update`s.
- name: Bootstrap container
run: |
apt-get update
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
ca-certificates curl git sudo
- name: Checkout sources
uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0
with:
persist-credentials: false
submodules: recursive
- name: Install build dependencies
run: |
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
build-essential gcc-14 g++-14 \
cmake ninja-build python3 python3-pip pkg-config patchelf \
wget \
libssl-dev liburing-dev \
zlib1g-dev libbz2-dev autoconf automake libtool \
clang llvm
# Force gcc-14 instead of ubuntu:26.04's default gcc-15. folly's pinned
# libunwind commit (f081cf4...) was written pre-C23 and uses legacy
# K&R-style function declarations (`func()` meaning "unspecified
# arguments"). gcc-15 defaults to `-std=gnu23` for C, where `func()`
# means "no arguments", so calls like `func(s)` in libunwind's tests
# become hard errors. gcc-14 still defaults to `-std=gnu17`, which
# preserves the legacy semantic.
#
# gcc-14 and gcc-15 share the same libstdc++ ABI, so the subsequent
# `cargo build` (which uses gcc-14 here too via cc/c++ alternatives)
# links cleanly against folly's output.
- name: Switch default compiler to gcc-14
run: |
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-14 100
update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-14 100
update-alternatives --install /usr/bin/cc cc /usr/bin/gcc-14 100
update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++-14 100
gcc --version
g++ --version
- name: Install rust
uses: actions-rust-lang/setup-rust-toolchain@166cdcfd11aee3cb47222f9ddb555ce30ddb9659 # v1.17.0
with:
toolchain: stable
cache-key: "v1-rust-coroutines"
cache-bin: false
cache-on-failure: false
cache-save-if: ${{ github.event_name == 'push' && github.ref_name == github.event.repository.default_branch }}
cache-targets: false
# The folly build's correctness depends on three independent inputs:
# 1. The folly commit (pinned by RocksDB's folly.mk:FOLLY_COMMIT_HASH).
# 2. The container release (glibc + libstdc++ + apt package versions).
# 3. The CPU arch (x86_64 vs aarch64).
# All three are encoded in the cache key. The final suffix lets us bump
# the cache manually if the build script changes in a way that
# invalidates prior caches.
- name: Restore folly install
id: cache-folly
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
# Cache only the installed artifacts needed by the cargo build. The
# source checkout, downloads, and intermediate object trees are not
# needed on a warm hit and can exceed the repository cache budget.
path: |
librocksdb-sys/folly-build/installed
librocksdb-sys/folly-build/liburing-2.15
librocksdb-sys/folly-build/liburing-prefix.txt
key: folly-${{ runner.arch }}-u26-${{ hashFiles('scripts/build_folly.sh', 'librocksdb-sys/rocksdb/folly.mk', 'librocksdb-sys/rocksdb/build_tools/getdeps_fallback_mirror.py') }}-v1
- name: Build folly
if: steps.cache-folly.outputs.cache-hit != 'true'
run: ./scripts/build_folly.sh
- name: Export ROCKSDB_FOLLY_INSTALL_PATH and LD_LIBRARY_PATH
run: |
# folly is compiled against the liburing `build_folly.sh` picked,
# which is usually one it built from source because no distro
# packages a new enough release. Put that same copy ahead of the
# system one here so RocksDB's io_uring code and libfolly.a agree
# on the headers and the runtime library. The file is absent when
# the system liburing was already good enough.
append_env() {
printf '%s\n' "$1" >> "$GITHUB_ENV"
}
LIBURING_PREFIX_FILE="$PWD/librocksdb-sys/folly-build/liburing-prefix.txt"
if [ -f "$LIBURING_PREFIX_FILE" ]; then
LIBURING_PREFIX=$(cat "$LIBURING_PREFIX_FILE")
echo "Using liburing from $LIBURING_PREFIX"
append_env "PKG_CONFIG_PATH=$LIBURING_PREFIX/lib/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}"
append_env "CPATH=$LIBURING_PREFIX/include${CPATH:+:$CPATH}"
append_env "LIBRARY_PATH=$LIBURING_PREFIX/lib${LIBRARY_PATH:+:$LIBRARY_PATH}"
fi
INSTALL_ROOT="$PWD/librocksdb-sys/folly-build/installed"
if [ ! -d "$INSTALL_ROOT" ]; then
echo "Error: $INSTALL_ROOT does not exist after cache restore." >&2
echo "Cache may have been corrupted or build_folly.sh failed." >&2
ls -la librocksdb-sys/folly-build/ || true
exit 1
fi
append_env "ROCKSDB_FOLLY_INSTALL_PATH=$INSTALL_ROOT"
# folly's getdeps produces libglog and libgflags as shared libs only
# (no static archives). librocksdb-sys/build.rs links them dynamically.
# `cargo:rustc-link-arg` for rpath would only apply to this crate's
# own test binaries (rust-lang/cargo#9554), not to the rust-rocksdb
# crate's test binaries that nextest actually runs - so set
# LD_LIBRARY_PATH for the rest of the job. This matches the
# "Set LD_LIBRARY_PATH" guidance in the README's runtime constraints
# section.
locate_libdir() {
local dep_dir
dep_dir=$(find "$INSTALL_ROOT" -maxdepth 1 -type d -name "$1-*" \
| head -1)
if [ -z "$dep_dir" ]; then
echo "Error: could not find $1-* under $INSTALL_ROOT" >&2
exit 1
fi
if [ -d "$dep_dir/lib64" ]; then
echo "$dep_dir/lib64"
else
echo "$dep_dir/lib"
fi
}
GLOG_LIBDIR=$(locate_libdir glog)
GFLAGS_LIBDIR=$(locate_libdir gflags)
RUNTIME_LIBDIRS="$GLOG_LIBDIR:$GFLAGS_LIBDIR"
if [ -n "${LIBURING_PREFIX:-}" ]; then
RUNTIME_LIBDIRS="$RUNTIME_LIBDIRS:$LIBURING_PREFIX/lib"
fi
append_env "LD_LIBRARY_PATH=$RUNTIME_LIBDIRS${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
- uses: taiki-e/install-action@68250fb3d551d72befef105162372ebb3e8016e0 # nextest
- name: cargo build --features coroutines,io-uring
run: cargo build --release --features coroutines,io-uring
- name: Run tests with coroutines feature
run: cargo nextest run --release --features coroutines,io-uring
- name: Run doctests with coroutines feature
run: cargo test --doc --release --features coroutines,io-uring
- name: Save folly install
if: >-
steps.cache-folly.outputs.cache-hit != 'true'
&& github.event_name == 'push'
&& github.ref_name == github.event.repository.default_branch
uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: |
librocksdb-sys/folly-build/installed
librocksdb-sys/folly-build/liburing-2.15
librocksdb-sys/folly-build/liburing-prefix.txt
key: folly-${{ runner.arch }}-u26-${{ hashFiles('scripts/build_folly.sh', 'librocksdb-sys/rocksdb/folly.mk', 'librocksdb-sys/rocksdb/build_tools/getdeps_fallback_mirror.py') }}-v1