mirror of
https://github.com/mudler/LocalAI.git
synced 2026-09-13 06:45:26 -04:00
* fix(ci): remove the e2e container before removing its image `docker stop` returns as soon as the container exits, but the daemon reaps a `--rm` container asynchronously after that. The `docker rmi localai-tests` that follows teardown-e2e then loses the race against the reaper and fails with "conflict: ... is using its referenced image", so make exits 1 and the job goes red after every spec has passed. This is why the E2E Backend Tests job fails at random across pull requests. Runs 33435319093, 33435332991, 33412165884 and 33444669207 all report "SUCCESS! -- 235 Passed | 0 Failed" and then die in teardown. `docker rm -f` is synchronous, so the image reference is gone before teardown-e2e returns. It also covers the case where no container is running, which `docker stop` could not because it rejects an empty argument list. Signed-off-by: Ettore Di Giacinto <mudler@localai.io> Assisted-by: Claude:claude-opus-5 [Claude Code] * fix(ci): open a tmate session only when a PR asks for one The tmate step runs on every failure and then holds the runner until GitHub cancels the job at the 6 hour limit. A one second cleanup race in the e2e teardown therefore costs a whole ubuntu-latest slot. The recent run list is full of 6h, 7h and 12h cancelled runs for that reason. The step now needs the `ci-debug` label on the pull request, so a session opens when somebody wants to debug and never otherwise. The 30 minute step timeout caps the cost when the label is left behind. Signed-off-by: Ettore Di Giacinto <mudler@localai.io> Assisted-by: Claude:claude-opus-5 [Claude Code] --------- Signed-off-by: Ettore Di Giacinto <mudler@localai.io> Co-authored-by: Ettore Di Giacinto <mudler@localai.io>
161 lines
6.6 KiB
YAML
161 lines
6.6 KiB
YAML
---
|
|
name: 'tests'
|
|
|
|
on:
|
|
pull_request:
|
|
push:
|
|
branches:
|
|
- master
|
|
tags:
|
|
- '*'
|
|
|
|
concurrency:
|
|
group: ci-tests-${{ github.event.pull_request.number || github.sha }}-${{ github.repository }}
|
|
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
|
|
|
jobs:
|
|
tests-linux:
|
|
runs-on: ubuntu-latest
|
|
strategy:
|
|
matrix:
|
|
go-version: ['1.26.x']
|
|
steps:
|
|
- name: Clone
|
|
uses: actions/checkout@v7
|
|
with:
|
|
submodules: true
|
|
# No free-disk-space step here on purpose. That action exists to make room
|
|
# for docker buildx layers, and this job runs no buildx step. It was also
|
|
# sized for a `make test` that downloaded multi-GB GGUF/whisper fixtures
|
|
# and built llama-cpp/whisper/stablediffusion-ggml; after the test-suite
|
|
# reorg it does neither (see the Makefile test target). It cost ~3min of
|
|
# every run, and its tool-cache:true wipe also forced setup-go and
|
|
# setup-node to re-download toolchains that ship preinstalled.
|
|
- name: Setup Go ${{ matrix.go-version }}
|
|
uses: actions/setup-go@v5
|
|
with:
|
|
go-version: ${{ matrix.go-version }}
|
|
cache: false
|
|
# You can test your matrix by printing the current Go version
|
|
- name: Display Go version
|
|
run: go version
|
|
- name: Proto Dependencies
|
|
run: |
|
|
# Install protoc
|
|
curl -L -s https://github.com/protocolbuffers/protobuf/releases/download/v26.1/protoc-26.1-linux-x86_64.zip -o protoc.zip && \
|
|
unzip -j -d /usr/local/bin protoc.zip bin/protoc && \
|
|
rm protoc.zip
|
|
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.34.2
|
|
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@1958fcbe2ca8bd93af633f11e97d44e567e945af
|
|
PATH="$PATH:$HOME/go/bin" make protogen-go
|
|
- name: Dependencies
|
|
run: |
|
|
sudo apt-get update
|
|
sudo apt-get install curl ffmpeg libopus-dev
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@v7
|
|
with:
|
|
node-version: '22'
|
|
- name: Build React UI
|
|
run: make react-ui
|
|
# Runs the core suite with coverage and fails if total coverage dropped
|
|
# below the committed baseline (coverage-baseline.txt). The gate is
|
|
# strict — any decrease fails. Raise the baseline with
|
|
# `make test-coverage-baseline` and commit it when coverage rises.
|
|
- name: Test (with coverage gate)
|
|
run: |
|
|
PATH="$PATH:/root/go/bin" make --jobs 5 --output-sync=target test-coverage-check
|
|
# tests/integration is outside the coverage roots because its store specs
|
|
# need a live backend. test-stores builds and installs local-store before
|
|
# running the complete suite, so new local-store specs are collected
|
|
# automatically without adding another workflow entry.
|
|
- name: Test local-store integration
|
|
run: PATH="$PATH:$HOME/go/bin" make test-stores
|
|
- name: Upload coverage report
|
|
if: ${{ always() }}
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: coverage-linux
|
|
path: |
|
|
coverage/coverage.out
|
|
coverage/coverage.html
|
|
if-no-files-found: ignore
|
|
# tmate keeps the runner busy until the 6 hour job limit, so a single
|
|
# failure costs a whole runner slot. Only open a session when someone
|
|
# asked for one by labelling the pull request `ci-debug`, and cap the
|
|
# session so a forgotten label cannot idle a runner either.
|
|
- name: Setup tmate session if tests fail
|
|
if: ${{ failure() && contains(github.event.pull_request.labels.*.name, 'ci-debug') }}
|
|
timeout-minutes: 30
|
|
uses: mxschmitt/action-tmate@v3.23
|
|
with:
|
|
detached: true
|
|
connect-timeout-seconds: 180
|
|
limit-access-to-actor: true
|
|
|
|
tests-apple:
|
|
runs-on: macos-latest
|
|
strategy:
|
|
matrix:
|
|
go-version: ['1.26.x']
|
|
steps:
|
|
- name: Clone
|
|
uses: actions/checkout@v7
|
|
with:
|
|
submodules: true
|
|
- name: Setup Go ${{ matrix.go-version }}
|
|
uses: actions/setup-go@v5
|
|
with:
|
|
go-version: ${{ matrix.go-version }}
|
|
cache: false
|
|
# You can test your matrix by printing the current Go version
|
|
- name: Display Go version
|
|
run: go version
|
|
- name: Dependencies
|
|
run: |
|
|
brew install protobuf grpc make protoc-gen-go protoc-gen-go-grpc libomp llvm opus ffmpeg
|
|
pip install --user --no-cache-dir grpcio-tools grpcio
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@v7
|
|
with:
|
|
node-version: '22'
|
|
- name: Build React UI
|
|
run: make react-ui
|
|
- name: Test
|
|
run: |
|
|
export C_INCLUDE_PATH=/usr/local/include
|
|
export CPLUS_INCLUDE_PATH=/usr/local/include
|
|
export CC=/opt/homebrew/opt/llvm/bin/clang
|
|
# Used to run the newer GNUMake version from brew that supports --output-sync
|
|
export PATH="/opt/homebrew/opt/make/libexec/gnubin:$PATH"
|
|
PATH="$PATH:$HOME/go/bin" make protogen-go
|
|
PATH="$PATH:$HOME/go/bin" BUILD_TYPE="GITHUB_CI_HAS_BROKEN_METAL" CMAKE_ARGS="-DGGML_F16C=OFF -DGGML_AVX512=OFF -DGGML_AVX2=OFF -DGGML_FMA=OFF" make --jobs 4 --output-sync=target test
|
|
# tmate keeps the runner busy until the 6 hour job limit, so a single
|
|
# failure costs a whole runner slot. Only open a session when someone
|
|
# asked for one by labelling the pull request `ci-debug`, and cap the
|
|
# session so a forgotten label cannot idle a runner either.
|
|
- name: Setup tmate session if tests fail
|
|
if: ${{ failure() && contains(github.event.pull_request.labels.*.name, 'ci-debug') }}
|
|
timeout-minutes: 30
|
|
uses: mxschmitt/action-tmate@v3.23
|
|
with:
|
|
detached: true
|
|
connect-timeout-seconds: 180
|
|
limit-access-to-actor: true
|
|
|
|
# Fast standalone unit tests for the backends' pure C++ helpers - currently the
|
|
# llama-cpp message reconstruction (backend/cpp/llama-cpp/message_content.h),
|
|
# which guards the OpenAI chat content normalization (mudler/LocalAI#10524,
|
|
# #7324, #7528). The runner discovers every *_test.cpp under backend/cpp/, so
|
|
# new pure-C++ unit tests are picked up with no CI changes. These need only the
|
|
# C++ stdlib + nlohmann/json, so they run on every PR without the full
|
|
# llama.cpp + gRPC backend build. (The same suite is also wired as an opt-in
|
|
# CMake/ctest target, -DLLAMA_GRPC_BUILD_TESTS=ON, for in-backend-build runs.)
|
|
tests-backend-cpp:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Clone
|
|
uses: actions/checkout@v7
|
|
- name: Run backend C++ unit tests
|
|
run: make test-backend-cpp
|