Skip to content

ci: add rescue release workflow #44

ci: add rescue release workflow

ci: add rescue release workflow #44

Workflow file for this run

name: Build Packages
on:
push:
branches:
- main
- "v*"
tags:
- "v*"
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref_type == 'branch' }}
env:
CMAKE_ARGS: "-DLLAMA_BUILD_EXAMPLES=OFF -DLLAMA_BUILD_TESTS=OFF -DLLAMA_BUILD_TOOLS=ON -DLLAMA_BUILD_SERVER=ON -DGGML_RPC=ON"
jobs:
release-meta:
name: Package metadata
runs-on: ubuntu-24.04
outputs:
tag_name: ${{ steps.meta.outputs.tag_name }}
create_release: ${{ steps.meta.outputs.create_release }}
steps:
- name: Clone
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Resolve package metadata
id: meta
shell: bash
run: |
set -euo pipefail
short_sha="${GITHUB_SHA::12}"
ref_name_safe="${GITHUB_REF_NAME//\//-}"
exact_tag="$(git tag --points-at "${GITHUB_SHA}" --list 'v*' | sort -V | tail -n 1 || true)"
create_release="false"
if [[ "${GITHUB_REF}" == refs/tags/v* ]]; then
tag_name="${GITHUB_REF_NAME}"
elif [[ "${GITHUB_REF}" == "refs/heads/main" && -n "${exact_tag}" ]]; then
tag_name="${exact_tag}"
else
tag_name="${ref_name_safe}-${short_sha}"
fi
if [[ "${GITHUB_EVENT_NAME}" == "push" ]]; then
git fetch origin +refs/heads/main:refs/remotes/origin/main --no-tags
if [[ "${GITHUB_REF}" == refs/tags/v* ]]; then
if git merge-base --is-ancestor "${GITHUB_SHA}" refs/remotes/origin/main; then
create_release="true"
else
echo "Tag ${GITHUB_REF_NAME} is not on origin/main; building packages without publishing a release."
fi
elif [[ "${GITHUB_REF}" == "refs/heads/main" && -n "${exact_tag}" ]]; then
create_release="true"
fi
fi
echo "tag_name=${tag_name}" >> "${GITHUB_OUTPUT}"
echo "create_release=${create_release}" >> "${GITHUB_OUTPUT}"
echo "Using package version: ${tag_name}"
echo "Publish GitHub release: ${create_release}"
macos-arm64:
name: macOS arm64 Metal
needs: release-meta
runs-on: macos-14
steps:
- name: Clone
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: "24"
cache: "npm"
cache-dependency-path: "tools/ui/package-lock.json"
- name: ccache
uses: ggml-org/ccache-action@v1.2.21
with:
key: release-macos-arm64
evict-old-files: 1d
- name: Build
run: |
cmake -B build \
-DCMAKE_BUILD_TYPE=Release \
-DGGML_METAL_USE_BF16=ON \
-DGGML_METAL_EMBED_LIBRARY=ON \
-DCMAKE_INSTALL_RPATH='@loader_path' \
-DCMAKE_BUILD_WITH_INSTALL_RPATH=ON \
-DLLAMA_FATAL_WARNINGS=ON \
-DLLAMA_BUILD_BORINGSSL=ON \
${{ env.CMAKE_ARGS }}
cmake --build build --config Release -j "$(sysctl -n hw.logicalcpu)"
- name: ccache stats
if: always()
run: ccache --show-stats
- name: Pack artifacts
run: |
cp LICENSE ./build/bin/
tar -czvf "beellama-${{ needs.release-meta.outputs.tag_name }}-bin-macos-arm64.tar.gz" \
-s ",^\.,beellama-${{ needs.release-meta.outputs.tag_name }}," \
-C ./build/bin .
- name: Upload artifacts
uses: actions/upload-artifact@v6
with:
path: beellama-${{ needs.release-meta.outputs.tag_name }}-bin-macos-arm64.tar.gz
name: beellama-bin-macos-arm64.tar.gz
ubuntu-cpu:
name: Ubuntu x64 CPU
needs: release-meta
runs-on: ubuntu-22.04
steps:
- name: Clone
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: "24"
cache: "npm"
cache-dependency-path: "tools/ui/package-lock.json"
- name: ccache
uses: ggml-org/ccache-action@v1.2.21
with:
key: release-ubuntu-cpu-x64
evict-old-files: 1d
- name: Dependencies
run: |
sudo apt-get update
sudo apt-get install -y build-essential libssl-dev
- name: Build
run: |
cmake -B build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_RPATH='$ORIGIN' \
-DCMAKE_BUILD_WITH_INSTALL_RPATH=ON \
-DGGML_BACKEND_DL=ON \
-DGGML_NATIVE=OFF \
-DGGML_CPU_ALL_VARIANTS=ON \
-DLLAMA_FATAL_WARNINGS=ON \
${{ env.CMAKE_ARGS }}
cmake --build build --config Release -j "$(nproc)"
- name: ccache stats
if: always()
run: ccache --show-stats
- name: Pack artifacts
run: |
cp LICENSE ./build/bin/
tar -czvf "beellama-${{ needs.release-meta.outputs.tag_name }}-bin-ubuntu-x64.tar.gz" \
--transform "s,^\.,beellama-${{ needs.release-meta.outputs.tag_name }}," \
-C ./build/bin .
- name: Upload artifacts
uses: actions/upload-artifact@v6
with:
path: beellama-${{ needs.release-meta.outputs.tag_name }}-bin-ubuntu-x64.tar.gz
name: beellama-bin-ubuntu-x64.tar.gz
ubuntu-vulkan:
name: Ubuntu x64 Vulkan
needs: release-meta
runs-on: ubuntu-22.04
steps:
- name: Clone
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: "24"
cache: "npm"
cache-dependency-path: "tools/ui/package-lock.json"
- name: ccache
uses: ggml-org/ccache-action@v1.2.21
with:
key: release-ubuntu-vulkan-x64
evict-old-files: 1d
- name: Dependencies
run: |
wget -qO - https://packages.lunarg.com/lunarg-signing-key-pub.asc | sudo apt-key add -
sudo wget -qO /etc/apt/sources.list.d/lunarg-vulkan-jammy.list https://packages.lunarg.com/vulkan/lunarg-vulkan-jammy.list
sudo apt-get update -y
sudo apt-get install -y build-essential mesa-vulkan-drivers vulkan-sdk libssl-dev
- name: Build
run: |
cmake -B build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_RPATH='$ORIGIN' \
-DCMAKE_BUILD_WITH_INSTALL_RPATH=ON \
-DGGML_BACKEND_DL=ON \
-DGGML_NATIVE=OFF \
-DGGML_CPU_ALL_VARIANTS=ON \
-DGGML_VULKAN=ON \
-DLLAMA_FATAL_WARNINGS=ON \
${{ env.CMAKE_ARGS }}
cmake --build build --config Release -j "$(nproc)"
- name: ccache stats
if: always()
run: ccache --show-stats
- name: Pack artifacts
run: |
cp LICENSE ./build/bin/
tar -czvf "beellama-${{ needs.release-meta.outputs.tag_name }}-bin-ubuntu-vulkan-x64.tar.gz" \
--transform "s,^\.,beellama-${{ needs.release-meta.outputs.tag_name }}," \
-C ./build/bin .
- name: Upload artifacts
uses: actions/upload-artifact@v6
with:
path: beellama-${{ needs.release-meta.outputs.tag_name }}-bin-ubuntu-vulkan-x64.tar.gz
name: beellama-bin-ubuntu-vulkan-x64.tar.gz
ubuntu-rocm:
name: Ubuntu x64 ROCm
needs: release-meta
runs-on: ubuntu-22.04
env:
ROCM_VERSION: "7.2.1"
GPU_TARGETS: "gfx908;gfx90a;gfx942;gfx1030;gfx1100;gfx1101;gfx1102;gfx1151;gfx1150;gfx1200;gfx1201"
steps:
- name: Clone
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: "24"
cache: "npm"
cache-dependency-path: "tools/ui/package-lock.json"
- name: Free up disk space
uses: ggml-org/free-disk-space@v1.3.1
with:
tool-cache: true
- name: ccache
uses: ggml-org/ccache-action@v1.2.21
with:
key: release-ubuntu-rocm-${{ env.ROCM_VERSION }}-x64
evict-old-files: 1d
- name: Dependencies
run: |
sudo apt-get update
sudo apt-get install -y build-essential git cmake wget libssl-dev
- name: Setup ROCm
run: |
sudo mkdir --parents --mode=0755 /etc/apt/keyrings
wget https://repo.radeon.com/rocm/rocm.gpg.key -O - | \
gpg --dearmor | sudo tee /etc/apt/keyrings/rocm.gpg > /dev/null
sudo tee /etc/apt/sources.list.d/rocm.list << EOF
deb [arch=amd64 signed-by=/etc/apt/keyrings/rocm.gpg] https://repo.radeon.com/rocm/apt/${ROCM_VERSION} jammy main
EOF
sudo tee /etc/apt/preferences.d/rocm-pin-600 << EOF
Package: *
Pin: release o=repo.radeon.com
Pin-Priority: 600
EOF
sudo apt-get update
sudo apt-get install -y rocm-hip-sdk
- name: Build
run: |
cmake -B build -S . \
-DCMAKE_HIP_COMPILER="$(hipconfig -l)/clang" \
-DCMAKE_BUILD_TYPE=Release \
-DGGML_BACKEND_DL=ON \
-DGGML_NATIVE=OFF \
-DCMAKE_INSTALL_RPATH='$ORIGIN' \
-DCMAKE_BUILD_WITH_INSTALL_RPATH=ON \
-DGGML_CPU_ALL_VARIANTS=ON \
-DGPU_TARGETS="${GPU_TARGETS}" \
-DGGML_HIP=ON \
-DHIP_PLATFORM=amd \
-DGGML_HIP_ROCWMMA_FATTN=ON \
${{ env.CMAKE_ARGS }}
cmake --build build --config Release -j "$(nproc)"
- name: ccache stats
if: always()
run: ccache --show-stats
- name: Pack artifacts
run: |
rocm_short="$(echo "${ROCM_VERSION}" | cut -d '.' -f 1,2)"
cp LICENSE ./build/bin/
tar -czvf "beellama-${{ needs.release-meta.outputs.tag_name }}-bin-ubuntu-rocm-${rocm_short}-x64.tar.gz" \
--transform "s,^\.,beellama-${{ needs.release-meta.outputs.tag_name }}," \
-C ./build/bin .
- name: Upload artifacts
uses: actions/upload-artifact@v6
with:
path: beellama-${{ needs.release-meta.outputs.tag_name }}-bin-ubuntu-rocm-7.2-x64.tar.gz
name: beellama-bin-ubuntu-rocm-7.2-x64.tar.gz
ubuntu-sycl:
name: Ubuntu x64 SYCL
needs: release-meta
runs-on: ubuntu-24.04
env:
ONEAPI_ROOT: /opt/intel/oneapi
ONEAPI_INSTALLER_VERSION: "2025.3.3"
ONEAPI_INSTALLER_URL: https://registrationcenter-download.intel.com/akdlm/IRC_NAS/56f7923a-adb8-43f3-8b02-2b60fcac8cab/intel-deep-learning-essentials-2025.3.3.16_offline.sh
LEVEL_ZERO_VERSION: "1.28.2"
LEVEL_ZERO_UBUNTU_VERSION: "u24.04"
steps:
- name: Clone
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: "24"
cache: "npm"
cache-dependency-path: "tools/ui/package-lock.json"
- name: Free up disk space
uses: ggml-org/free-disk-space@v1.3.1
with:
tool-cache: true
- name: Prepare oneAPI cache path
run: |
sudo mkdir -p "${ONEAPI_ROOT}"
sudo chown -R "${USER}:${USER}" /opt/intel
- name: Cache oneAPI installation
id: cache-oneapi
uses: actions/cache@v5
with:
path: ${{ env.ONEAPI_ROOT }}
key: oneapi-linux-${{ env.ONEAPI_INSTALLER_VERSION }}-${{ runner.os }}
- name: ccache
uses: ggml-org/ccache-action@v1.2.21
with:
key: release-ubuntu-sycl-${{ env.ONEAPI_INSTALLER_VERSION }}-x64
evict-old-files: 1d
- name: Dependencies
run: |
sudo apt-get update
sudo apt-get install -y build-essential git cmake ninja-build wget ca-certificates libssl-dev
- name: Install oneAPI
if: steps.cache-oneapi.outputs.cache-hit != 'true'
run: |
installer="${RUNNER_TEMP}/intel-deep-learning-essentials-${ONEAPI_INSTALLER_VERSION}.sh"
wget "${ONEAPI_INSTALLER_URL}" -O "${installer}"
sudo bash "${installer}" -s -a --silent --eula accept
sudo chown -R "${USER}:${USER}" "${ONEAPI_ROOT}"
- name: Install Level Zero SDK
run: |
cd /tmp
wget -q "https://github.com/oneapi-src/level-zero/releases/download/v${LEVEL_ZERO_VERSION}/level-zero_${LEVEL_ZERO_VERSION}%2B${LEVEL_ZERO_UBUNTU_VERSION}_amd64.deb" -O level-zero.deb
wget -q "https://github.com/oneapi-src/level-zero/releases/download/v${LEVEL_ZERO_VERSION}/level-zero-devel_${LEVEL_ZERO_VERSION}%2B${LEVEL_ZERO_UBUNTU_VERSION}_amd64.deb" -O level-zero-devel.deb
sudo apt-get -o Dpkg::Options::="--force-overwrite" install -y ./level-zero.deb ./level-zero-devel.deb
- name: Build
run: |
source "${ONEAPI_ROOT}/setvars.sh"
cmake -B build -G "Ninja" \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_RPATH='$ORIGIN' \
-DCMAKE_BUILD_WITH_INSTALL_RPATH=ON \
-DGGML_SYCL=ON \
-DGGML_SYCL_F16=OFF \
-DCMAKE_C_COMPILER=icx \
-DCMAKE_CXX_COMPILER=icpx \
-DGGML_BACKEND_DL=ON \
-DGGML_NATIVE=OFF \
-DGGML_CPU_ALL_VARIANTS=ON \
${{ env.CMAKE_ARGS }}
cmake --build build --config Release -j "$(nproc)"
- name: ccache stats
if: always()
run: ccache --show-stats
- name: Pack artifacts
run: |
cp LICENSE ./build/bin/
tar -czvf "beellama-${{ needs.release-meta.outputs.tag_name }}-bin-ubuntu-sycl-x64.tar.gz" \
--transform "s,^\.,beellama-${{ needs.release-meta.outputs.tag_name }}," \
-C ./build/bin .
- name: Upload artifacts
uses: actions/upload-artifact@v6
with:
path: beellama-${{ needs.release-meta.outputs.tag_name }}-bin-ubuntu-sycl-x64.tar.gz
name: beellama-bin-ubuntu-sycl-x64.tar.gz
windows-cpu:
name: Windows x64 CPU
needs: release-meta
runs-on: windows-2025
steps:
- name: Clone
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: "24"
cache: "npm"
cache-dependency-path: "tools/ui/package-lock.json"
- name: ccache
uses: ggml-org/ccache-action@v1.2.21
with:
key: release-windows-cpu-x64
variant: ccache
evict-old-files: 1d
- name: Install Ninja
run: choco install ninja -y
- name: Build
shell: cmd
run: |
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
cmake -S . -B build -G "Ninja Multi-Config" ^
-D CMAKE_TOOLCHAIN_FILE=cmake/x64-windows-llvm.cmake ^
-DLLAMA_BUILD_BORINGSSL=ON ^
-DGGML_NATIVE=OFF ^
-DGGML_BACKEND_DL=ON ^
-DGGML_CPU_ALL_VARIANTS=ON ^
-DGGML_OPENMP=ON ^
%CMAKE_ARGS%
cmake --build build --config Release
- name: ccache stats
if: always()
run: ccache --show-stats
- name: Pack artifacts
shell: pwsh
run: |
$ErrorActionPreference = "Stop"
$bin = ".\build\bin\Release"
Copy-Item ".\LICENSE" $bin
$omp = Get-ChildItem "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Redist\MSVC" -Recurse -Filter "libomp140.x86_64.dll" | Select-Object -First 1
if ($omp) {
Copy-Item $omp.FullName $bin
}
7z a -snl "beellama-bin-win-cpu-x64.zip" "$bin\*"
- name: Upload artifacts
uses: actions/upload-artifact@v6
with:
path: beellama-bin-win-cpu-x64.zip
name: beellama-bin-win-cpu-x64.zip
windows-sycl:
name: Windows x64 SYCL
needs: release-meta
runs-on: windows-2022
env:
WINDOWS_BASEKIT_URL: https://registrationcenter-download.intel.com/akdlm/IRC_NAS/b60765d1-2b85-4e85-86b6-cb0e9563a699/intel-deep-learning-essentials-2025.3.3.18_offline.exe
WINDOWS_DPCPP_MKL: intel.oneapi.win.cpp-dpcpp-common:intel.oneapi.win.mkl.devel:intel.oneapi.win.dnnl:intel.oneapi.win.tbb.devel
LEVEL_ZERO_SDK_URL: https://github.com/oneapi-src/level-zero/releases/download/v1.28.2/level-zero-win-sdk-1.28.2.zip
ONEAPI_ROOT: 'C:\Program Files (x86)\Intel\oneAPI'
ONEAPI_INSTALLER_VERSION: "2025.3.3"
steps:
- name: Clone
uses: actions/checkout@v6
- name: Cache oneAPI installation
id: cache-oneapi
uses: actions/cache@v5
with:
path: ${{ env.ONEAPI_ROOT }}
key: oneapi-windows-${{ env.ONEAPI_INSTALLER_VERSION }}-${{ runner.os }}
- name: Install oneAPI
if: steps.cache-oneapi.outputs.cache-hit != 'true'
shell: cmd
run: scripts\install-oneapi.bat "%WINDOWS_BASEKIT_URL%" "%WINDOWS_DPCPP_MKL%"
- name: Install Level Zero SDK
shell: pwsh
run: |
$ErrorActionPreference = "Stop"
$archive = Join-Path $env:RUNNER_TEMP "level-zero-win-sdk.zip"
$extractDir = Join-Path $env:RUNNER_TEMP "level-zero-sdk"
Invoke-WebRequest -Uri "${{ env.LEVEL_ZERO_SDK_URL }}" -OutFile $archive
Expand-Archive -Path $archive -DestinationPath $extractDir -Force
$sdkRoot = Get-ChildItem -Path $extractDir -Directory | Select-Object -First 1
if (-not $sdkRoot) {
$sdkRoot = Get-Item $extractDir
}
"LEVEL_ZERO_V1_SDK_PATH=$($sdkRoot.FullName)" | Out-File -FilePath $env:GITHUB_ENV -Append
- name: ccache
uses: ggml-org/ccache-action@v1.2.21
with:
key: release-windows-sycl-${{ env.ONEAPI_INSTALLER_VERSION }}-x64
variant: ccache
evict-old-files: 1d
- name: Install Ninja
run: choco install ninja -y
- name: Build
shell: cmd
run: |
call "%ONEAPI_ROOT%\setvars.bat" intel64 --force
icx --version
cmake -G "Ninja" -B build ^
-DCMAKE_C_COMPILER=cl ^
-DCMAKE_CXX_COMPILER=icx ^
-DCMAKE_BUILD_TYPE=Release ^
-DGGML_BACKEND_DL=ON ^
-DBUILD_SHARED_LIBS=ON ^
-DGGML_CPU=OFF ^
-DGGML_SYCL=ON ^
-DGGML_SYCL_F16=OFF ^
-DLLAMA_BUILD_EXAMPLES=OFF ^
-DLLAMA_BUILD_TESTS=OFF ^
-DLLAMA_BUILD_TOOLS=OFF ^
-DLLAMA_BUILD_SERVER=OFF ^
-DLLAMA_BUILD_BORINGSSL=ON
cmake --build build --config Release -j %NUMBER_OF_PROCESSORS% --target ggml-sycl
- name: ccache stats
if: always()
run: ccache --show-stats
- name: Pack SYCL backend
shell: pwsh
run: |
$ErrorActionPreference = "Stop"
$bin = ".\build\bin"
Copy-Item ".\LICENSE" $bin -Force
$runtimeFiles = @(
"$env:ONEAPI_ROOT\mkl\latest\bin\mkl_sycl_blas.5.dll",
"$env:ONEAPI_ROOT\mkl\latest\bin\mkl_core.2.dll",
"$env:ONEAPI_ROOT\mkl\latest\bin\mkl_tbb_thread.2.dll",
"$env:ONEAPI_ROOT\compiler\latest\bin\ur_adapter_level_zero.dll",
"$env:ONEAPI_ROOT\compiler\latest\bin\ur_adapter_level_zero_v2.dll",
"$env:ONEAPI_ROOT\compiler\latest\bin\ur_adapter_opencl.dll",
"$env:ONEAPI_ROOT\compiler\latest\bin\ur_loader.dll",
"$env:ONEAPI_ROOT\compiler\latest\bin\ur_win_proxy_loader.dll",
"$env:ONEAPI_ROOT\compiler\latest\bin\sycl8.dll",
"$env:ONEAPI_ROOT\compiler\latest\bin\svml_dispmd.dll",
"$env:ONEAPI_ROOT\compiler\latest\bin\libmmd.dll",
"$env:ONEAPI_ROOT\compiler\latest\bin\libiomp5md.dll",
"$env:ONEAPI_ROOT\compiler\latest\bin\sycl-ls.exe",
"$env:ONEAPI_ROOT\compiler\latest\bin\libsycl-fallback-bfloat16.spv",
"$env:ONEAPI_ROOT\compiler\latest\bin\libsycl-native-bfloat16.spv",
"$env:ONEAPI_ROOT\dnnl\latest\bin\dnnl.dll",
"$env:ONEAPI_ROOT\tbb\latest\bin\tbb12.dll",
"$env:ONEAPI_ROOT\tcm\latest\bin\tcm.dll",
"$env:ONEAPI_ROOT\tcm\latest\bin\libhwloc-15.dll",
"$env:ONEAPI_ROOT\umf\latest\bin\umf.dll"
)
foreach ($file in $runtimeFiles) {
Copy-Item -LiteralPath $file -Destination $bin -Force
}
$zeLoader = Get-ChildItem -Path @($env:ONEAPI_ROOT, $env:LEVEL_ZERO_V1_SDK_PATH) -Recurse -Filter "ze_loader.dll" -ErrorAction SilentlyContinue | Select-Object -First 1
if ($zeLoader) {
Copy-Item -LiteralPath $zeLoader.FullName -Destination $bin -Force
} else {
Write-Warning "ze_loader.dll was not found in oneAPI or the Level Zero SDK; relying on the system driver runtime"
}
7z a -snl "beellama-bin-win-sycl-x64.zip" "$bin\*"
- name: Upload SYCL backend
uses: actions/upload-artifact@v6
with:
path: beellama-bin-win-sycl-x64.zip
name: beellama-bin-win-sycl-x64.zip
windows-cuda:
name: Windows x64 CUDA ${{ matrix.cuda }}
needs: release-meta
runs-on: windows-2022
env:
CCACHE_MAXSIZE: 5G
CCACHE_SLOPPINESS: time_macros
strategy:
fail-fast: false
matrix:
cuda: ["12.4", "13.1"]
steps:
- name: Clone
uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: "24"
cache: "npm"
cache-dependency-path: "tools/ui/package-lock.json"
- name: Install ccache
uses: ggml-org/ccache-action@v1.2.21
with:
key: release-windows-cuda-${{ matrix.cuda }}
variant: ccache
evict-old-files: 1d
- name: Cache CUDA Toolkit
id: cache-cuda
uses: actions/cache@v5
with:
path: C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v${{ matrix.cuda }}
key: cuda-windows-${{ matrix.cuda }}-${{ hashFiles('.github/actions/windows-setup-cuda/action.yml') }}
- name: Install CUDA Toolkit
if: steps.cache-cuda.outputs.cache-hit != 'true'
uses: ./.github/actions/windows-setup-cuda
with:
cuda_version: ${{ matrix.cuda }}
- name: Configure CUDA environment
shell: pwsh
run: |
$ErrorActionPreference = "Stop"
$cudaPath = "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v${{ matrix.cuda }}"
$nvcc = Join-Path $cudaPath "bin\nvcc.exe"
if (-not (Test-Path $nvcc)) {
throw "CUDA Toolkit not found at $cudaPath"
}
Join-Path $cudaPath "bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
$libNvvp = Join-Path $cudaPath "libnvvp"
if (Test-Path $libNvvp) {
$libNvvp | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
}
"CUDA_PATH=$cudaPath" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
$versionEnv = "CUDA_PATH_V${{ matrix.cuda }}".Replace(".", "_")
"$versionEnv=$cudaPath" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
- name: Install Ninja
run: choco install ninja -y
- name: Build
shell: cmd
run: |
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
cmake -S . -B build -G "Ninja Multi-Config" ^
-DGGML_BACKEND_DL=ON ^
-DGGML_NATIVE=OFF ^
-DGGML_CPU=OFF ^
-DGGML_CUDA=ON ^
-DGGML_CUDA_FA=ON ^
-DGGML_CUDA_FA_ALL_QUANTS=ON ^
-DLLAMA_BUILD_BORINGSSL=ON ^
-DCMAKE_CUDA_COMPILER_LAUNCHER=ccache ^
-DGGML_CUDA_CUB_3DOT2=ON
set /A NINJA_JOBS=%NUMBER_OF_PROCESSORS%-1
cmake --build build --config Release -j %NINJA_JOBS% --target ggml-cuda
- name: ccache stats
if: always()
run: ccache --show-stats
- name: Pack CUDA backend
run: 7z a -snl "beellama-bin-win-cuda-${{ matrix.cuda }}-x64.zip" .\build\bin\Release\ggml-cuda.dll
- name: Upload CUDA backend
uses: actions/upload-artifact@v6
with:
path: beellama-bin-win-cuda-${{ matrix.cuda }}-x64.zip
name: beellama-bin-win-cuda-${{ matrix.cuda }}-x64.zip
- name: Pack CUDA runtime
shell: pwsh
run: |
$ErrorActionPreference = "Stop"
$dst = ".\build\bin\cudart"
New-Item -ItemType Directory -Force -Path $dst | Out-Null
$roots = @("${{ env.CUDA_PATH }}\bin", "${{ env.CUDA_PATH }}\lib", "${{ env.CUDA_PATH }}\bin\x64")
foreach ($root in $roots) {
if (Test-Path $root) {
Get-ChildItem -Path (Join-Path $root "*") -File -ErrorAction SilentlyContinue |
Where-Object { $_.Name -like "cudart64_*.dll" -or $_.Name -like "cublas64_*.dll" -or $_.Name -like "cublasLt64_*.dll" } |
Copy-Item -Destination $dst -Force
}
}
7z a "cudart-beellama-bin-win-cuda-${{ matrix.cuda }}-x64.zip" "$dst\*"
- name: Upload CUDA runtime
uses: actions/upload-artifact@v6
with:
path: cudart-beellama-bin-win-cuda-${{ matrix.cuda }}-x64.zip
name: cudart-beellama-bin-win-cuda-${{ matrix.cuda }}-x64.zip
windows-hip:
name: Windows x64 HIP/Radeon
needs: release-meta
runs-on: windows-2022
env:
HIPSDK_INSTALLER_VERSION: "26.Q1"
GPU_TARGETS: "gfx1150;gfx1151;gfx1200;gfx1201;gfx1100;gfx1101;gfx1102;gfx1030;gfx1031;gfx1032"
steps:
- name: Clone
uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: "24"
cache: "npm"
cache-dependency-path: "tools/ui/package-lock.json"
- name: Grab rocWMMA package
run: |
curl -o rocwmma.deb "https://repo.radeon.com/rocm/apt/7.2.1/pool/main/r/rocwmma-dev/rocwmma-dev_2.2.0.70201-81~24.04_amd64.deb"
7z x rocwmma.deb
7z x data.tar
- name: Cache ROCm installation
id: cache-rocm
uses: actions/cache@v5
with:
path: C:\Program Files\AMD\ROCm
key: rocm-${{ env.HIPSDK_INSTALLER_VERSION }}-${{ runner.os }}
- name: ccache
uses: ggml-org/ccache-action@v1.2.21
with:
key: release-windows-hip-${{ env.HIPSDK_INSTALLER_VERSION }}-x64
evict-old-files: 1d
- name: Install ROCm
if: steps.cache-rocm.outputs.cache-hit != 'true'
run: |
$ErrorActionPreference = "Stop"
Invoke-WebRequest -Uri "https://download.amd.com/developer/eula/rocm-hub/AMD-Software-PRO-Edition-${{ env.HIPSDK_INSTALLER_VERSION }}-Win11-For-HIP.exe" -OutFile "${env:RUNNER_TEMP}\rocm-install.exe"
$proc = Start-Process "${env:RUNNER_TEMP}\rocm-install.exe" -ArgumentList '-install' -NoNewWindow -PassThru
$completed = $proc.WaitForExit(600000)
if (-not $completed) {
$proc.Kill()
Write-Error "ROCm installation timed out after 10 minutes"
}
if ($proc.ExitCode -ne 0) {
Write-Error "ROCm installation failed with exit code $($proc.ExitCode)"
}
- name: Verify ROCm
run: |
$clangPath = Get-ChildItem 'C:\Program Files\AMD\ROCm\*\bin\clang.exe' | Select-Object -First 1
if (-not $clangPath) {
Write-Error "ROCm installation not found"
}
& $clangPath.FullName --version
- name: Build
run: |
$env:HIP_PATH=$(Resolve-Path 'C:\Program Files\AMD\ROCm\*\bin\clang.exe' | Split-Path | Split-Path)
$env:CMAKE_PREFIX_PATH="${env:HIP_PATH}"
cmake -G "Unix Makefiles" -B build -S . `
-DCMAKE_C_COMPILER="${env:HIP_PATH}\bin\clang.exe" `
-DCMAKE_CXX_COMPILER="${env:HIP_PATH}\bin\clang++.exe" `
-DCMAKE_CXX_FLAGS="-I$($PWD.Path.Replace('\', '/'))/opt/rocm-7.2.1/include/ -Wno-ignored-attributes -Wno-nested-anon-types" `
-DCMAKE_BUILD_TYPE=Release `
-DGGML_BACKEND_DL=ON `
-DGGML_NATIVE=OFF `
-DGGML_CPU=OFF `
-DGPU_TARGETS="${env:GPU_TARGETS}" `
-DGGML_HIP_ROCWMMA_FATTN=ON `
-DGGML_HIP=ON `
-DLLAMA_BUILD_BORINGSSL=ON
cmake --build build --target ggml-hip -j ${env:NUMBER_OF_PROCESSORS}
New-Item -ItemType Directory -Force -Path "build\bin\rocblas\library" | Out-Null
New-Item -ItemType Directory -Force -Path "build\bin\hipblaslt\library" | Out-Null
Copy-Item "${env:HIP_PATH}\bin\libhipblas.dll" "build\bin\"
Copy-Item "${env:HIP_PATH}\bin\libhipblaslt.dll" "build\bin\"
Copy-Item "${env:HIP_PATH}\bin\rocblas.dll" "build\bin\"
Copy-Item "${env:HIP_PATH}\bin\rocblas\library\*" "build\bin\rocblas\library\"
Copy-Item "${env:HIP_PATH}\bin\hipblaslt\library\*" "build\bin\hipblaslt\library\"
- name: ccache stats
if: always()
run: ccache --show-stats
- name: Pack artifacts
run: 7z a -snl "beellama-bin-win-hip-radeon-x64.zip" .\build\bin\*
- name: Upload artifacts
uses: actions/upload-artifact@v6
with:
path: beellama-bin-win-hip-radeon-x64.zip
name: beellama-bin-win-hip-radeon-x64.zip
package-assets:
name: Assemble release assets
needs:
- release-meta
- macos-arm64
- ubuntu-cpu
- ubuntu-vulkan
- ubuntu-rocm
- ubuntu-sycl
- windows-cpu
- windows-sycl
- windows-cuda
- windows-hip
runs-on: ubuntu-24.04
steps:
- name: Clone
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Download artifacts
uses: actions/download-artifact@v7
with:
path: ./artifact
merge-multiple: true
- name: Prepare release assets
shell: bash
env:
TAG_NAME: ${{ needs.release-meta.outputs.tag_name }}
run: |
set -euo pipefail
shopt -s nullglob
mkdir -p release
cpu_zip="artifact/beellama-bin-win-cpu-x64.zip"
if [[ -f "${cpu_zip}" ]]; then
temp_dir="$(mktemp -d)"
unzip -q "${cpu_zip}" -d "${temp_dir}"
for target_zip in artifact/beellama-bin-win-*-x64.zip; do
if [[ "$(basename "${target_zip}")" == "beellama-bin-win-cpu-x64.zip" ]]; then
continue
fi
realpath_target_zip="$(realpath "${target_zip}")"
(cd "${temp_dir}" && zip -qr "${realpath_target_zip}" .)
done
rm -rf "${temp_dir}"
fi
for zip_file in artifact/beellama-bin-win-*.zip; do
base_name="$(basename "${zip_file}" .zip)"
mv "${zip_file}" "release/beellama-${TAG_NAME}-${base_name#beellama-}.zip"
done
for zip_file in artifact/cudart-beellama-bin-win-cuda-*.zip; do
base_name="$(basename "${zip_file}" .zip)"
suffix="${base_name#cudart-beellama-bin-win-}"
mv "${zip_file}" "release/beellama-${TAG_NAME}-cudart-win-${suffix}.zip"
done
for tar_file in artifact/*.tar.gz; do
mv "${tar_file}" release/
done
sha256sum release/* > release/SHA256SUMS.txt
ls -lh release
- name: Write release notes
shell: bash
env:
TAG_NAME: ${{ needs.release-meta.outputs.tag_name }}
run: |
set -euo pipefail
release_url="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/releases/download/${TAG_NAME}"
changelog_url="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/blob/main/CHANGELOG.md"
image_repo="ghcr.io/${GITHUB_REPOSITORY,,}"
repo_name="${GITHUB_REPOSITORY#*/}"
repo_name="${repo_name,,}"
package_url="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/pkgs/container/${repo_name}"
docker_link() {
local tag="$1"
printf '[`%s:%s`](%s)' "${image_repo}" "${tag}" "${package_url}"
}
docker_server="$(docker_link "server-${TAG_NAME}")"
docker_cpu="$(docker_link "server-cpu-${TAG_NAME}")"
docker_cuda="$(docker_link "server-cuda-${TAG_NAME}")"
docker_cuda12="$(docker_link "server-cuda12-${TAG_NAME}")"
docker_cuda13="$(docker_link "server-cuda13-${TAG_NAME}")"
docker_rocm="$(docker_link "server-rocm-${TAG_NAME}")"
docker_vulkan="$(docker_link "server-vulkan-${TAG_NAME}")"
docker_sycl="$(docker_link "server-sycl-${TAG_NAME}")"
cat > release-notes.md << EOF
<details open>
<summary>Changelog</summary>
[CHANGELOG.md](${changelog_url})
</details>
**macOS:**
- [macOS Apple Silicon (arm64)](${release_url}/beellama-${TAG_NAME}-bin-macos-arm64.tar.gz)
**Linux:**
- [Ubuntu x64 (CPU)](${release_url}/beellama-${TAG_NAME}-bin-ubuntu-x64.tar.gz)
- [Ubuntu x64 (Vulkan)](${release_url}/beellama-${TAG_NAME}-bin-ubuntu-vulkan-x64.tar.gz)
- [Ubuntu x64 (ROCm 7.2)](${release_url}/beellama-${TAG_NAME}-bin-ubuntu-rocm-7.2-x64.tar.gz)
- [Ubuntu x64 (SYCL)](${release_url}/beellama-${TAG_NAME}-bin-ubuntu-sycl-x64.tar.gz)
**Windows:**
- [Windows x64 (CPU)](${release_url}/beellama-${TAG_NAME}-bin-win-cpu-x64.zip)
- [Windows x64 (SYCL)](${release_url}/beellama-${TAG_NAME}-bin-win-sycl-x64.zip)
- [Windows x64 (CUDA 12)](${release_url}/beellama-${TAG_NAME}-bin-win-cuda-12.4-x64.zip) - [CUDA 12.4 DLLs](${release_url}/beellama-${TAG_NAME}-cudart-win-cuda-12.4-x64.zip)
- [Windows x64 (CUDA 13)](${release_url}/beellama-${TAG_NAME}-bin-win-cuda-13.1-x64.zip) - [CUDA 13.1 DLLs](${release_url}/beellama-${TAG_NAME}-cudart-win-cuda-13.1-x64.zip)
- [Windows x64 (HIP)](${release_url}/beellama-${TAG_NAME}-bin-win-hip-radeon-x64.zip)
**Docker:**
- ${docker_server} / ${docker_cpu} (CPU, linux/amd64 + linux/arm64; usable on Apple Silicon Docker Desktop without Metal acceleration)
- ${docker_cuda} / ${docker_cuda12}
- ${docker_cuda13}
- ${docker_rocm}
- ${docker_vulkan}
- ${docker_sycl}
EOF
- name: Upload release assets
uses: actions/upload-artifact@v6
with:
name: beellama-release-assets
path: |
release/*
release-notes.md
wait-docker:
name: Wait for Docker images
if: ${{ needs.release-meta.outputs.create_release == 'true' }}
needs:
- release-meta
runs-on: ubuntu-24.04
permissions:
actions: read
contents: read
steps:
- name: Wait for Docker workflow
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
HEAD_SHA: ${{ github.sha }}
REF_NAME: ${{ github.ref_name }}
TAG_NAME: ${{ needs.release-meta.outputs.tag_name }}
run: |
set -euo pipefail
deadline=$((SECONDS + 7200))
while (( SECONDS < deadline )); do
run_info="$(
gh run list \
--repo "${GITHUB_REPOSITORY}" \
--workflow docker.yml \
--commit "${HEAD_SHA}" \
--event push \
--json databaseId,status,conclusion,headBranch,url,createdAt \
--limit 20 \
--jq "map(select(.headBranch == \"${TAG_NAME}\" or .headBranch == \"${REF_NAME}\" or .headBranch == \"\" or .headBranch == null)) | sort_by(.createdAt) | reverse | .[0] | select(. != null) | [.databaseId, .status, (.conclusion // \"\"), .url] | @tsv"
)"
if [[ -z "${run_info}" ]]; then
echo "Waiting for Docker workflow run for ${TAG_NAME} (${HEAD_SHA})..."
sleep 30
continue
fi
IFS=$'\t' read -r run_id status conclusion url <<< "${run_info}"
echo "Docker workflow run ${run_id}: status=${status} conclusion=${conclusion:-pending} ${url}"
if [[ "${status}" == "completed" ]]; then
if [[ "${conclusion}" == "success" ]]; then
exit 0
fi
echo "Docker workflow did not succeed: ${conclusion}" >&2
exit 1
fi
sleep 30
done
echo "Timed out waiting for Docker workflow for ${TAG_NAME} (${HEAD_SHA})." >&2
exit 1
release:
name: Publish GitHub release
if: ${{ needs.release-meta.outputs.create_release == 'true' }}
needs:
- release-meta
- package-assets
- wait-docker
runs-on: ubuntu-24.04
permissions:
contents: write
steps:
- name: Download release assets
uses: actions/download-artifact@v7
with:
name: beellama-release-assets
path: ./release-bundle
- name: Create or update release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG_NAME: ${{ needs.release-meta.outputs.tag_name }}
run: |
set -euo pipefail
notes_file="$(find release-bundle -type f -name release-notes.md | head -n 1)"
if [[ -z "${notes_file}" ]]; then
echo "release-notes.md not found in release asset bundle" >&2
exit 1
fi
mapfile -t release_files < <(find release-bundle -type f ! -name release-notes.md | sort)
if [[ "${#release_files[@]}" -eq 0 ]]; then
echo "No release files found in release asset bundle" >&2
exit 1
fi
if gh release view "${TAG_NAME}" >/dev/null 2>&1; then
gh release upload "${TAG_NAME}" "${release_files[@]}" --clobber
gh release edit "${TAG_NAME}" --title "${TAG_NAME}" --notes-file "${notes_file}"
else
gh release create "${TAG_NAME}" "${release_files[@]}" --title "${TAG_NAME}" --notes-file "${notes_file}" --verify-tag
fi