From 739d3a7c37c8d6d88caa7bf402cd5478fdbbcdc1 Mon Sep 17 00:00:00 2001 From: mattshax Date: Thu, 10 Sep 2026 15:54:28 +0000 Subject: [PATCH] ci: a manual macOS job that builds GUFI and exercises its vector stack Run by hand rather than on every push, since the AI dependency path compiles llama.cpp and takes far longer than the test suite. It builds GUFI at a chosen ref on a clean macOS runner, indexes a small tree and queries it, then does exactly what the Studio does with the vector extensions: load the embedding model, embed a phrase with lembed, store vectors in a vec0 table, and take the nearest by distance. Finally it points the built server at that index to confirm it finds the binaries. What this answers that a local build cannot is whether GUFI works on a machine nobody has configured, which is the state a new Mac user is in. --- .github/workflows/gufi-macos.yml | 89 ++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 .github/workflows/gufi-macos.yml diff --git a/.github/workflows/gufi-macos.yml b/.github/workflows/gufi-macos.yml new file mode 100644 index 0000000..81655d6 --- /dev/null +++ b/.github/workflows/gufi-macos.yml @@ -0,0 +1,89 @@ +# Build GUFI on a clean macOS runner and exercise the pieces the Studio +# depends on. Run by hand rather than on every push: the AI dependency path +# compiles llama.cpp and takes far longer than the test suite. +# +# What this answers that a local build cannot: whether GUFI builds and its +# vector stack works on a machine nobody has configured, which is the state +# a new Mac user is in. +name: gufi-macos + +on: + workflow_dispatch: + inputs: + gufi_ref: + description: GUFI branch, tag, or commit + default: main + dep_ai: + description: Build the AI dependencies (sqlite-vec and sqlite-lembed) + type: boolean + default: true + +jobs: + build: + runs-on: macos-15 + timeout-minutes: 90 + steps: + - uses: actions/checkout@v4 + + - name: build GUFI + env: + GUFI_SRC: ${{ github.workspace }}/gufi-src + GUFI_PREFIX: ${{ github.workspace }}/gufi + GUFI_AI: ${{ inputs.dep_ai && '1' || '0' }} + run: | + set -x + git clone https://github.com/mar-file-system/GUFI "$GUFI_SRC" + git -C "$GUFI_SRC" checkout "${{ inputs.gufi_ref }}" + indexer/setup_gufi.sh + + - name: what got built + run: | + ls "${{ github.workspace }}/gufi/bin" + "${{ github.workspace }}/gufi/bin/gufi_query" -H 2>&1 | head -20 || true + + - name: index a tree and query it + run: | + set -e + BIN="${{ github.workspace }}/gufi/bin" + mkdir -p corpus/notes + printf 'the index is a tree of per-directory databases\n' > corpus/notes/design.txt + printf 'nothing to do with the other file\n' > corpus/unrelated.md + "$BIN/gufi_dir2index" -x corpus idx + "$BIN/gufi_query" -d ' ' -E "SELECT name, size FROM vrpentries;" idx/corpus + + - name: embed a phrase and search vectors + if: ${{ inputs.dep_ai }} + run: | + set -e + BIN="${{ github.workspace }}/gufi/bin" + MODEL="$(find "${{ github.workspace }}" -name 'minilm384.gguf' | head -1)" + test -n "$MODEL" + # The pattern the Studio uses: load the model, embed the question + # with lembed, store document vectors in a vec0 table, and take the + # nearest by distance. + "$BIN/gufi_sqlite3" <