* test(storage): add crash-replay and handle-failure coverage for ReferenceCounter Adds 6 test cases: - Recovery after forced close preserves committed data - Uncommitted transaction rolled back after forced close - Corrupted database file rejected on open - Consistent stats after interrupted commit recovery - Multiple PENDING transactions survive force close - WAL checkpoint survives forced close * fix(ci): remove ccache — conflicts with OpenBLAS ASM as direct compiler * fix(ci): use explicit CC/CXX paths to prevent Conan from using ccache directly ccache was picked up by Conan/CMake as the compiler itself (/usr/bin/ccache) rather than as a transparent wrapper, causing OpenBLAS ASM compilation to fail with 'ccache: invalid option -- D'. Setting explicit compiler paths prevents this. * fix(ci): add YAMS_SKIP_CCACHE to avoid OpenBLAS ASM ccache conflict setup.sh wraps CC/CXX with ccache for faster incremental builds, but this causes Conan/CMake to use ccache directly as the ASM compiler for OpenBLAS, where it fails on -D flags. Add an opt-out gate in setup.sh and set YAMS_SKIP_CCACHE=1 in .build.yml for sourcehut CI VMs. * fix(ci): add libomp-dev, libfaiss-dev, libopenblas-dev for FAISS build * fix(ci): limit meson compile to -j1 to prevent OOM on sourcehut VMs * fix(build): restore hooks and shrink srht Compile the storage library with YAMS_TESTING in test builds so debug-only hooks link again. Include the POSIX chmod header used by the storage utility Catch2 coverage cases. Prune SourceHut fallback stage archives to runtime files so branch artifacts stay under the upload limit. * refactor(storage): drop dead code, add coverage * refactor(cli): polish grep/search graph UX * fix(daemon): stabilize shutdown and CI paths - force vector-backed tests to opt out of CI-wide disable flags - reset reference prune statements between deletes - make optional-plugin and POSIX-only test assumptions portable - extract ServiceManager open/shutdown helpers for safer WAL recovery work * test(daemon): add db vacuum coverage * test(daemon): add WAL startup recovery - cover stale WAL startup recovery in ServiceManager - cover repeated restart cycles with seeded WAL sidecars - assert daemon recovery reporting for corrupt data-dir DBs - verify oversized metadata DBs shrink after WAL recovery shutdown * refactor(grep): consolidate indexed content scan * fix(grep): remove pre-scan candidate truncation * refactor(runtime): split startup, harden storage * feat(bench): add manifest retrieval corpus * fix(bench): run fusion experiment on simeon * fix(cli): sharpen search graph hints * fix(build): refresh version metadata * fix(ci): stabilize sync search and srht packaging * fix(ci): unblock windows and shrink artifacts * fix(ci): stabilize linux runtime checks * fix(build): shrink srht manifest
383 lines
14 KiB
YAML
383 lines
14 KiB
YAML
# .build.yml
|
|
#
|
|
# SourceHut build manifest for YAMS (single Linux target).
|
|
# Key points:
|
|
# - Compute version from Git ref (GIT_REF) or release channel (RELEASE_CHANNEL) at runtime; no manifest expressions.
|
|
# - Persist computed version into ~/.buildenv for subsequent tasks.
|
|
# - Add static build tags for search/badges.
|
|
# - Gate packaging steps so they run for tag builds and for nightly/weekly channels.
|
|
# - Install Conan via pipx (or venv fallback), since Debian doesn't provide python3-conan.
|
|
|
|
image: debian/trixie
|
|
|
|
secrets:
|
|
- 46f739e5-4538-45dd-a79f-bf173b7a2ed9
|
|
|
|
sources:
|
|
- https://git.sr.ht/~trevon/yams
|
|
|
|
# Static metadata for search and badges (unrelated to Git tags)
|
|
tags:
|
|
- linux
|
|
- release
|
|
- cmake
|
|
- conan
|
|
- yams
|
|
- nightly
|
|
- weekly
|
|
|
|
environment:
|
|
# Define consistent directories (setup.sh uses build/release for Release builds).
|
|
BUILD_DIR: build/release
|
|
STAGE_DIR: stage # relative to BUILD_DIR (Meson --destdir uses builddir as base)
|
|
# Optional: set this to "nightly" or "weekly" via scheduler/env to produce
|
|
# date/week-based releases on non-tag builds.
|
|
# RELEASE_CHANNEL:
|
|
|
|
packages:
|
|
# Build dependencies (Debian/apt)
|
|
- build-essential # gcc, make, etc.
|
|
- cmake
|
|
- meson
|
|
- ninja-build
|
|
- zip
|
|
- ccache
|
|
- dpkg-dev
|
|
- fakeroot
|
|
- rpm
|
|
- lld
|
|
- clang
|
|
- llvm
|
|
- python3
|
|
- python3-pip
|
|
- python3-venv
|
|
- pipx
|
|
- git
|
|
- libncurses-dev
|
|
- libtinfo-dev
|
|
- pkg-config
|
|
- libboost-all-dev
|
|
- liburing-dev # enables io_uring async path instead of fallback
|
|
- libomp-dev # OpenMP runtime for FAISS parallel compute
|
|
- libfaiss-dev # FAISS vector similarity library
|
|
- libopenblas-dev # optimized BLAS for FAISS/vector math
|
|
- libarchive-dev # enables archive extraction features
|
|
- libacl1-dev # required for libarchive ACL support
|
|
- libtag1-dev # enables taglib (audio metadata) detection
|
|
- libsqlite3-dev # enables SQLite database support
|
|
- libssl-dev
|
|
- libcurl4-gnutls-dev # use gnutls variant; required by libmediainfo-dev (conflicts with openssl variant)
|
|
- libsqlite3-dev
|
|
- libncurses-dev
|
|
- protobuf-compiler
|
|
- libprotobuf-dev
|
|
- libmediainfo-dev # enables MediaInfo-based video metadata extraction
|
|
- mediainfo # MediaInfo CLI tool used at runtime for JSON output
|
|
- xz-utils # for extracting Zig tarball
|
|
|
|
tasks:
|
|
# Determine version from the Git ref and persist to ~/.buildenv for later tasks.
|
|
- compute_version: |
|
|
set -e
|
|
# Detect repository root (sr.ht often checks out into ./yams). Support Meson or CMake projects.
|
|
if [ -d yams ] && { [ -f yams/meson.build ] || [ -f yams/CMakeLists.txt ]; }; then
|
|
REPO_DIR="yams"
|
|
else
|
|
REPO_DIR="."
|
|
fi
|
|
cd "${REPO_DIR}"
|
|
|
|
CHANNEL="${RELEASE_CHANNEL:-}"
|
|
# Auto-channelize main branch builds as nightly when not tagged
|
|
if [[ -z "${CHANNEL}" && "${GIT_REF:-}" == "refs/heads/main" ]]; then
|
|
CHANNEL="nightly"
|
|
export RELEASE_CHANNEL="nightly"
|
|
# Persist for subsequent tasks which may source this
|
|
echo "RELEASE_CHANNEL=nightly" >> ~/.buildenv
|
|
fi
|
|
|
|
# Determine numeric base version from latest tag (strip leading v), fallback to 0.0.0
|
|
RAW_TAG_NUMERIC="$(git describe --tags --abbrev=0 2>/dev/null || echo 0.0.0)"
|
|
BASE_NUMERIC_VERSION="${RAW_TAG_NUMERIC#v}"
|
|
|
|
if [ "$CHANNEL" = "nightly" ]; then
|
|
CLEAN_VERSION_DISPLAY="nightly-$(date -u +%Y%m%d)"
|
|
CLEAN_VERSION_CMAKE="${BASE_NUMERIC_VERSION}"
|
|
elif [ "$CHANNEL" = "weekly" ]; then
|
|
CLEAN_VERSION_DISPLAY="weekly-$(date -u +%G)w$(date -u +%V)"
|
|
CLEAN_VERSION_CMAKE="${BASE_NUMERIC_VERSION}"
|
|
else
|
|
# Prefer tag-triggered builds; otherwise use last tag as numeric
|
|
if [[ "${GIT_REF:-}" =~ ^refs/tags/ ]]; then
|
|
RAW_TAG="${GIT_REF#refs/tags/}"
|
|
CLEAN_VERSION_DISPLAY="${RAW_TAG#v}"
|
|
CLEAN_VERSION_CMAKE="${RAW_TAG#v}"
|
|
else
|
|
CLEAN_VERSION_DISPLAY="${BASE_NUMERIC_VERSION}"
|
|
CLEAN_VERSION_CMAKE="${BASE_NUMERIC_VERSION}"
|
|
fi
|
|
fi
|
|
|
|
# Persist for subsequent tasks
|
|
echo "YAMS_VERSION=${CLEAN_VERSION_DISPLAY}" >> ~/.buildenv
|
|
echo "YAMS_VERSION_CMAKE=${CLEAN_VERSION_CMAKE}" >> ~/.buildenv
|
|
echo "Computed YAMS_VERSION(display)=${CLEAN_VERSION_DISPLAY}, YAMS_VERSION_CMAKE=${CLEAN_VERSION_CMAKE} (GIT_REF=${GIT_REF:-n/a}, RELEASE_CHANNEL=${CHANNEL:-n/a})"
|
|
|
|
- install_zig: |
|
|
set -e
|
|
# Install Zig 0.15.2 stable for zyp PDF plugin
|
|
ARCH=$(uname -m)
|
|
case "$ARCH" in
|
|
x86_64) ZIG_ARCH="x86_64" ;;
|
|
aarch64) ZIG_ARCH="aarch64" ;;
|
|
*) echo "Unsupported architecture: $ARCH"; exit 1 ;;
|
|
esac
|
|
ZIG_VERSION="0.15.2"
|
|
curl -fsSL "https://ziglang.org/download/${ZIG_VERSION}/zig-${ZIG_ARCH}-linux-${ZIG_VERSION}.tar.xz" -o /tmp/zig.tar.xz
|
|
sudo tar -xJf /tmp/zig.tar.xz -C /opt
|
|
sudo mv /opt/zig-${ZIG_ARCH}-linux-${ZIG_VERSION} /opt/zig
|
|
sudo ln -sf /opt/zig/zig /usr/local/bin/zig
|
|
rm /tmp/zig.tar.xz
|
|
zig version
|
|
echo "PATH=/opt/zig:${PATH}" >> ~/.buildenv
|
|
|
|
- setup: |
|
|
set -e
|
|
# Ensure pipx/venv/pip path is prepared
|
|
export PATH="${HOME}/.local/bin:${PATH}"
|
|
|
|
# Configure git identity and signing key (requested)
|
|
git config --global user.name "Trevon" || true
|
|
git config --global user.email "git@trevon.dev" || true
|
|
git config --global user.signingkey "C1E8284DAE319BA313FCB40038686EA797D7A8A7" || true
|
|
# Note: actual signed commits/tags require the private key in the agent; we only set identity here.
|
|
|
|
# Configure ccache (optional acceleration)
|
|
export CCACHE_DIR="${HOME}/.cache/ccache"
|
|
mkdir -p "${CCACHE_DIR}"
|
|
echo "CCACHE_DIR=${CCACHE_DIR}" >> ~/.buildenv
|
|
if command -v ccache >/dev/null 2>&1; then
|
|
ccache --set-config=max_size=2G || true
|
|
ccache --zero-stats || true
|
|
ccache -s || true
|
|
fi
|
|
|
|
# Install Conan via pipx when available; otherwise fallback to user pip or an isolated venv
|
|
if ! command -v conan >/dev/null 2>&1; then
|
|
if command -v pipx >/dev/null 2>&1; then
|
|
pipx install 'conan<3' --pip-args='--upgrade' || true
|
|
fi
|
|
fi
|
|
if ! command -v conan >/dev/null 2>&1; then
|
|
python3 -m pip install --user --upgrade 'conan<3' || true
|
|
hash -r
|
|
fi
|
|
if ! command -v conan >/dev/null 2>&1; then
|
|
python3 -m venv /opt/conan
|
|
. /opt/conan/bin/activate
|
|
python -m pip install --upgrade pip setuptools wheel
|
|
python -m pip install 'conan<3'
|
|
export PATH="/opt/conan/bin:${PATH}"
|
|
hash -r
|
|
fi
|
|
|
|
# Persist Conan PATH and CPU count for subsequent tasks and fail fast if missing
|
|
if command -v conan >/dev/null 2>&1; then
|
|
CONAN_DIR="$(dirname "$(command -v conan)")"
|
|
echo "PATH=${CONAN_DIR}:\$PATH" >> ~/.buildenv
|
|
else
|
|
echo "Conan is not available after installation attempts" >&2
|
|
exit 1
|
|
fi
|
|
CONAN_CPU_COUNT="${CONAN_CPU_COUNT:-$(nproc || getconf _NPROCESSORS_ONLN || echo 2)}"
|
|
echo "CONAN_CPU_COUNT=${CONAN_CPU_COUNT}" >> ~/.buildenv
|
|
|
|
# Detect and move into repository root
|
|
if [ -d yams ] && { [ -f yams/meson.build ] || [ -f yams/CMakeLists.txt ]; }; then
|
|
REPO_DIR="yams"
|
|
else
|
|
REPO_DIR="."
|
|
fi
|
|
cd "${REPO_DIR}"
|
|
|
|
# Configure Conan (use explicit GCC host/build profiles for Debian CI)
|
|
conan --version
|
|
conan profile detect --force || true
|
|
|
|
echo "Conan profile configured (default, overridden by setup.sh):"
|
|
conan profile show -pr default || conan profile show || true
|
|
|
|
- yams_semver_guard: |
|
|
set -e
|
|
if [ -d yams ] && { [ -f yams/meson.build ] || [ -f yams/CMakeLists.txt ]; }; then
|
|
REPO_DIR="yams"
|
|
else
|
|
REPO_DIR="."
|
|
fi
|
|
cd "${REPO_DIR}"
|
|
if [ -f scripts/ci/check_yams_semver.py ]; then
|
|
echo "Running YAMS semver guard..."
|
|
python3 scripts/ci/check_yams_semver.py
|
|
else
|
|
echo "No semver guard script found; skipping."
|
|
fi
|
|
|
|
- build: |
|
|
set -e
|
|
export PATH="${HOME}/.local/bin:/opt/conan/bin:${PATH}"
|
|
if ! command -v conan >/dev/null 2>&1; then
|
|
echo "conan not found in PATH; aborting build" >&2
|
|
exit 1
|
|
fi
|
|
if [ -d yams ] && [ -f yams/meson.build ]; then
|
|
REPO_DIR="yams"
|
|
else
|
|
REPO_DIR="."
|
|
fi
|
|
cd "${REPO_DIR}"
|
|
export YAMS_DISABLE_MODEL_PRELOAD=1
|
|
CLEAN_VERSION_MESON="${YAMS_VERSION}"
|
|
echo "Starting build (Meson version ${CLEAN_VERSION_MESON})"
|
|
|
|
# Use setup.sh with environment variables for consistent build configuration
|
|
export YAMS_COMPILER=gcc
|
|
export YAMS_CPPSTD=20
|
|
export YAMS_CONAN_HOST_PROFILE=./conan/profiles/host-linux-gcc
|
|
export YAMS_CONAN_ARCH=x86_64
|
|
|
|
# Avoid ccache environment wrapping in CI VMs — interferes with
|
|
# Conan/OpenBLAS ASM compilation (ccache doesn't handle -D flags)
|
|
export YAMS_SKIP_CCACHE=1
|
|
|
|
# Configure FAST_MODE via extra Meson flags
|
|
if [ "${FAST_MODE:-0}" = "1" ]; then
|
|
echo "FAST_MODE=1: build will skip ONNX and tests"
|
|
export YAMS_EXTRA_MESON_FLAGS="-Dyams-version=${CLEAN_VERSION_MESON} -Denable-onnx=disabled -Dplugin-onnx=false -Dbuild-tests=false"
|
|
else
|
|
export YAMS_EXTRA_MESON_FLAGS="-Dyams-version=${CLEAN_VERSION_MESON}"
|
|
fi
|
|
|
|
# Set install prefix to /usr for Linux packages (matches GitHub workflow)
|
|
export YAMS_INSTALL_PREFIX="/usr"
|
|
|
|
# Run setup.sh (Release build) - it now respects all YAMS_* environment variables
|
|
./setup.sh Release
|
|
|
|
# Build the project (single-job: prevents OOM on large files like mcp_server.cpp)
|
|
meson compile -C build/release -j1
|
|
|
|
# Install the built artifacts into build-local staging directory (BUILD_DIR/STAGE_DIR).
|
|
meson install -C build/release --destdir "${STAGE_DIR}"
|
|
|
|
# Show ccache stats after build (if available)
|
|
if command -v ccache >/dev/null 2>&1; then
|
|
ccache -s || true
|
|
fi
|
|
|
|
- test: |
|
|
set -e
|
|
# Run test suite; do not fail the build solely due to test failures so we can publish logs
|
|
if [ -d yams ] && [ -f yams/meson.build ]; then
|
|
REPO_DIR="yams"
|
|
else
|
|
REPO_DIR="."
|
|
fi
|
|
cd "${REPO_DIR}"
|
|
mkdir -p artifacts || true
|
|
if [ -d "${BUILD_DIR}" ]; then
|
|
echo "Running meson tests in ${BUILD_DIR}..."
|
|
meson test -C "${BUILD_DIR}" --print-errorlogs || true
|
|
# Collect logs and common debug info
|
|
if [ -d "${BUILD_DIR}/meson-logs" ]; then
|
|
tar -C "${BUILD_DIR}" -czf artifacts/meson-logs.tar.gz meson-logs || true
|
|
cp -vf "${BUILD_DIR}/meson-logs/testlog.txt" artifacts/testlog.txt 2>/dev/null || true
|
|
cp -vf "${BUILD_DIR}/meson-logs/meson-log.txt" artifacts/meson-log.txt 2>/dev/null || true
|
|
fi
|
|
# Export compile_commands if generated
|
|
if [ -f "${BUILD_DIR}/compile_commands.json" ]; then
|
|
cp -vf "${BUILD_DIR}/compile_commands.json" artifacts/compile_commands.json || true
|
|
fi
|
|
else
|
|
echo "BUILD_DIR ${BUILD_DIR} missing; skipping meson tests" | tee artifacts/test-notes.txt
|
|
fi
|
|
|
|
- package: |
|
|
set -e
|
|
# Package on tag builds or when explicitly channelized as nightly/weekly
|
|
# Auto-channelize main branch builds as nightly when not tagged
|
|
if [[ -z "${RELEASE_CHANNEL:-}" && "${GIT_REF:-}" == "refs/heads/main" ]]; then
|
|
export RELEASE_CHANNEL=nightly
|
|
fi
|
|
if [[ "${GIT_REF:-}" != refs/tags/* && "${RELEASE_CHANNEL:-}" != "nightly" && "${RELEASE_CHANNEL:-}" != "weekly" ]]; then
|
|
echo "Skipping packaging (not a tag build and no release channel): GIT_REF=${GIT_REF:-n/a} RELEASE_CHANNEL=${RELEASE_CHANNEL:-n/a}"
|
|
exit 0
|
|
fi
|
|
if [ -d yams ] && { [ -f yams/meson.build ] || [ -f yams/CMakeLists.txt ]; }; then
|
|
REPO_DIR="yams"
|
|
else
|
|
REPO_DIR="."
|
|
fi
|
|
cd "${REPO_DIR}"
|
|
CLEAN_VERSION="${YAMS_VERSION}"
|
|
echo "Packaging the release..."
|
|
# Package from the staged install under BUILD_DIR/STAGE_DIR
|
|
if [ ! -d "${BUILD_DIR}/${STAGE_DIR}" ]; then
|
|
echo "ERROR: Stage directory ${BUILD_DIR}/${STAGE_DIR} not found" >&2
|
|
ls -al "${BUILD_DIR}" || true
|
|
exit 1
|
|
fi
|
|
cd "${BUILD_DIR}/${STAGE_DIR}"
|
|
tar -czf "../yams-${CLEAN_VERSION}-linux-x86_64.tar.gz" .
|
|
echo "Created asset: yams-${CLEAN_VERSION}-linux-x86_64.tar.gz"
|
|
# Also publish a raw stage archive for debugging/inspection
|
|
tar -czf "../yams-${CLEAN_VERSION}-stage.tar.gz" .
|
|
if command -v zip >/dev/null 2>&1; then
|
|
# Only attempt zip if there are regular files to include; otherwise zip exits with "Nothing to do!"
|
|
if find . -type f -print -quit | grep -q .; then
|
|
zip -qry "../yams-${CLEAN_VERSION}-stage.zip" . || echo "zip failed; continuing (tarball already created)"
|
|
else
|
|
echo "Stage contains no regular files; skipping zip archive"
|
|
fi
|
|
fi
|
|
|
|
- package_meson: |
|
|
set -e
|
|
# Package on tag builds or when explicitly channelized as nightly/weekly
|
|
if [[ "${GIT_REF:-}" != refs/tags/* && "${RELEASE_CHANNEL:-}" != "nightly" && "${RELEASE_CHANNEL:-}" != "weekly" ]]; then
|
|
echo "Skipping packaging (not a tag build and no release channel): GIT_REF=${GIT_REF:-n/a} RELEASE_CHANNEL=${RELEASE_CHANNEL:-n/a}"
|
|
exit 0
|
|
fi
|
|
if [ -d yams ] && [ -f yams/meson.build ]; then
|
|
REPO_DIR="yams"
|
|
else
|
|
REPO_DIR="."
|
|
fi
|
|
cd "${REPO_DIR}"
|
|
CLEAN_VERSION="${YAMS_VERSION}"
|
|
echo "Packaging with Meson..."
|
|
if [ -x scripts/build-deb.sh ]; then
|
|
scripts/build-deb.sh "${CLEAN_VERSION}" "${BUILD_DIR}"
|
|
else
|
|
echo "scripts/build-deb.sh not found; skipping distro package step"
|
|
fi
|
|
|
|
- collect_artifacts: |
|
|
set -e
|
|
if [ -d yams ] && { [ -f yams/meson.build ] || [ -f yams/CMakeLists.txt ]; }; then
|
|
REPO_DIR="yams"
|
|
else
|
|
REPO_DIR="."
|
|
fi
|
|
bash "${REPO_DIR}/scripts/srht-collect-artifacts.sh"
|
|
exit 0
|
|
|
|
artifacts:
|
|
# SourceHut interprets artifact names literally (no shell globs). Provide
|
|
# stable filenames in collect_artifacts.
|
|
- "artifacts/yams.tar.gz"
|
|
- "artifacts/yams.deb"
|
|
- "artifacts/yams.rpm"
|
|
- "artifacts/meson-logs.tar.gz"
|
|
- "artifacts/testlog.txt"
|
|
- "artifacts/meson-log.txt"
|
|
- "artifacts/compile_commands.json"
|