Skip to content

build: 更新依赖版本并注释本地替换配置 #191

build: 更新依赖版本并注释本地替换配置

build: 更新依赖版本并注释本地替换配置 #191

Workflow file for this run

# =============================================================================
# MindX CI Pipeline — Production-grade GitHub Actions
# =============================================================================
# Stages: lint → vet → security → test (race + coverage) → build (matrix)
#
# Triggers:
# - push to main/develop, all PRs
# - manual dispatch for debugging
# =============================================================================
name: CI
on:
push:
branches: [main, develop]
paths-ignore:
- '**.md'
- 'docs/**'
- 'LICENSE'
- '.all-contributorsrc'
pull_request:
branches: [main, develop]
workflow_dispatch:
# Cancel in-progress runs on the same branch/PR
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
# ==========================================================================
# Environment defaults
# ==========================================================================
env:
GO_VERSION: '1.26'
CGO_ENABLED: 1
GOLANGCI_LINT_VERSION: v2.9
MINDX_WORKSPACE: ${{ github.workspace }}/.test
MODEL_PATH: runtime/data/models/model.onnx
jobs:
# ==========================================================================
# Stage 1: Lint — golangci-lint with project config
# ==========================================================================
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
cache: true
- name: golangci-lint
uses: golangci/golangci-lint-action@v9
with:
version: ${{ env.GOLANGCI_LINT_VERSION }}
args: --timeout=5m
# ==========================================================================
# Stage 2: Vet — static analysis
# ==========================================================================
vet:
name: Vet
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
cache: true
# Note: vet runs with CGO_ENABLED=1 (set globally) so CGO-dependent
# packages (gorag/go-tree-sitter/onnxruntime_go) compile correctly.
- name: Run go vet
run: |
PKGS=$(go list ./... | grep -v 'gort\|onnxruntime\|tree-sitter' || true)
if [ -z "$PKGS" ]; then
echo "No packages to vet"
else
echo "$PKGS" | xargs go vet
fi
# ==========================================================================
# Stage 3: Security — vulnerability check
# ==========================================================================
security:
name: Security
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
cache: true
- name: Install govulncheck
run: go install golang.org/x/vuln/cmd/govulncheck@latest
- name: Run govulncheck
run: |
PKGS=$(go list ./... | grep -v 'gort\|onnxruntime\|tree-sitter' || true)
if [ -z "$PKGS" ]; then
echo "No packages to scan"
else
govulncheck $PKGS | tee govulncheck-output.txt
fi
# ==========================================================================
# Stage 4: Test — race detector + coverage (matrix: OS)
# ==========================================================================
test:
name: Test (${{ matrix.os }})
runs-on: ${{ matrix.os }}
needs: [lint, vet]
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
env:
CGO_ENABLED: 1 # race detector requires CGO
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
cache: true
- name: Install ONNX Runtime (Linux)
if: runner.os == 'Linux'
run: |
ONNX_VERSION="1.24.4"
ONNX_DIR="onnxruntime-linux-x64-${ONNX_VERSION}"
curl -fL -o /tmp/onnxruntime.tgz \
"https://github.com/microsoft/onnxruntime/releases/download/v${ONNX_VERSION}/${ONNX_DIR}.tgz"
sudo tar xzf /tmp/onnxruntime.tgz -C /usr/local/lib \
"${ONNX_DIR}/lib/libonnxruntime.so.${ONNX_VERSION}" \
"${ONNX_DIR}/lib/libonnxruntime.so.1" \
"${ONNX_DIR}/lib/libonnxruntime.so"
sudo ln -sf "/usr/local/lib/${ONNX_DIR}/lib/libonnxruntime.so.${ONNX_VERSION}" \
"/usr/local/lib/libonnxruntime.so.${ONNX_VERSION}" 2>/dev/null || true
sudo ln -sf "/usr/local/lib/${ONNX_DIR}/lib/libonnxruntime.so.1" \
"/usr/local/lib/libonnxruntime.so.1" 2>/dev/null || true
sudo ln -sf "/usr/local/lib/${ONNX_DIR}/lib/libonnxruntime.so" \
"/usr/local/lib/libonnxruntime.so" 2>/dev/null || true
sudo ldconfig 2>/dev/null || true
echo "ONNX Runtime installed:"
ls -la /usr/local/lib/libonnxruntime.so*
- name: Install ONNX Runtime (macOS)
if: runner.os == 'macOS'
run: |
if ! brew list onnxruntime &>/dev/null; then
brew install onnxruntime
else
echo "onnxruntime already installed"
fi
- name: Restore embedder model from cache
id: model-cache
uses: actions/cache@v4
with:
path: ${{ env.MODEL_PATH }}
key: model-q4-onnx-v1
- name: Download embedder model (cache miss)
if: steps.model-cache.outputs.cache-hit != 'true'
run: |
mkdir -p "$(dirname "${{ env.MODEL_PATH }}")"
rm -f "${{ env.MODEL_PATH }}"
echo "Downloading embedder model from HuggingFace..."
curl -fL -o "${{ env.MODEL_PATH }}" \
"https://huggingface.co/Xenova/bge-small-zh-v1.5/resolve/main/onnx/model.onnx" || \
{ echo "ERROR: Failed to download embedder model"; exit 1; }
- name: Prepare test workspace
run: |
mkdir -p .test
cp -r config .test/config 2>/dev/null || true
# DefaultApp(nil) requires mindx home with agents/models/providers/skills
# macOS/Linux: ~/.mindx Windows: %APPDATA%/mindx
if [ -n "$APPDATA" ]; then
MINDX_HOME="$APPDATA/mindx"
else
MINDX_HOME="$HOME/.mindx"
fi
mkdir -p "$MINDX_HOME/agents" "$MINDX_HOME/skills" "$MINDX_HOME/sessions" "$MINDX_HOME/settings"
echo 'models: []' > "$MINDX_HOME/settings/models.yml"
echo 'providers: []' > "$MINDX_HOME/settings/providers.yml"
shell: bash
- name: Run tests with race detector & coverage
shell: bash
run: |
go test \
-race \
-coverprofile=coverage.out \
-covermode=atomic \
-timeout=10m \
-v ./... 2>&1 | tee test-output.txt
env:
MINDX_WORKSPACE: ${{ env.MINDX_WORKSPACE }}
- name: Display coverage summary
if: runner.os != 'Windows'
run: go tool cover -func=coverage.out | tail -1
- name: Upload coverage artifact
if: matrix.os == 'ubuntu-latest'
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: coverage.out
retention-days: 7
- name: Upload test output
if: always()
uses: actions/upload-artifact@v4
with:
name: test-output-${{ matrix.os }}
path: test-output.txt
retention-days: 7
# ==========================================================================
# Stage 5: Build verification (matrix: OS + Arch)
# ==========================================================================
build:
name: Build (${{ matrix.goos }}/${{ matrix.goarch }})
runs-on: ${{ matrix.runner }}
needs: [test]
strategy:
fail-fast: false
matrix:
include:
- goos: linux
goarch: amd64
runner: ubuntu-latest
- goos: linux
goarch: arm64
runner: ubuntu-latest
- goos: darwin
goarch: amd64
runner: macos-latest
- goos: darwin
goarch: arm64
runner: macos-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
cache: true
- name: Restore embedder model from cache
id: model-cache
uses: actions/cache@v4
with:
path: ${{ env.MODEL_PATH }}
key: model-q4-onnx-v1
- name: Download embedder model (cache miss)
if: steps.model-cache.outputs.cache-hit != 'true'
run: |
mkdir -p "$(dirname "${{ env.MODEL_PATH }}")"
rm -f "${{ env.MODEL_PATH }}"
echo "Downloading embedder model from HuggingFace..."
curl -fL -o "${{ env.MODEL_PATH }}" \
"https://huggingface.co/Xenova/bge-small-zh-v1.5/resolve/main/onnx/model.onnx" || \
{ echo "ERROR: Failed to download embedder model"; exit 1; }
- name: Install musl cross-compiler
if: matrix.goos == 'linux'
run: |
sudo apt-get update
sudo apt-get install -y musl-tools musl-dev
# For arm64: install zig as cross-compiler fallback (musl.cc often unreachable from CI)
if [ "${{ matrix.goarch }}" = "arm64" ]; then
if ! command -v aarch64-linux-musl-gcc &>/dev/null; then
echo "aarch64-linux-musl-gcc not found, installing zig..."
ZIG_VER="0.13.0"
wget -q "https://ziglang.org/download/${ZIG_VER}/zig-linux-x86_64-${ZIG_VER}.tar.xz" -O /tmp/zig.tar.xz
sudo tar xf /tmp/zig.tar.xz -C /usr/local
sudo ln -sf /usr/local/zig-linux-x86_64-${ZIG_VER}/zig /usr/local/bin/zig
rm /tmp/zig.tar.xz
zig version
fi
fi
- name: Get version info
id: version
shell: bash
run: |
echo "version=$(git describe --tags --abbrev=0 2>/dev/null || echo 'dev')" >> "$GITHUB_OUTPUT"
echo "commit=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT"
echo "build_time=$(date -u '+%Y-%m-%dT%H:%M:%SZ')" >> "$GITHUB_OUTPUT"
- name: Build
shell: bash
env:
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
run: |
# Set musl cross-compiler for Linux (Alpine Docker image uses musl)
if [ "$GOOS" = "linux" ]; then
if [ "$GOARCH" = "amd64" ]; then
export CC=x86_64-linux-musl-gcc
elif [ "$GOARCH" = "arm64" ]; then
# Use native musl-gcc if available, otherwise fall back to zig
if command -v aarch64-linux-musl-gcc &>/dev/null; then
export CC=aarch64-linux-musl-gcc
else
export CC="zig cc -target aarch64-linux-musl"
fi
fi
fi
BINARY_NAME=mindx
VERSION=${{ steps.version.outputs.version }}
COMMIT=${{ steps.version.outputs.commit }}
BUILD_TIME=${{ steps.version.outputs.build_time }}
SUFFIX=""
[ "${{ matrix.goos }}" = "windows" ] && SUFFIX=".exe"
go build \
-trimpath \
-ldflags="-s -w \
-X github.com/DotNetAge/mindx/internal/core.Version=${VERSION#v} \
-X github.com/DotNetAge/mindx/internal/core.Commit=${COMMIT} \
-X github.com/DotNetAge/mindx/internal/core.BuildTime=${BUILD_TIME}" \
-o dist/${BINARY_NAME}-${{ matrix.goos }}-${{ matrix.goarch }}${SUFFIX} \
.
ls -lh dist/
- name: Upload build artifact
uses: actions/upload-artifact@v4
with:
name: mindx-${{ matrix.goos }}-${{ matrix.goarch }}
path: dist/
retention-days: 7