From 57d12f9ae0776dce2edb8755c9ad2741749e5a51 Mon Sep 17 00:00:00 2001 From: lc285652 Date: Mon, 27 Jul 2026 19:07:22 +0800 Subject: [PATCH 1/4] ci: add release workflow to publish prebuilt shared libraries - release.yml: triggered by v* tag push or manual dispatch, creates GitHub Release via softprops/action-gh-release - _build_prebuilt.yml: reusable workflow building zvec SDK (include/ + lib/, shared libs only) for osx-arm64, linux-amd64, linux-arm64 and windows-amd64 with DuckDB-style asset naming --- .github/workflows/_build_prebuilt.yml | 147 ++++++++++++++++++++++++++ .github/workflows/release.yml | 83 +++++++++++++++ 2 files changed, 230 insertions(+) create mode 100644 .github/workflows/_build_prebuilt.yml create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/_build_prebuilt.yml b/.github/workflows/_build_prebuilt.yml new file mode 100644 index 000000000..5dd9b57a6 --- /dev/null +++ b/.github/workflows/_build_prebuilt.yml @@ -0,0 +1,147 @@ +name: Build Prebuilt Libraries + +on: + workflow_dispatch: + workflow_call: + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + name: Build (${{ matrix.os_name }}-${{ matrix.arch }}) + runs-on: ${{ matrix.os }} + timeout-minutes: 180 + strategy: + fail-fast: false + matrix: + include: + - target: aarch64-apple-darwin + os: macos-15 + os_name: osx + arch: arm64 + ext: tar.gz + - target: x86_64-unknown-linux-gnu + os: ubuntu-24.04 + os_name: linux + arch: amd64 + ext: tar.gz + - target: aarch64-unknown-linux-gnu + os: ubuntu-24.04-arm + os_name: linux + arch: arm64 + ext: tar.gz + - target: x86_64-pc-windows-msvc + os: windows-2025 + os_name: windows + arch: amd64 + ext: zip + + env: + INSTALL_DIR: ${{ github.workspace }}/install + DIST_DIR: ${{ github.workspace }}/dist + + steps: + - name: Checkout code + uses: actions/checkout@v7 + with: + submodules: recursive + + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: '3.11' + cache: 'pip' + cache-dependency-path: 'pyproject.toml' + + - name: Install dependencies (Unix) + if: runner.os != 'Windows' + run: | + python -m pip install --upgrade pip + python -m pip install \ + pybind11==3.0 \ + cmake==3.30.0 \ + ninja==1.11.1 + shell: bash + + - name: Install dependencies (Windows) + if: runner.os == 'Windows' + run: | + python -m pip install --upgrade pip ` + pybind11==3.0 ` + cmake==3.30.0 ` + ninja==1.11.1 + shell: powershell + + - name: Set up MSVC environment + if: runner.os == 'Windows' + uses: ilammy/msvc-dev-cmd@v1.13.0 + with: + arch: x64 + + - name: Configure CMake + shell: bash + run: | + cmake -S . -B build -G Ninja \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX="$INSTALL_DIR" \ + -DBUILD_TOOLS=OFF \ + -DBUILD_PYTHON_BINDINGS=OFF \ + -DBUILD_C_BINDINGS=ON \ + -DBUILD_ZVEC_SHARED=ON \ + -DBUILD_ZVEC_CORE_SHARED=ON \ + -DBUILD_ZVEC_AILEGO_SHARED=ON \ + -DENABLE_WERROR=OFF + + - name: Build and install SDK + shell: bash + run: | + NPROC=$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 4) + cmake --build build --target install --parallel "$NPROC" + + - name: Stage package contents + shell: bash + run: | + mkdir -p "$DIST_DIR" + cp -R "$INSTALL_DIR"/. "$DIST_DIR"/. + # Ship shared libraries only: zvec static libs are not self-contained + # (third-party deps like rocksdb/arrow/protobuf are not installed). + # On Windows, keep DLL import libs (*_shared.lib, zvec_c_api.lib). + rm -f "$DIST_DIR"/lib/*.a + rm -f "$DIST_DIR"/lib/zvec.lib \ + "$DIST_DIR"/lib/zvec_core.lib \ + "$DIST_DIR"/lib/zvec_ailego.lib \ + "$DIST_DIR"/lib/zvec_turbo.lib + # On Windows, DLLs are installed into bin/ (RUNTIME); move them to + # lib/ so the package layout is include/ + lib/ on all platforms. + if [ -d "$DIST_DIR/bin" ]; then + find "$DIST_DIR/bin" -name '*.dll' -exec mv {} "$DIST_DIR/lib/" \; + rm -rf "${DIST_DIR:?}/bin" + fi + + - name: Package SDK (Unix) + if: runner.os != 'Windows' + shell: bash + run: | + tar czf "zvec-sdk-${{ matrix.os_name }}-${{ matrix.arch }}.${{ matrix.ext }}" -C "$DIST_DIR" . + ls -lh "zvec-sdk-${{ matrix.os_name }}-${{ matrix.arch }}.${{ matrix.ext }}" + + - name: Package SDK (Windows) + if: runner.os == 'Windows' + shell: powershell + run: | + $Pkg = "zvec-sdk-${{ matrix.os_name }}-${{ matrix.arch }}.${{ matrix.ext }}" + Compress-Archive -Path "$env:DIST_DIR\*" -DestinationPath "$Pkg" -Force + Get-ChildItem "$Pkg" | Select-Object Name, Length + + - name: Upload artifact + uses: actions/upload-artifact@v7 + with: + name: zvec-sdk-${{ matrix.os_name }}-${{ matrix.arch }} + path: zvec-sdk-${{ matrix.os_name }}-${{ matrix.arch }}.${{ matrix.ext }} + if-no-files-found: error + retention-days: 7 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..0bd08348d --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,83 @@ +name: Release + +on: + push: + tags: + - 'v*' + workflow_dispatch: + inputs: + tag: + description: 'Release tag (e.g., v0.3.0)' + required: true + type: string + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + # Step 1: Build prebuilt libraries for all platforms + build-prebuilt: + name: Build Prebuilt Libraries + uses: ./.github/workflows/_build_prebuilt.yml + + # Step 2: Create release and upload prebuilt libraries + release: + name: Create Release + needs: build-prebuilt + runs-on: ubuntu-24.04 + permissions: + contents: write + + steps: + - name: Checkout code + uses: actions/checkout@v7 + with: + ref: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.ref }} + submodules: recursive + fetch-tags: true + fetch-depth: 0 + + - name: Extract version from tag + id: version + shell: bash + run: | + if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then + RAW_TAG="${{ inputs.tag }}" + else + RAW_TAG="${GITHUB_REF#refs/tags/}" + fi + VERSION="${RAW_TAG#v}" + echo "version=$VERSION" >> "$GITHUB_OUTPUT" + echo "tag=$RAW_TAG" >> "$GITHUB_OUTPUT" + echo "Releasing version: $VERSION (tag: $RAW_TAG)" + + - name: Download all prebuilt artifacts + uses: actions/download-artifact@v8 + with: + path: prebuilt-artifacts/ + pattern: zvec-sdk-* + merge-multiple: false + + - name: List prebuilt artifacts + shell: bash + run: | + echo "Release assets:" + find prebuilt-artifacts/ -type f \( -name '*.tar.gz' -o -name '*.zip' \) | sort + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ steps.version.outputs.tag }} + name: ${{ steps.version.outputs.tag }} + generate_release_notes: true + draft: false + prerelease: ${{ contains(steps.version.outputs.tag, 'alpha') || contains(steps.version.outputs.tag, 'beta') || contains(steps.version.outputs.tag, 'rc') }} + files: | + prebuilt-artifacts/**/*.tar.gz + prebuilt-artifacts/**/*.zip + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 4ad697d66c6ceab821da35445277580b1038effb Mon Sep 17 00:00:00 2001 From: lc285652 Date: Mon, 27 Jul 2026 19:16:42 +0800 Subject: [PATCH 2/4] ci: remove concurrency group from reusable build workflow to fix deadlock When called via workflow_call, github.workflow resolves to the caller's name, making the reusable workflow compete with the caller for the same concurrency group and deadlocking the run. Concurrency is controlled by the caller (release.yml). --- .github/workflows/_build_prebuilt.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/_build_prebuilt.yml b/.github/workflows/_build_prebuilt.yml index 5dd9b57a6..d8efdc24e 100644 --- a/.github/workflows/_build_prebuilt.yml +++ b/.github/workflows/_build_prebuilt.yml @@ -7,10 +7,6 @@ on: permissions: contents: read -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - jobs: build: name: Build (${{ matrix.os_name }}-${{ matrix.arch }}) From bd77a264d1bbf85f5ba421caea7868409f54e744 Mon Sep 17 00:00:00 2001 From: lc285652 Date: Tue, 28 Jul 2026 10:03:55 +0800 Subject: [PATCH 3/4] ci: dump third-party ExternalProject logs on build failure --- .github/workflows/_build_prebuilt.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/_build_prebuilt.yml b/.github/workflows/_build_prebuilt.yml index d8efdc24e..2c6305f10 100644 --- a/.github/workflows/_build_prebuilt.yml +++ b/.github/workflows/_build_prebuilt.yml @@ -99,6 +99,15 @@ jobs: NPROC=$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 4) cmake --build build --target install --parallel "$NPROC" + - name: Dump third-party build logs on failure + if: failure() + shell: bash + run: | + find build -type f \( -name '*-configure-*.log' -o -name '*-build-*.log' -o -name '*-install-*.log' \) | while read -r f; do + echo "===== $f =====" + tail -80 "$f" + done + - name: Stage package contents shell: bash run: | From aacbdad74949f00e1ccd9153729100ed5f7d67b5 Mon Sep 17 00:00:00 2001 From: lc285652 Date: Tue, 28 Jul 2026 10:14:45 +0800 Subject: [PATCH 4/4] ci: rename INSTALL_DIR env var to avoid clobbering lz4 Makefile variable lz4's Makefile.inc defines 'INSTALL_DIR ?= install -d -m 755' as a command, which gets overridden by our INSTALL_DIR environment variable, breaking 'make install' on all Unix platforms. Prefix our env vars with ZVEC_. --- .github/workflows/_build_prebuilt.yml | 33 +++++++++++++++------------ 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/.github/workflows/_build_prebuilt.yml b/.github/workflows/_build_prebuilt.yml index 2c6305f10..28e0403dd 100644 --- a/.github/workflows/_build_prebuilt.yml +++ b/.github/workflows/_build_prebuilt.yml @@ -38,8 +38,11 @@ jobs: ext: zip env: - INSTALL_DIR: ${{ github.workspace }}/install - DIST_DIR: ${{ github.workspace }}/dist + # Prefixed with ZVEC_ to avoid clashing with Makefile conventions: + # lz4's Makefile.inc defines `INSTALL_DIR ?= install -d -m 755` which + # would be overridden by an INSTALL_DIR environment variable. + ZVEC_INSTALL_DIR: ${{ github.workspace }}/install + ZVEC_DIST_DIR: ${{ github.workspace }}/dist steps: - name: Checkout code @@ -84,7 +87,7 @@ jobs: run: | cmake -S . -B build -G Ninja \ -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_INSTALL_PREFIX="$INSTALL_DIR" \ + -DCMAKE_INSTALL_PREFIX="$ZVEC_INSTALL_DIR" \ -DBUILD_TOOLS=OFF \ -DBUILD_PYTHON_BINDINGS=OFF \ -DBUILD_C_BINDINGS=ON \ @@ -111,28 +114,28 @@ jobs: - name: Stage package contents shell: bash run: | - mkdir -p "$DIST_DIR" - cp -R "$INSTALL_DIR"/. "$DIST_DIR"/. + mkdir -p "$ZVEC_DIST_DIR" + cp -R "$ZVEC_INSTALL_DIR"/. "$ZVEC_DIST_DIR"/. # Ship shared libraries only: zvec static libs are not self-contained # (third-party deps like rocksdb/arrow/protobuf are not installed). # On Windows, keep DLL import libs (*_shared.lib, zvec_c_api.lib). - rm -f "$DIST_DIR"/lib/*.a - rm -f "$DIST_DIR"/lib/zvec.lib \ - "$DIST_DIR"/lib/zvec_core.lib \ - "$DIST_DIR"/lib/zvec_ailego.lib \ - "$DIST_DIR"/lib/zvec_turbo.lib + rm -f "$ZVEC_DIST_DIR"/lib/*.a + rm -f "$ZVEC_DIST_DIR"/lib/zvec.lib \ + "$ZVEC_DIST_DIR"/lib/zvec_core.lib \ + "$ZVEC_DIST_DIR"/lib/zvec_ailego.lib \ + "$ZVEC_DIST_DIR"/lib/zvec_turbo.lib # On Windows, DLLs are installed into bin/ (RUNTIME); move them to # lib/ so the package layout is include/ + lib/ on all platforms. - if [ -d "$DIST_DIR/bin" ]; then - find "$DIST_DIR/bin" -name '*.dll' -exec mv {} "$DIST_DIR/lib/" \; - rm -rf "${DIST_DIR:?}/bin" + if [ -d "$ZVEC_DIST_DIR/bin" ]; then + find "$ZVEC_DIST_DIR/bin" -name '*.dll' -exec mv {} "$ZVEC_DIST_DIR/lib/" \; + rm -rf "${ZVEC_DIST_DIR:?}/bin" fi - name: Package SDK (Unix) if: runner.os != 'Windows' shell: bash run: | - tar czf "zvec-sdk-${{ matrix.os_name }}-${{ matrix.arch }}.${{ matrix.ext }}" -C "$DIST_DIR" . + tar czf "zvec-sdk-${{ matrix.os_name }}-${{ matrix.arch }}.${{ matrix.ext }}" -C "$ZVEC_DIST_DIR" . ls -lh "zvec-sdk-${{ matrix.os_name }}-${{ matrix.arch }}.${{ matrix.ext }}" - name: Package SDK (Windows) @@ -140,7 +143,7 @@ jobs: shell: powershell run: | $Pkg = "zvec-sdk-${{ matrix.os_name }}-${{ matrix.arch }}.${{ matrix.ext }}" - Compress-Archive -Path "$env:DIST_DIR\*" -DestinationPath "$Pkg" -Force + Compress-Archive -Path "$env:ZVEC_DIST_DIR\*" -DestinationPath "$Pkg" -Force Get-ChildItem "$Pkg" | Select-Object Name, Length - name: Upload artifact