build: 更新依赖版本并注释本地替换配置 #191
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # ============================================================================= | |
| # 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 |