# Builds DigUp for Windows and Linux on x64: the shell's Windows installer, and its .deb and AppImage, kept as the run's # artifacts (nothing is published). By hand: `gh workflow run packages.yml`, or `-f ref=`. The Mac app is # built and released on a Mac (scripts/release.sh). llama.cpp gets its Vulkan backend beside the CPU ones (the Vulkan # SDK's shader compiler is what makes scripts/build-llama.sh build it): a computer whose GPU runs the model faster than # its processor uses it (`digup speed --model` decides), any other the processor. Each package is then installed and # launched, hidden (scripts/check-*-package.sh): the AppImage and the .deb on Ubuntu 22.04 and 24.04 and Debian 12, the # installer on Windows. With the update signing key in the repository's secrets, the installer and the AppImage # come with the .sig files the update feed needs (scripts/update-feed.py). name: Packages on: workflow_dispatch: inputs: ref: description: Branch or tag to build default: main permissions: contents: read jobs: linux: # Built in an Ubuntu 22.04 container: the binaries then ask for glibc 2.35 at most and start on Ubuntu 22.04, Debian 12, # Mint 21 and anything newer (built on 24.04 they'd need its 2.39). GitHub is retiring its ubuntu-22.04 runners. runs-on: ubuntu-24.04 container: ubuntu:22.04 steps: - name: Build tools # GStreamer's plugins are the ones the AppImage carries for WebKit's media player (scripts/package-linux.sh). run: | apt-get update -q DEBIAN_FRONTEND=noninteractive apt-get install -y -q --no-install-recommends ca-certificates curl git gnupg \ xz-utils unzip python3 binutils build-essential cmake ninja-build meson nasm pkg-config patchelf file \ zlib1g-dev libcurl4-openssl-dev libxml2-dev libedit2 libsqlite3-0 libz3-dev libpython3-dev tzdata \ libwebkit2gtk-4.1-dev libayatana-appindicator3-dev librsvg2-dev libxdo-dev libssl-dev libvulkan1 \ gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-gl gstreamer1.0-alsa - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ inputs.ref }} - name: Swift run: | version=6.4.0 url=https://download.swift.org/swift-$version-release/ubuntu2204/swift-$version-RELEASE/swift-$version-RELEASE-ubuntu22.04.tar.gz curl -fsSL -o swift.tar.gz "$url" curl -fsSL -o swift.tar.gz.sig "$url.sig" curl -fsSL --compressed https://www.swift.org/keys/all-keys.asc | gpg --quiet --import gpg --verify swift.tar.gz.sig swift.tar.gz mkdir -p "$RUNNER_TEMP/swift" tar -xzf swift.tar.gz -C "$RUNNER_TEMP/swift" --strip-components 1 rm swift.tar.gz swift.tar.gz.sig echo "$RUNNER_TEMP/swift/usr/bin" >> "$GITHUB_PATH" - name: Rust and Node run: | curl -fsSL https://sh.rustup.rs | sh -s -- -y -q --profile minimal echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" # Node runs Tauri's CLI (Ubuntu 22.04's own Node is too old for it). node=node-v24.20.0-linux-x64 curl -fsSL -o "$RUNNER_TEMP/node.tar.xz" "https://nodejs.org/dist/v24.20.0/$node.tar.xz" echo "2f2c0da162318f0de47665410c7c8c2ed3d36c8f3105de4bbc61176c70a7cbf2 $RUNNER_TEMP/node.tar.xz" | sha256sum -c - tar -xJf "$RUNNER_TEMP/node.tar.xz" -C "$RUNNER_TEMP" echo "$RUNNER_TEMP/$node/bin" >> "$GITHUB_PATH" - name: Vulkan SDK # Its shader compiler and headers (Ubuntu 22.04 has no glslc); the backend loads the system's Vulkan at run time. run: | version=1.4.363.0 curl -fsSL -o "$RUNNER_TEMP/vulkansdk.tar.xz" \ "https://sdk.lunarg.com/sdk/download/$version/linux/vulkansdk-linux-x86_64-$version.tar.xz" echo "197962f5cbf80baf2775a03336a01cee7c8745686c65aaa70d3f751ade4d7e43 $RUNNER_TEMP/vulkansdk.tar.xz" | sha256sum -c - tar -xJf "$RUNNER_TEMP/vulkansdk.tar.xz" -C "$RUNNER_TEMP" rm "$RUNNER_TEMP/vulkansdk.tar.xz" sdk=$RUNNER_TEMP/$version/x86_64 echo "VULKAN_SDK=$sdk" >> "$GITHUB_ENV" echo "CMAKE_PREFIX_PATH=$sdk:$sdk/lib/VulkanLoader" >> "$GITHUB_ENV" echo "$sdk/bin" >> "$GITHUB_PATH" - uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: path: Vendor/ffmpeg key: ffmpeg-linux-${{ hashFiles('scripts/build-ffmpeg.sh') }} - name: Build env: APPIMAGE_EXTRACT_AND_RUN: 1 # Tauri's AppImage tools are AppImages, and a container has no FUSE TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} run: | scripts/fetch-vendor.sh scripts/build-llama.sh scripts/package-linux.sh - name: Check the glibc asked for run: | # ffmpeg and ffprobe are static: objdump has nothing to say about them. newest=$( (objdump -T shell/src-tauri/target/release/digup-shell shell/src-tauri/helper/* 2>/dev/null || true) | grep -o 'GLIBC_[0-9.]*' | sort -uV | tail -1) echo "newest glibc version asked for: $newest" [ -n "$newest" ] && [ "$(printf '%s\n' "$newest" GLIBC_2.35 | sort -V | tail -1)" = GLIBC_2.35 ] - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: DigUp-linux-x64 path: | shell/src-tauri/target/release/bundle/deb/*.deb shell/src-tauri/target/release/bundle/appimage/*.AppImage shell/src-tauri/target/release/bundle/appimage/*.AppImage.sig linux-check: # The packages where people will run them, in a bare container of each distribution: the AppImage first, with only # the libraries any desktop has, then the .deb (which brings what it needs); each with a hidden first launch. needs: linux runs-on: ubuntu-24.04 strategy: fail-fast: false matrix: image: ["ubuntu:22.04", "ubuntu:24.04", "debian:12"] container: ${{ matrix.image }} env: # WebKit's web processes sandbox themselves with bubblewrap, whose namespaces Docker's default seccomp profile # refuses inside a container; on a desktop they're sandboxed as usual. WEBKIT_DISABLE_SANDBOX_THIS_IS_DANGEROUS: 1 steps: - name: Tools run: | apt-get update -q DEBIAN_FRONTEND=noninteractive apt-get install -y -q --no-install-recommends ca-certificates xvfb xauth dbus - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ inputs.ref }} - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: DigUp-linux-x64 path: packages # as the bundle had them: deb/ and appimage/ - uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: path: models key: embeddinggemma-2-q8_0-bfcd298 - name: The AppImage # Before the .deb installs the system's WebKit and GStreamer: the AppImage must bring its own. Installed first are # the libraries AppImages leave to the system, which any desktop has (ALSA's is libasound2t64 on Ubuntu 24.04). run: | asound=libasound2 apt-cache show libasound2t64 > /dev/null 2>&1 && asound=libasound2t64 DEBIAN_FRONTEND=noninteractive apt-get install -y -q --no-install-recommends libx11-6 libx11-xcb1 libxcb1 \ libfontconfig1 libfreetype6 libharfbuzz0b libfribidi0 libwayland-client0 libgbm1 libdrm2 libgl1 libegl1 \ libgles2 libexpat1 $asound chmod +x packages/appimage/*.AppImage MODELS="$PWD/models" scripts/check-linux-package.sh packages/appimage/*.AppImage - name: The .deb run: | DEBIAN_FRONTEND=noninteractive apt-get install -y -q ./packages/deb/*.deb MODELS="$PWD/models" scripts/check-linux-package.sh /usr/bin/digup-shell - name: The update signature # Signed with the repository's key (once its secrets are set), the AppImage's signature must match the public key # installed copies check updates with (tauri.conf.json), or no update could ever be installed. if: matrix.image == 'ubuntu:24.04' run: | signature=$(ls packages/appimage/*.AppImage.sig 2> /dev/null || true) if [ -z "$signature" ]; then echo "not signed: the update signing key isn't in the repository's secrets" exit 0 fi DEBIAN_FRONTEND=noninteractive apt-get install -y -q --no-install-recommends minisign sed -n 's/.*"pubkey": "\([^"]*\)".*/\1/p' shell/src-tauri/tauri.conf.json | base64 -d > "$RUNNER_TEMP/update.pub" base64 -d "$signature" > "$RUNNER_TEMP/update.minisig" minisign -V -p "$RUNNER_TEMP/update.pub" -m "${signature%.sig}" -x "$RUNNER_TEMP/update.minisig" windows: runs-on: windows-2025 steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ inputs.ref }} # The small ffmpeg is built once per version of its build script (build-ffmpeg.sh does nothing when it's there). - uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 id: ffmpeg with: path: Vendor/ffmpeg key: ffmpeg-windows-${{ hashFiles('scripts/build-ffmpeg.sh') }} - uses: msys2/setup-msys2@ec48f7c5447b3140e2b088413ae3a55687bccb6e # v2.33.0 if: steps.ffmpeg.outputs.cache-hit != 'true' with: msystem: MINGW64 release: false # the runner's own MSYS2 update: true install: >- make mingw-w64-x86_64-gcc mingw-w64-x86_64-meson mingw-w64-x86_64-ninja mingw-w64-x86_64-nasm mingw-w64-x86_64-pkgconf mingw-w64-x86_64-zlib - name: ffmpeg # The small LGPL ffmpeg the installer carries (as the Linux packages do): only what DigUp reads, so its licenses # are FFmpeg's, dav1d's and zlib's. Built with MSYS2's MinGW compilers, before the MSVC environment. if: steps.ffmpeg.outputs.cache-hit != 'true' shell: msys2 {0} run: scripts/build-ffmpeg.sh - uses: compnerd/gha-setup-swift@bbae8ce86bac5a3449f3992b3d88bc4ca25f2057 # v0.5.0 with: swift-version: swift-6.4.0-release swift-build: 6.4.0-RELEASE - uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1.13.0 - name: Vulkan SDK shell: bash run: | version=1.4.363.0 temp=$(cygpath -u "$RUNNER_TEMP") curl -fsSL -o "$temp/vulkansdk.exe" \ "https://sdk.lunarg.com/sdk/download/$version/windows/vulkansdk-windows-X64-$version.exe" echo "94a82d378f7a5e3e54c9db7d2fb7016af136e14ac0a18dbf0f2f67a36352d141 $temp/vulkansdk.exe" | sha256sum -c - "$temp/vulkansdk.exe" --root "C:\\VulkanSDK\\$version" --accept-licenses --default-answer --confirm-command install echo "VULKAN_SDK=C:\\VulkanSDK\\$version" >> "$GITHUB_ENV" echo "C:\\VulkanSDK\\$version\\Bin" >> "$GITHUB_PATH" - name: Build shell: bash run: | # MSVC's tools before Git's: Git's /usr/bin/link (coreutils) would stand in for link.exe. export PATH="$(dirname "$(command -v cl)"):$PATH" scripts/fetch-vendor.sh scripts/build-llama.sh scripts/package-windows.sh env: TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: DigUp-windows-x64 path: | shell/src-tauri/target/release/bundle/nsis/*.exe shell/src-tauri/target/release/bundle/nsis/*.exe.sig - uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: path: models key: embeddinggemma-2-q8_0-bfcd298-windows - name: The installer shell: bash run: MODELS="$PWD/models" scripts/check-windows-package.sh shell/src-tauri/target/release/bundle/nsis/*-setup.exe