Publish Nightly #69
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
| name: Publish Nightly | |
| # Manual builds of `pie` for distribution. Each run rewrites the | |
| # `nightly` rolling pre-release on this repo's GitHub Releases — | |
| # every artifact is uploaded with `gh release upload --clobber`, so | |
| # download URLs stay stable across runs. | |
| # | |
| # The prepare-release job creates the release if needed before any | |
| # matrix jobs start uploading assets. | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| tag: | |
| description: "Release tag to update (assets uploaded with --clobber)" | |
| type: string | |
| default: "nightly" | |
| portable: | |
| description: "Build portable matrix (Linux x86_64/aarch64 Vulkan + macOS arm64 Metal + Windows x86_64 Vulkan/CUDA)" | |
| type: boolean | |
| default: true | |
| cuda_manylinux: | |
| description: "Build the per-compute-capability CUDA matrix (manylinux_2_28, glibc 2.28; the CUDA release path)" | |
| type: boolean | |
| default: true | |
| permissions: | |
| contents: write # needed for `gh release upload` | |
| env: | |
| # Release notes body — keeps the release page in sync with the | |
| # latest workflow run. | |
| RELEASE_NOTES: | | |
| Rolling build from commit ${{ github.sha }} on ${{ github.ref_name }}. | |
| Workflow: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} | |
| jobs: | |
| # ========================================================================= | |
| # Create/update the rolling release before any matrix job tries to upload. | |
| # This keeps `gh release upload` from racing a missing release, and keeps | |
| # the rolling build out of GitHub's "Latest" release slot. | |
| # ========================================================================= | |
| prepare-release: | |
| if: inputs.portable || inputs.cuda_manylinux | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Ensure rolling release exists | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| TAG: ${{ inputs.tag }} | |
| run: | | |
| set -euxo pipefail | |
| if gh release view "${TAG}" --repo "${GITHUB_REPOSITORY}" >/dev/null 2>&1; then | |
| release_id="$(gh release view "${TAG}" --json databaseId --jq .databaseId --repo "${GITHUB_REPOSITORY}")" | |
| gh api \ | |
| -X PATCH \ | |
| "repos/${GITHUB_REPOSITORY}/releases/${release_id}" \ | |
| -f tag_name="${TAG}" \ | |
| -f name="${TAG}" \ | |
| -f body="${RELEASE_NOTES}" \ | |
| -F draft=false \ | |
| -F prerelease=true \ | |
| -f make_latest=false | |
| else | |
| gh release create "${TAG}" \ | |
| --repo "${GITHUB_REPOSITORY}" \ | |
| --target "${GITHUB_SHA}" \ | |
| --title "${TAG}" \ | |
| --notes "${RELEASE_NOTES}" \ | |
| --prerelease \ | |
| --latest=false | |
| fi | |
| # ========================================================================= | |
| # Portable matrix — Linux/Windows Vulkan, macOS Metal, plus Windows | |
| # portable CUDA. Runs on the larger org runners wherever they exist. | |
| # ========================================================================= | |
| portable: | |
| if: inputs.portable | |
| needs: prepare-release | |
| name: portable / ${{ matrix.target.label }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| target: | |
| # Linux portable artifacts ship the Vulkan ggml backend (works on | |
| # NVIDIA/AMD/Intel GPUs). Built directly on the larger Ubuntu | |
| # runners — NOT in a manylinux container — because ggml-vulkan | |
| # hard-requires `glslc` (find_package(Vulkan COMPONENTS glslc)), | |
| # which Rocky 8 / manylinux_2_28 doesn't package but Ubuntu 24.04+ | |
| # does. glibc floor is therefore the runner's Ubuntu (>= 2.39), | |
| # acceptable for a GPU artifact. | |
| - label: x86_64-linux-vulkan | |
| runner: ubuntu-large-x64 | |
| container: "" | |
| platform: linux | |
| triple: x86_64-unknown-linux-gnu | |
| archive: tar.gz | |
| backend: vulkan | |
| backend_env: "PIE_PORTABLE_VULKAN=1" | |
| - label: aarch64-linux-vulkan | |
| runner: ubuntu-large-arm64 | |
| container: "" | |
| platform: linux | |
| triple: aarch64-unknown-linux-gnu | |
| archive: tar.gz | |
| backend: vulkan | |
| backend_env: "PIE_PORTABLE_VULKAN=1" | |
| - label: aarch64-macos-metal | |
| # macos-15 gets Xcode 16 with libc++ 17, which has | |
| # `std::atomic_ref` (C++20). macos-14's Xcode 15.4 ships | |
| # libc++ 15, which doesn't. | |
| runner: macos-15 | |
| container: "" | |
| platform: macos | |
| triple: aarch64-apple-darwin | |
| archive: tar.gz | |
| backend: metal | |
| backend_env: "PIE_PORTABLE_METAL=1" | |
| - label: x86_64-windows-vulkan | |
| runner: windows-large-x64 | |
| container: "" | |
| platform: windows | |
| triple: x86_64-pc-windows-msvc | |
| archive: zip | |
| backend: vulkan | |
| backend_env: "PIE_PORTABLE_VULKAN=1" | |
| - label: x86_64-windows-cuda | |
| runner: windows-large-x64 | |
| container: "" | |
| platform: windows | |
| triple: x86_64-pc-windows-msvc | |
| archive: zip | |
| backend: cuda | |
| backend_env: "PIE_PORTABLE_CUDA=1" | |
| # ggml-cuda compiles many template instances slowly with nvcc. | |
| # Build one real+PTX arch; the PTX keeps the artifact | |
| # forward-JIT-able on newer NVIDIA GPUs. | |
| cuda_arch: "75" | |
| runs-on: ${{ matrix.target.runner }} | |
| container: ${{ matrix.target.container || '' }} | |
| env: | |
| ARTIFACT_NAME: pie-${{ matrix.target.label }}.${{ matrix.target.archive }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| # manylinux containers ship gcc + cmake + ninja but no rust. | |
| # We dnf-install: | |
| # - `openssl-devel` + `pkg-config`: for `openssl-sys` (reqwest's | |
| # default features). | |
| # - `perl`: openssl-sys build script's vendored fallback. | |
| # - `gcc-toolset-14-gcc(-c++)`: needed for libstdc++ 14, which | |
| # ships <span> and other C++20 headers driver/portable's | |
| # source uses. The container's stock gcc-8 / libstdc++-8 | |
| # is missing them. | |
| # | |
| # Then we pin CC/CXX explicitly to the toolset's binaries — | |
| # without that, cmake-rs picks `/opt/clang/bin/cc` (also on | |
| # PATH inside the manylinux image) and we lose the libstdc++ 14 | |
| # come link time. | |
| - name: Install build deps + rustup (manylinux only) | |
| if: startsWith(matrix.target.container, 'quay.io/pypa/manylinux') | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| dnf install -y --setopt=install_weak_deps=False \ | |
| openssl-devel pkg-config perl git \ | |
| gcc-toolset-14-gcc gcc-toolset-14-gcc-c++ | |
| # GitHub CLI — used by the upload step. The manylinux image | |
| # doesn't ship `gh` and the upload step's --clobber flow has | |
| # no clean curl equivalent. `gh` rpm depends on `git`, | |
| # installed above. | |
| dnf install -y 'dnf-command(config-manager)' | |
| dnf config-manager --add-repo \ | |
| https://cli.github.com/packages/rpm/gh-cli.repo | |
| dnf install -y gh --repo gh-cli | |
| # Pin compiler explicitly. cmake-rs (via cc-rs) reads | |
| # CC/CXX, so this forces CMake to use gcc-toolset-14 even | |
| # though manylinux's `/opt/clang/bin` is also on PATH and | |
| # would otherwise be picked. We need libstdc++ 14 for the | |
| # C++20 headers (`<span>`) the portable driver source uses. | |
| { | |
| echo "CC=/opt/rh/gcc-toolset-14/root/usr/bin/gcc" | |
| echo "CXX=/opt/rh/gcc-toolset-14/root/usr/bin/g++" | |
| echo "AR=/opt/rh/gcc-toolset-14/root/usr/bin/ar" | |
| echo "PATH=/opt/rh/gcc-toolset-14/root/usr/bin:${PATH}" | |
| echo "MANPATH=/opt/rh/gcc-toolset-14/root/usr/share/man:" | |
| echo "LD_LIBRARY_PATH=/opt/rh/gcc-toolset-14/root/usr/lib64:/opt/rh/gcc-toolset-14/root/usr/lib" | |
| echo "PKG_CONFIG_PATH=/opt/rh/gcc-toolset-14/root/usr/lib64/pkgconfig" | |
| } >> "$GITHUB_ENV" | |
| curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \ | |
| sh -s -- -y --profile minimal --default-toolchain stable | |
| echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" | |
| - name: Install Rust (non-container runners) | |
| if: matrix.target.container == '' | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: ${{ matrix.target.triple }} | |
| - name: Install Vulkan toolchain + build deps (linux only) | |
| if: matrix.target.platform == 'linux' && matrix.target.backend == 'vulkan' | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| # No manylinux container on this leg: ggml-vulkan hard-requires | |
| # `glslc` (find_package(Vulkan COMPONENTS glslc REQUIRED)), which | |
| # Rocky 8 / manylinux_2_28 doesn't package but Ubuntu 24.04+ does. | |
| # Install the Vulkan headers/loader/compiler plus the C/C++ build | |
| # toolchain that the cmake-rs driver build and openssl-sys need. | |
| export DEBIAN_FRONTEND=noninteractive | |
| sudo apt-get update | |
| # spirv-headers provides <spirv/unified1/spirv.hpp> (namespace spv), | |
| # which ggml-vulkan.cpp includes for SPIR-V reflection — not pulled | |
| # in by libvulkan-dev/glslc alone. | |
| sudo apt-get install -y --no-install-recommends \ | |
| build-essential cmake ninja-build pkg-config \ | |
| glslc libvulkan-dev spirv-headers libssl-dev | |
| glslc --version | |
| - name: Install Vulkan SDK (windows only) | |
| id: vulkan_sdk | |
| if: matrix.target.platform == 'windows' && matrix.target.backend == 'vulkan' | |
| # node24 action that installs the full SDK (headers + import libs). | |
| # Replaces humbletim/install-vulkan-sdk (node20 + a transitive | |
| # actions/cache@v4) which warns under the Node-20 deprecation. | |
| uses: jakoch/install-vulkan-sdk-action@v1.5.5 | |
| with: | |
| cache: true | |
| - name: Export VULKAN_SDK (windows only) | |
| if: matrix.target.platform == 'windows' && matrix.target.backend == 'vulkan' | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| # cmake-rs / build.rs read the VULKAN_SDK env var; surface jakoch's | |
| # output to the environment and sanity-check the files ggml needs. | |
| echo "VULKAN_SDK=${{ steps.vulkan_sdk.outputs.VULKAN_SDK }}" >> "$GITHUB_ENV" | |
| test -f "${{ steps.vulkan_sdk.outputs.VULKAN_SDK }}/Include/vulkan/vulkan.h" | |
| test -f "${{ steps.vulkan_sdk.outputs.VULKAN_SDK }}/Lib/vulkan-1.lib" | |
| - name: Install CUDA toolkit (windows portable cuda only) | |
| if: matrix.target.platform == 'windows' && matrix.target.backend == 'cuda' | |
| uses: Jimver/cuda-toolkit@v0.2.35 | |
| with: | |
| cuda: '12.9.1' | |
| - name: Verify CUDA toolkit (windows portable cuda only) | |
| if: matrix.target.platform == 'windows' && matrix.target.backend == 'cuda' | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| nvcc --version | |
| test -n "${CUDA_PATH:-${CUDA_HOME:-}}" | |
| - name: Set up MSVC environment (windows cuda only) | |
| # ggml-cuda's enable_language(CUDA) under CMake's Visual Studio | |
| # generator needs the CUDA MSBuild toolset integration, which the | |
| # toolkit installer doesn't reliably register on the hosted image | |
| # ("No CUDA toolset found"). We build with the Ninja generator | |
| # instead (set in the cargo step); sourcing the MSVC dev environment | |
| # here puts cl.exe on PATH so nvcc/CMake can use it as host compiler. | |
| if: matrix.target.platform == 'windows' && matrix.target.backend == 'cuda' | |
| # node24 equivalent of ilammy/msvc-dev-cmd (which is node20-only and | |
| # warns under the Node-20 deprecation). Sets up vcvars so cl.exe is on | |
| # PATH for the Ninja CUDA build. | |
| uses: TheMrMilchmann/setup-msvc-dev@v4.0.0 | |
| with: | |
| arch: x64 | |
| - name: Cache cargo | |
| uses: actions/cache@v5 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| target | |
| key: build-${{ matrix.target.label }}-${{ hashFiles('**/Cargo.lock') }} | |
| restore-keys: build-${{ matrix.target.label }}- | |
| - name: cargo build (release-min) | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| if [ -n "${{ matrix.target.backend_env }}" ]; then | |
| export ${{ matrix.target.backend_env }} | |
| fi | |
| if [[ "${{ matrix.target.backend }}" == "cuda" ]]; then | |
| export PIE_PORTABLE_CUDA_ARCH='${{ matrix.target.cuda_arch }}' | |
| fi | |
| if [[ "${{ matrix.target.platform }}" == "windows" ]]; then | |
| # ggml-vulkan nests a shader-generator CMake build under Cargo's | |
| # OUT_DIR, and ggml-cuda produces many long object paths. Keep the | |
| # target root short enough for the legacy 260-character path limit | |
| # on Windows, and isolate backend flavors from each other. | |
| export CARGO_TARGET_DIR="C:/t/pie-${{ matrix.target.backend }}" | |
| # 32-core windows-large runner: parallelize the native ggml build | |
| # fully (was capped at 4 for the old small hosted runners). | |
| export CMAKE_BUILD_PARALLEL_LEVEL="$(nproc 2>/dev/null || echo 8)" | |
| if [[ "${{ matrix.target.backend }}" == "cuda" ]]; then | |
| # Drive nvcc via Ninja — the VS generator can't find the CUDA | |
| # toolset on the hosted image. cl.exe is on PATH from the | |
| # preceding msvc-dev-cmd step. | |
| export CMAKE_GENERATOR=Ninja | |
| ninja --version | |
| # Git Bash ships /usr/bin/link.exe (GNU coreutils `link`), which | |
| # shadows MSVC's link.exe for rustc once msvc-dev-cmd activates the | |
| # MSVC env (rustc then resolves the linker via PATH and picks the | |
| # GNU one -> "extra operand" link errors). Drop it so `link` | |
| # resolves to MSVC's linker. (Only needed on the cuda leg, which is | |
| # the only one that runs msvc-dev-cmd.) | |
| rm -f /usr/bin/link /usr/bin/link.exe || true | |
| fi | |
| fi | |
| # `release-min`: thin LTO, panic=abort, strip=symbols. | |
| # Defined in workspace Cargo.toml. Smaller + faster than | |
| # plain `release` (no LTO at all by default), without fat | |
| # LTO's many-hour link cost. Distribution profile. | |
| cargo build --profile release-min \ | |
| --target ${{ matrix.target.triple }} \ | |
| -p pie-server \ | |
| --features driver-portable,driver-dummy | |
| - name: Package | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| mkdir -p dist | |
| TARGET_ROOT="target" | |
| if [[ "${{ matrix.target.platform }}" == "windows" ]]; then | |
| TARGET_ROOT="C:/t/pie-${{ matrix.target.backend }}" | |
| fi | |
| BIN_DIR="${TARGET_ROOT}/${{ matrix.target.triple }}/release-min" | |
| if [[ "${{ matrix.target.archive }}" == "zip" ]]; then | |
| # Windows .exe; 7z preinstalled on windows-latest. | |
| 7z a "dist/${ARTIFACT_NAME}" "${BIN_DIR}/pie.exe" | |
| else | |
| tar -C "${BIN_DIR}" -czf "dist/${ARTIFACT_NAME}" pie | |
| fi | |
| ls -la dist/ | |
| - name: Upload to release (--clobber) | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| # Many matrix legs --clobber the same rolling release concurrently; | |
| # GitHub's asset API intermittently 5xx/422s under that contention. | |
| # Retry a few times before failing the leg. | |
| for attempt in 1 2 3 4 5; do | |
| if gh release upload "${{ inputs.tag }}" "dist/${ARTIFACT_NAME}" --clobber --repo "${{ github.repository }}"; then | |
| exit 0 | |
| fi | |
| echo "upload attempt ${attempt} failed; retrying in $((attempt * 10))s" >&2 | |
| sleep $((attempt * 10)) | |
| done | |
| echo "upload failed after retries" >&2 | |
| exit 1 | |
| # ========================================================================= | |
| # Per-compute-capability CUDA matrix on GH-hosted larger runners with a | |
| # manylinux_2_28 base — binaries with a glibc 2.28 floor (RHEL 8 / Ubuntu | |
| # 20.04 / Debian 11). | |
| # | |
| # Matrix = compute-capability × CUDA-version × os-arch; each leg builds a | |
| # SINGLE SM, so the build parallelizes (wall-clock ~= one arch, not a | |
| # 6-arch fatbin) and each binary is small. The installer detects the GPU's | |
| # compute capability and picks the matching asset. Built inside | |
| # nvidia/cuda:X.Y-devel-rockylinux8 containers on ubuntu-large-{x64,arm64}. | |
| # Opt-in via the `cuda_manylinux` workflow input. | |
| # ========================================================================= | |
| cuda-manylinux: | |
| if: inputs.cuda_manylinux | |
| needs: prepare-release | |
| name: cuda / ${{ matrix.target.os_arch }}-sm${{ matrix.target.cc }} / cuda-${{ matrix.cuda.short }} | |
| runs-on: ${{ matrix.target.runner }} | |
| # One compute-capability per job (not a 6-arch fatbin), so each leg is | |
| # quick and the legs run in parallel across the larger runners. Keep a | |
| # generous net for cold caches. | |
| timeout-minutes: 120 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| # Per-compute-capability: CC × CUDA-version × os-arch. Each entry | |
| # builds ONE arch. The installer detects the GPU's compute capability | |
| # (nvidia-smi, or the PIE_CC override) and picks the matching asset. | |
| cuda: | |
| - { version: "12.8.1", short: "12.8" } | |
| - { version: "13.0.0", short: "13.0" } | |
| target: | |
| # x86_64: Ampere (80/86), Ada (89), Hopper (90), Blackwell DC (100) + consumer (120). | |
| - { os_arch: x86_64, cc: "80", runner: ubuntu-large-x64, triple: x86_64-unknown-linux-gnu } | |
| - { os_arch: x86_64, cc: "86", runner: ubuntu-large-x64, triple: x86_64-unknown-linux-gnu } | |
| - { os_arch: x86_64, cc: "89", runner: ubuntu-large-x64, triple: x86_64-unknown-linux-gnu } | |
| - { os_arch: x86_64, cc: "90", runner: ubuntu-large-x64, triple: x86_64-unknown-linux-gnu } | |
| - { os_arch: x86_64, cc: "100", runner: ubuntu-large-x64, triple: x86_64-unknown-linux-gnu } | |
| - { os_arch: x86_64, cc: "120", runner: ubuntu-large-x64, triple: x86_64-unknown-linux-gnu } | |
| # aarch64: Grace-Hopper (90), Grace-Blackwell (100). | |
| - { os_arch: aarch64, cc: "90", runner: ubuntu-large-arm64, triple: aarch64-unknown-linux-gnu } | |
| - { os_arch: aarch64, cc: "100", runner: ubuntu-large-arm64, triple: aarch64-unknown-linux-gnu } | |
| exclude: | |
| # Blackwell consumer (RTX 50) shipped in the CUDA-13/driver-580 era — | |
| # no one pairs sm120 with a CUDA 12.8 runtime. | |
| - cuda: { version: "12.8.1", short: "12.8" } | |
| target: { os_arch: x86_64, cc: "120", runner: ubuntu-large-x64, triple: x86_64-unknown-linux-gnu } | |
| # Grace-Blackwell (GB200) is a 2025/CUDA-13 platform — the | |
| # arm64 × Blackwell × CUDA-12.8 intersection is empty. | |
| - cuda: { version: "12.8.1", short: "12.8" } | |
| target: { os_arch: aarch64, cc: "100", runner: ubuntu-large-arm64, triple: aarch64-unknown-linux-gnu } | |
| container: nvidia/cuda:${{ matrix.cuda.version }}-devel-rockylinux8 | |
| env: | |
| ARTIFACT_NAME: pie-${{ matrix.target.os_arch }}-linux-cuda${{ matrix.cuda.short }}-sm${{ matrix.target.cc }}.tar.gz | |
| PIE_PORTABLE_CUDA: "1" | |
| PIE_PORTABLE_CUDA_ARCH: ${{ matrix.target.cc }} | |
| CMAKE_CUDA_ARCHITECTURES: ${{ matrix.target.cc }} | |
| CMAKE_CUDA_RUNTIME_LIBRARY: Shared | |
| CARGO_INCREMENTAL: "0" | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Bootstrap container | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| # `ninja-build` lives in the PowerTools repo on Rocky 8; | |
| # EPEL covers extras. `patch` for the vendored llama.cpp | |
| # patches; `git` for CPM's git fetches. NCCL ships in | |
| # NVIDIA's cuda repo (already configured by the base image) | |
| # as `libnccl-devel`; pulls `libnccl` runtime in via deps. | |
| dnf install -y epel-release dnf-plugins-core | |
| dnf config-manager --set-enabled powertools | |
| dnf install -y --setopt=install_weak_deps=False \ | |
| openssl-devel pkg-config perl git patch \ | |
| cmake ninja-build \ | |
| gcc-toolset-12-gcc gcc-toolset-12-gcc-c++ \ | |
| libnccl libnccl-devel | |
| # Pin compiler explicitly: `source enable` only adjusts PATH — | |
| # cmake-rs probes CC/CXX env vars and otherwise picks | |
| # `/usr/bin/cc` (gcc-8.5, no <span> / C++20). Same nvcc | |
| # host-compiler issue applies via CUDAHOSTCXX (nvcc | |
| # auto-picks gcc-8.5 and silently drops `-std=c++20`). | |
| { | |
| echo "CC=/opt/rh/gcc-toolset-12/root/usr/bin/gcc" | |
| echo "CXX=/opt/rh/gcc-toolset-12/root/usr/bin/g++" | |
| echo "AR=/opt/rh/gcc-toolset-12/root/usr/bin/ar" | |
| echo "CUDAHOSTCXX=/opt/rh/gcc-toolset-12/root/usr/bin/g++" | |
| echo "PATH=/opt/rh/gcc-toolset-12/root/usr/bin:${PATH}" | |
| echo "LD_LIBRARY_PATH=/opt/rh/gcc-toolset-12/root/usr/lib64:/opt/rh/gcc-toolset-12/root/usr/lib" | |
| echo "PKG_CONFIG_PATH=/opt/rh/gcc-toolset-12/root/usr/lib64/pkgconfig" | |
| # rustc's final link must go through the gcc-toolset-12 gcc driver | |
| # so libstdc++_nonshared.a is pulled in for the C++17/20 libstdc++ | |
| # symbols (std::filesystem, std::__throw_bad_array_new_length) the | |
| # C++ drivers use. The stock /usr/bin/cc (gcc-8.5) links the old | |
| # system libstdc++ and fails the link with undefined symbols. | |
| # The linker env var is per-target-triple; derive its name from the | |
| # triple so this one bootstrap works for both x86_64 and aarch64. | |
| echo "CARGO_TARGET_$(echo '${{ matrix.target.triple }}' | tr 'a-z-' 'A-Z_')_LINKER=/opt/rh/gcc-toolset-12/root/usr/bin/gcc" | |
| } >> "$GITHUB_ENV" | |
| curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \ | |
| sh -s -- -y --profile minimal --default-toolchain stable | |
| echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" | |
| - name: Cache cargo | |
| uses: actions/cache@v5 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| target | |
| key: build-cuda-${{ matrix.target.os_arch }}-sm${{ matrix.target.cc }}-${{ matrix.cuda.short }}-${{ hashFiles('**/Cargo.lock') }} | |
| restore-keys: build-cuda-${{ matrix.target.os_arch }}-sm${{ matrix.target.cc }}-${{ matrix.cuda.short }}- | |
| - name: cargo build (release-min) | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| # `release-min`: thin LTO, panic=abort, strip=symbols. | |
| # Defined in workspace Cargo.toml. | |
| cargo build --profile release-min \ | |
| --target ${{ matrix.target.triple }} \ | |
| -p pie-server \ | |
| --features driver-portable,driver-cuda,driver-dummy | |
| - name: Package | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| mkdir -p dist | |
| BIN_DIR="target/${{ matrix.target.triple }}/release-min" | |
| tar -C "${BIN_DIR}" -czf "dist/${ARTIFACT_NAME}" pie | |
| ls -la dist/ | |
| - name: Upload to release | |
| uses: softprops/action-gh-release@v3 | |
| with: | |
| tag_name: ${{ inputs.tag }} | |
| files: dist/${{ env.ARTIFACT_NAME }} | |
| fail_on_unmatched_files: true | |
| make_latest: false | |
| # ========================================================================= | |
| # Refresh the release notes once after all builds finish. | |
| # ========================================================================= | |
| refresh-notes: | |
| if: always() && (inputs.portable || inputs.cuda_manylinux) | |
| needs: [portable, cuda-manylinux] | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Edit release notes + body | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| TAG: ${{ inputs.tag }} | |
| run: | | |
| set -euxo pipefail | |
| release_id="$(gh release view "${TAG}" --json databaseId --jq .databaseId --repo "${GITHUB_REPOSITORY}")" | |
| gh api \ | |
| -X PATCH \ | |
| "repos/${GITHUB_REPOSITORY}/releases/${release_id}" \ | |
| -f tag_name="${TAG}" \ | |
| -f name="${TAG}" \ | |
| -f body="${RELEASE_NOTES}" \ | |
| -F draft=false \ | |
| -F prerelease=true \ | |
| -f make_latest=false |