From 8402dcebdd3bbc74aca90e68363b3ef19b2d9d02 Mon Sep 17 00:00:00 2001 From: Daniel Han Date: Fri, 26 Jun 2026 08:27:11 +0000 Subject: [PATCH] docker-publish: pin one llama.cpp prebuilt release across both arch legs The base build-args never passed LLAMA_PREBUILT_TAG, so the Dockerfile fell back to latest and each matrix leg resolved whatever unslothai/llama.cpp release was current at its own build time. If latest moved between the amd64 and arm64 legs, one published manifest could carry different GGUF binaries per arch. Resolve the release once in a new prepare job (explicit llama_prebuilt_tag dispatch input for a frozen build, else follow the /releases/latest redirect to a concrete tag, mirroring docker/build.sh) and pass that single tag to both legs. --- .github/workflows/docker-publish.yml | 38 ++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 0226343192..9085b261a4 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -44,6 +44,10 @@ on: description: 'unsloth-zoo git ref to bake in' required: false default: 'main' + llama_prebuilt_tag: + description: 'unslothai/llama.cpp prebuilt release tag to bake (blank = newest)' + required: false + default: '' env: REGISTRY: docker.io @@ -66,6 +70,36 @@ permissions: contents: read jobs: + # --------------------------------------------------------------------------- + # Resolve the llama.cpp prebuilt release ONCE, up front, so both arch legs of + # the base build bake the identical GGUF binaries. Resolving "latest" inside + # each leg would let upstream publish a new release between the amd64 and + # arm64 builds, putting different binaries under one published image tag. + # An explicit dispatch input pins a frozen release; otherwise we follow the + # /releases/latest redirect to a concrete tag (mirrors docker/build.sh). + # --------------------------------------------------------------------------- + prepare: + runs-on: ubuntu-latest + timeout-minutes: 5 + permissions: + contents: read + outputs: + llama_tag: ${{ steps.llama.outputs.tag }} + steps: + - name: Resolve llama.cpp prebuilt tag + id: llama + env: + INPUT_TAG: ${{ github.event.inputs.llama_prebuilt_tag }} + run: | + TAG="$INPUT_TAG" + if [ -z "$TAG" ]; then + TAG="$(curl -fsSL -o /dev/null -w '%{url_effective}' \ + https://github.com/unslothai/llama.cpp/releases/latest \ + | sed -n 's#.*/releases/tag/##p')" + fi + echo "tag=${TAG:-latest}" >> "$GITHUB_OUTPUT" + echo "llama.cpp prebuilt tag: ${TAG:-latest}" + # --------------------------------------------------------------------------- # Per-arch build. The matrix fans out two parallel jobs on the matching # native runner. Each pushes a single-arch image *by digest* (no human- @@ -75,6 +109,7 @@ jobs: # that you get when two jobs push the same tag separately. # --------------------------------------------------------------------------- build: + needs: prepare strategy: fail-fast: false matrix: @@ -170,12 +205,15 @@ jobs: # UNSLOTH_ZOO_REF (from the resolve step above): explicit dispatch # input, else the pushed tag IF the zoo repo has it, else main -- a # branch SHA does not exist in the zoo repo. + # LLAMA_PREBUILT_TAG (from the prepare job): one concrete tag shared + # by both arch legs so the published manifest is reproducible. build-args: | CUDA_VERSION=12.8.1 UBUNTU_VERSION=24.04 PYTHON_VERSION=3.12 UNSLOTH_REF=${{ github.event.inputs.unsloth_ref || (startsWith(github.ref, 'refs/tags/') && github.ref_name) || github.sha || 'main' }} UNSLOTH_ZOO_REF=${{ steps.zoo_ref.outputs.ref }} + LLAMA_PREBUILT_TAG=${{ needs.prepare.outputs.llama_tag }} # Stash the per-arch digest as an artifact for the merge job to pick up. # Filenames need to be unique across the matrix; `platform` contains a