ci: build an image that can actually be built

This pipeline could not work on this fleet and had not produced an image in
weeks, while looking idle rather than broken.

  buildctl-daemonless.sh: command not found (exit 127). Jobs run in
  catthehacker/ubuntu:act-24.04 per GIT_RUNNER_LABELS; there is no buildctl
  in it. It also read secrets.GIT_CLONE_TOKEN, which exists on neither the
  repo nor the hanzoai org on git.hanzo.ai.

  The kubectl patch step failed the same way (kubectl: command not found) and
  was futile anyway: cd.hanzo.ai selfHeal restores the App CR from the pin in
  hanzoai/universe on its next poll. Rollout is a reviewed pin there, never a
  CI side effect — so the deploy step is removed, not repaired.

Replaced with the shape proven on hanzoai/playground, the only one of these
whose build job has ever gone green here: setup-buildx + login-action +
build-push-action, using GHCR_USER/GHCR_TOKEN/GH_PAT which DO exist as org
secrets. Keeps playground's imagetools verification, because build-push-action
can exit 0 before the manifest resolves.
This commit is contained in:
2026-07-27 05:05:40 -07:00
parent 1ffb901f07
commit 4b6e7c9656
+69 -15
View File
@@ -1,24 +1,78 @@
# Build the image and push it. Nothing else.
#
# REWRITTEN 2026-07-27. The previous version could not work on this fleet, in two
# independent ways, and produced no image for weeks while looking merely idle:
#
# 1. `buildctl-daemonless.sh: command not found` (exit 127). Jobs here run in
# catthehacker/ubuntu:act-24.04 (see GIT_RUNNER_LABELS on the git-runner
# StatefulSet) and that image has no buildctl. It also read
# `secrets.GIT_CLONE_TOKEN`, which exists on neither the repo nor the org.
# 2. The `kubectl patch app` step failed with `kubectl: command not found` for
# the same reason — and it was futile regardless: cd.hanzo.ai's selfHeal
# restores the App CR from the pin in hanzoai/universe on its next poll.
# Rollout is a reviewed tag pin there, never a CI side effect.
#
# So the deploy step is gone on purpose. CI's job is to make a tag EXIST;
# choosing which tag runs is a reviewed change in universe.
#
# This is the shape proven on hanzoai/playground, whose build job is the only
# one of these that has ever gone green on this fleet. GHCR_USER / GHCR_TOKEN /
# GH_PAT all exist as hanzoai org secrets on git.hanzo.ai.
name: deploy name: deploy
on: on:
push: push:
branches: [main] branches: [main]
workflow_dispatch:
concurrency:
group: deploy-templates-blueprints-${{ github.ref }}
cancel-in-progress: true
jobs: jobs:
deploy: build:
runs-on: hanzo-build-linux-amd64 # Must name a label a runner ACTUALLY advertises. The four online
# git-runners offer hanzo-build-linux-amd64; a label nothing offers does not
# fail, it queues until the 24h timeout — silence, not an error.
runs-on: [hanzo-build-linux-amd64]
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Build + push image
- id: meta
run: echo "tag=sha-$(echo "$GITHUB_SHA" | cut -c1-7)" >> "$GITHUB_OUTPUT"
- uses: docker/setup-buildx-action@v3
with:
driver: docker-container
driver-opts: network=host
# Without this the push is unauthenticated and 403s at the registry.
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ secrets.GHCR_USER }}
password: ${{ secrets.GHCR_TOKEN }}
- uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile
platforms: linux/amd64
push: true
provenance: false
tags: ghcr.io/hanzoai/templates-blueprints:${{ steps.meta.outputs.tag }}
secrets: |
GIT_AUTH_TOKEN=${{ secrets.GH_PAT }}
# build-push-action can exit 0 before the manifest resolves, so a green run
# could still mean a future ImagePullBackOff. Prove it pulls.
- name: Verify the pushed image resolves
run: | run: |
SHA="${GITHUB_SHA::8}" set -euo pipefail
buildctl-daemonless.sh build --frontend=dockerfile.v0 \ img="ghcr.io/hanzoai/templates-blueprints:${{ steps.meta.outputs.tag }}"
--opt context="${{ github.server_url }}/${{ github.repository }}.git#${GITHUB_SHA}" \ for i in 1 2 3 4 5 6; do
--opt filename=Dockerfile --opt platform=linux/amd64 \ if docker buildx imagetools inspect "$img" >/dev/null 2>&1; then
--secret id=GIT_AUTH_TOKEN,env=GIT_AUTH_TOKEN \ echo "resolved $img"; exit 0
--output "type=image,name=ghcr.io/hanzoai/templates-blueprints:${SHA},push=true" --progress=plain fi
env: sleep 5
GIT_AUTH_TOKEN: ${{ secrets.GIT_CLONE_TOKEN }}
- name: Deploy — declare tag to operator
run: |
for app in templates-blueprints; do
kubectl -n hanzo patch app "$app" --type=merge -p "{\"spec\":{\"image\":{\"repository\":\"ghcr.io/hanzoai/templates-blueprints\",\"tag\":\"${GITHUB_SHA::8}\"}}}"
done done
echo "::error::pushed image never resolved: $img"; exit 1