Skip to content

build-image

build-image #98

Workflow file for this run

name: build-image
# Assemble the cppmega runtime image from the prebuilt wheel release and push
# to ghcr.io/datasunriseou/cppmega:<sha>. Buildx registry cache lives in the same
# repo so re-runs after a fix start from the last good layer, never from scratch.
on:
workflow_dispatch:
inputs:
wheels_tag:
description: "Wheel release tag (without 'wheels-' prefix). Empty = latest."
required: false
type: string
workflow_run:
workflows: [build-wheels]
types: [completed]
permissions:
contents: read
packages: write # ghcr.io push
concurrency:
group: build-image-${{ github.ref }}
cancel-in-progress: true
env:
IMAGE: ghcr.io/datasunriseou/cppmega
jobs:
image:
if: |
github.repository == 'DatasunriseOU/cppmega' &&
(github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success')
runs-on: [self-hosted, Linux, X64, cppmega]
steps:
- uses: actions/checkout@v4
- name: Verify persistent runner capacity
shell: bash
run: |
set -euo pipefail
df -h "$GITHUB_WORKSPACE"
available_kib=$(df -Pk "$GITHUB_WORKSPACE" | awk 'NR == 2 {print $4}')
minimum_kib=$((80 * 1024 * 1024))
if (( available_kib < minimum_kib )); then
echo "::error::build-image requires at least 80 GiB free on the persistent runner"
exit 1
fi
- name: Resolve wheel release tag
id: rel
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
if [[ -n "${{ inputs.wheels_tag }}" ]]; then
TAG="wheels-${{ inputs.wheels_tag }}"
else
TAG=$(gh release list --limit 50 --json tagName --jq '.[].tagName' \
| grep '^wheels-' | head -1)
fi
if [[ -z "$TAG" ]]; then
echo "No wheel release found — run build-wheels.yml first." >&2
exit 1
fi
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
echo "Using wheel release: $TAG"
- name: Download wheels
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
mkdir -p wheels
gh release download "${{ steps.rel.outputs.tag }}" --dir wheels --pattern '*.whl'
ls -lh wheels/
- name: Verify required wheels
run: |
set -euo pipefail
required=(
'transformer_engine-*.whl'
'flash_attn-*.whl'
'flash_attn_3-*.whl'
'mamba_ssm-*.whl'
'causal_conv1d-*.whl'
'fast_hadamard_transform-*.whl'
'tilelang-*.whl'
'qoptim_cuda-*.whl'
)
for pattern in "${required[@]}"; do
matches=(wheels/$pattern)
if [[ ! -e "${matches[0]}" ]]; then
echo "::error::wheel release ${{ steps.rel.outputs.tag }} is missing required asset: $pattern"
ls -lh wheels/ || true
exit 1
fi
done
- name: Set up buildx
uses: docker/setup-buildx-action@v3
- name: Log in to ghcr.io
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Compute tags
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.IMAGE }}
tags: |
type=sha,format=long
type=sha,prefix=,format=short
type=raw,value=latest,enable={{is_default_branch}}
type=raw,value=${{ steps.rel.outputs.tag }}
- name: Build & push (cache to/from registry)
uses: docker/build-push-action@v6
with:
context: .
file: docker/Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: |
type=registry,ref=${{ env.IMAGE }}:buildcache
cache-to: |
type=registry,ref=${{ env.IMAGE }}:buildcache,mode=max
provenance: false # cleaner package listing in ghcr UI