diff --git a/.github/workflows/_build_prebuilt.yml b/.github/workflows/_build_prebuilt.yml new file mode 100644 index 000000000..28e0403dd --- /dev/null +++ b/.github/workflows/_build_prebuilt.yml @@ -0,0 +1,155 @@ +name: Build Prebuilt Libraries + +on: + workflow_dispatch: + workflow_call: + +permissions: + contents: read + +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: + # 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 + 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="$ZVEC_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: 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: | + 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 "$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 "$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 "$ZVEC_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:ZVEC_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 }}