From c89493a65276d312ec4052d1d0c22a3c4ccaad63 Mon Sep 17 00:00:00 2001 From: Pedro Ramos <131530838+pr9000@users.noreply.github.com> Date: Mon, 3 Aug 2026 11:15:22 +0100 Subject: [PATCH 1/3] ci(freebsd): add build-freebsd job to reusable build workflow Adds FreeBSD 15.1 and 14.4 x86_64 build matrix legs. The aarch64 leg remains commented out due to npm lightningcss missing prebuilt binaries on freebsd-arm64. Signed-off-by: Pedro Ramos <131530838+pr9000@users.noreply.github.com> --- .github/workflows/_build.yml | 75 ++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/.github/workflows/_build.yml b/.github/workflows/_build.yml index 82d2f6241..4dd0f69e2 100644 --- a/.github/workflows/_build.yml +++ b/.github/workflows/_build.yml @@ -334,3 +334,78 @@ jobs: with: name: binaries-linux-${{ matrix.arch }}-portable path: "*.tar.gz" + + build-freebsd: + name: build-unix (freebsd-${{ matrix.release }}, freebsd, ${{ matrix.arch }}, clang, clang++) + strategy: + fail-fast: false + matrix: + release: ['15.1', '14.4'] + arch: ['x86_64'] + # arch: ['x86_64', 'aarch64'] + # aarch64 disabled for now: lightningcss (a native Rust dependency of + # the Vite/CSS build pipeline) publishes no prebuilt binary for + # freebsd-arm64, so `npm run build` fails with "Cannot find module + # '../lightningcss.freebsd-arm64.node'" — a real gap in that + # package's platform coverage, not something fixable on our side + # without vendoring a Rust build of it. Re-enable once lightningcss + # ships that target, or once the frontend build is moved to run + # natively on a Linux host instead of inside the FreeBSD VM. + include: + - arch: x86_64 + artifact_arch: amd64 + sync: rsync + # - arch: aarch64 + # artifact_arch: arm64-aarch64 + # sync: scp + # Must use ubuntu-latest (x86_64 host). Running QEMU guest emulation on arm runners (ubuntu-*-arm) + # causes severe performance degradation leading to 3+ hour timeouts. + runs-on: ubuntu-latest + timeout-minutes: 240 + steps: + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + + - name: Build FreeBSD ${{ matrix.release }} (${{ matrix.arch }}) binaries inside VM + # https://github.com/vmactions/freebsd-vm + uses: vmactions/freebsd-vm@v1 + with: + release: ${{ matrix.release }} + arch: ${{ matrix.arch }} + # Sync options: rsync, sshfs, nfs, scp + sync: ${{ matrix.sync }} + usesh: true + mem: 6144 + cpu: 4 + prepare: | + pkg update -f + pkg install -y gmake sqlite3 pkgconf node22 npm-node22 bash + run: | + which python3 >/dev/null 2>&1 || ln -sf $(which python3.15 python3.14 python3.13 python3.12 python3.11 python3.10 2>/dev/null | head -n 1) /usr/local/bin/python3 + echo "Python location: $(which python3 2>/dev/null || echo 'not found')" + python3 --version 2>&1 || true + + # 1. Build standard binary + gmake -f Makefile.cbm cbm + scripts/package-release.sh freebsd ${{ matrix.arch }}-${{ matrix.release }} + + # 2. Build UI binary + gmake -f Makefile.cbm cbm-with-ui + scripts/package-release.sh freebsd ${{ matrix.arch }}-${{ matrix.release }} --variant ui + + - name: Attest standard binary provenance + if: ${{ inputs.attest }} + uses: actions/attest-build-provenance@0f67c3f4856b2e3261c31976d6725780e5e4c373 # v4.1.1 + with: + subject-path: codebase-memory-mcp-freebsd-${{ matrix.artifact_arch }}-${{ matrix.release }}.tar.gz + + - name: Attest UI binary provenance + if: ${{ inputs.attest }} + uses: actions/attest-build-provenance@0f67c3f4856b2e3261c31976d6725780e5e4c373 # v4.1.1 + with: + subject-path: codebase-memory-mcp-ui-freebsd-${{ matrix.artifact_arch }}-${{ matrix.release }}.tar.gz + + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: binaries-freebsd-${{ matrix.artifact_arch }}-${{ matrix.release }} + path: "*.tar.gz" + From e78f9e2f62f5a574472a8a0989592f64e16a14c9 Mon Sep 17 00:00:00 2001 From: Pedro Ramos <131530838+pr9000@users.noreply.github.com> Date: Thu, 6 Aug 2026 10:10:57 +0100 Subject: [PATCH 2/3] fix(ci): route FreeBSD build through canonical scripts/build.sh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - scripts/env.sh: add freebsd* OS detection + MAKE=gmake (BSD make doesn't understand GNU Makefile.cbm syntax; all other platforms use 'make') - scripts/build.sh: use $MAKE instead of hard-coded 'make' (2 call sites) - scripts/package-release.sh: add 'freebsd' to GOOS case validation + usage - .github/workflows/_build.yml: replace inline gmake calls with scripts/build.sh, following venue-parity contract Venue parity contract requires: provision in prepare:, call canonical scripts/ in run:. Inline gmake violated this — now FreeBSD follows the same pattern as Linux/macOS/Windows. Closes: PR #1422 venue-parity contract violation Signed-off-by: Pedro Ramos <131530838+pr9000@users.noreply.github.com> --- .github/workflows/_build.yml | 21 +++++++++++++-------- scripts/build.sh | 4 ++-- scripts/env.sh | 13 ++++++++++++- scripts/package-release.sh | 6 +++--- 4 files changed, 30 insertions(+), 14 deletions(-) diff --git a/.github/workflows/_build.yml b/.github/workflows/_build.yml index 4dd0f69e2..73c07f731 100644 --- a/.github/workflows/_build.yml +++ b/.github/workflows/_build.yml @@ -379,17 +379,22 @@ jobs: prepare: | pkg update -f pkg install -y gmake sqlite3 pkgconf node22 npm-node22 bash - run: | which python3 >/dev/null 2>&1 || ln -sf $(which python3.15 python3.14 python3.13 python3.12 python3.11 python3.10 2>/dev/null | head -n 1) /usr/local/bin/python3 - echo "Python location: $(which python3 2>/dev/null || echo 'not found')" - python3 --version 2>&1 || true - - # 1. Build standard binary - gmake -f Makefile.cbm cbm + run: | + # Build standard binary (canonical scripts/build.sh pattern) + if [ -n "${{ inputs.version }}" ]; then + scripts/build.sh --version "${{ inputs.version }}" CC=clang CXX=clang++ + else + scripts/build.sh CC=clang CXX=clang++ + fi scripts/package-release.sh freebsd ${{ matrix.arch }}-${{ matrix.release }} - # 2. Build UI binary - gmake -f Makefile.cbm cbm-with-ui + # Build UI binary + if [ -n "${{ inputs.version }}" ]; then + scripts/build.sh --version "${{ inputs.version }}" --with-ui CC=clang CXX=clang++ + else + scripts/build.sh --with-ui CC=clang CXX=clang++ + fi scripts/package-release.sh freebsd ${{ matrix.arch }}-${{ matrix.release }} --variant ui - name: Attest standard binary provenance diff --git a/scripts/build.sh b/scripts/build.sh index 575477a94..7fd7426b5 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -149,10 +149,10 @@ cbm_remove_build_dir "$ROOT" "$BUILD_DIR" # Step 2: Build (Makefile applies $ARCHFLAGS for the target arch on macOS) if $WITH_UI; then - make -j"$NPROC" -f Makefile.cbm cbm-with-ui \ + $MAKE -j"$NPROC" -f Makefile.cbm cbm-with-ui \ CFLAGS_EXTRA="$CFLAGS_EXTRA" "${EXTRA_MAKE_ARGS[@]+"${EXTRA_MAKE_ARGS[@]}"}" else - make -j"$NPROC" -f Makefile.cbm cbm \ + $MAKE -j"$NPROC" -f Makefile.cbm cbm \ CFLAGS_EXTRA="$CFLAGS_EXTRA" "${EXTRA_MAKE_ARGS[@]+"${EXTRA_MAKE_ARGS[@]}"}" fi diff --git a/scripts/env.sh b/scripts/env.sh index e23affe4c..0d0e7b6f6 100755 --- a/scripts/env.sh +++ b/scripts/env.sh @@ -7,7 +7,7 @@ # ARCH — target architecture (arm64 / x86_64) # ARCHFLAGS — "-arch " on macOS (target slice for clang/ld), empty elsewhere # NPROC — number of CPU cores -# OS — darwin / linux / windows +# OS — darwin / linux / windows / freebsd set -euo pipefail @@ -16,10 +16,21 @@ OS="$(uname -s | tr '[:upper:]' '[:lower:]')" case "$OS" in darwin) OS="darwin" ;; linux) OS="linux" ;; + freebsd*) OS="freebsd" ;; mingw*|msys*|cygwin*) OS="windows" ;; *) OS="unknown" ;; esac +# ── Set platform-appropriate make ────────────────────────────── +# FreeBSD ships BSD make as the default 'make'; GNU Makefile syntax in +# Makefile.cbm requires gmake. All other platforms use 'make'. +if [[ "$OS" == "freebsd" ]]; then + MAKE=gmake +else + MAKE=make +fi +export MAKE + # ── Detect / override architecture ───────────────────────────── # Default: native HARDWARE architecture (not Rosetta-translated). # On macOS under Rosetta, uname -m returns x86_64 even on Apple Silicon. diff --git a/scripts/package-release.sh b/scripts/package-release.sh index 72b090704..868fbfc54 100755 --- a/scripts/package-release.sh +++ b/scripts/package-release.sh @@ -23,7 +23,7 @@ Usage: scripts/package-release.sh [--variant standard|ui] The canonical release-archive step: identical in the release build and the local artifact-flow smoke lane. - goos linux | darwin | windows + goos linux | darwin | windows | freebsd goarch arch label used verbatim in the archive name (amd64, arm64, arm64-portable, ...) --variant standard (default) | ui — selects the archive NAME prefix; the @@ -77,8 +77,8 @@ for arg in "$@"; do done [ -n "$GOOS" ] && [ -n "$GOARCH" ] || { usage >&2; exit 2; } case "$GOOS" in -linux | darwin | windows) ;; -*) echo "package-release: goos must be linux, darwin or windows." >&2; exit 2 ;; +linux | darwin | windows | freebsd) ;; +*) echo "package-release: goos must be linux, darwin, windows or freebsd." >&2; exit 2 ;; esac case "$VARIANT" in standard) SUFFIX="" ;; From 635373c4b7eb16398df7fe35bb90b8ee927fe4c0 Mon Sep 17 00:00:00 2001 From: Pedro Ramos <131530838+pr9000@users.noreply.github.com> Date: Thu, 6 Aug 2026 18:00:43 +0100 Subject: [PATCH 3/3] fix(ci): pin vmactions/freebsd-vm to SHA for security audit Security audit (scripts/security-audit.sh Layer 1) blocks unpinned GitHub Actions. Pin vmactions/freebsd-vm@v1 to its release commit SHA. Ref: scripts/security-audit.sh BLOCKED check Signed-off-by: Pedro Ramos <131530838+pr9000@users.noreply.github.com> --- .github/workflows/_build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/_build.yml b/.github/workflows/_build.yml index 73c07f731..42f9480cd 100644 --- a/.github/workflows/_build.yml +++ b/.github/workflows/_build.yml @@ -367,7 +367,7 @@ jobs: - name: Build FreeBSD ${{ matrix.release }} (${{ matrix.arch }}) binaries inside VM # https://github.com/vmactions/freebsd-vm - uses: vmactions/freebsd-vm@v1 + uses: vmactions/freebsd-vm@83b151f58c6047089f4c80eb5ba2039d158ce093 # v1 with: release: ${{ matrix.release }} arch: ${{ matrix.arch }}