the generator is a tool, the document is an argument

They shared a name and the lane died on it. `SPEC_REF` is the ref of the
DOCUMENT — hanzoai/ci's client lane exports a hanzoai/cloud sha or v-tag — and
this script also handed it to `git clone --branch` against hanzoai/openapi, which
is a different repository and has never had a ref by that name.
`git ls-remote hanzoai/openapi 5126939` returns nothing, and neither does
v1.801.495, so every CI regeneration died at the clone before the generator ran.
By hand it appeared to work, because with SPEC_REF unset the default was `main`
and both repositories happen to have a branch called that — which is the worst
kind of coincidence, one that makes a broken path look tested.

The generator is cloned at its own default branch now, from git.hanzo.ai, and the
document reaches the driver as a value: hanzoai/ci passes it digest-checked, and
without that the driver reads this tree's .spec-lock and fetches the same bytes
from the same forge. A hand run and a CI run project the same document instead of
whatever main happens to be.
This commit is contained in:
2026-08-08 06:20:02 -07:00
parent 69e74af7dc
commit b07499c8a5
+14 -17
View File
@@ -14,8 +14,15 @@
# ./scripts/generate.sh # regenerate in place
# ./scripts/generate.sh --check # non-zero if the committed client drifted
#
# hanzoai/openapi is PRIVATE, so raw.githubusercontent.com 404s it and a clone
# needs credentials: SPEC_TOKEN, else GH_TOKEN, else GITHUB_TOKEN, else ssh.
# THE GENERATOR IS A TOOL; THE DOCUMENT IS AN ARGUMENT. They had one name here
# and it broke the lane. `SPEC_REF` is the ref of the DOCUMENT — hanzoai/ci's
# client lane exports a hanzoai/cloud sha or v-tag — and it was also handed to
# `git clone --branch` on hanzoai/openapi, which is a different repository and
# has never had a ref by that name. So every CI regeneration died at the clone,
# and by hand it worked only because SPEC_REF defaulted to `main` and both repos
# happen to have one. The generator is cloned at its own default branch now, and
# the document reaches the driver as a value.
#
# Point OPENAPI at a checkout you already have to skip the clone entirely.
#
# Requires: python3 (+pyyaml), java 11+, git.
@@ -23,27 +30,17 @@ set -euo pipefail
cd "$(dirname "$0")/.."
OPENAPI="${OPENAPI:-}"
SPEC_REPO="${SPEC_REPO:-hanzoai/openapi}"
SPEC_REF="${SPEC_REF:-main}"
if [ -z "$OPENAPI" ]; then
OPENAPI="$(mktemp -d "${TMPDIR:-/tmp}/hanzo-openapi.XXXXXX")"
trap 'rm -rf "$OPENAPI"' EXIT
TOKEN="${SPEC_TOKEN:-${GH_TOKEN:-${GITHUB_TOKEN:-}}}"
if [ -n "$TOKEN" ]; then
echo "cloning private ${SPEC_REPO}@${SPEC_REF} with a token (raw.githubusercontent.com 404s private paths)"
git clone --depth 1 --branch "$SPEC_REF" \
"https://x-access-token:${TOKEN}@github.com/${SPEC_REPO}.git" "$OPENAPI" >/dev/null 2>&1
else
echo "cloning ${SPEC_REPO}@${SPEC_REF} over ssh; set SPEC_TOKEN/GH_TOKEN/GITHUB_TOKEN or OPENAPI to override"
git clone --depth 1 --branch "$SPEC_REF" "[email protected]:${SPEC_REPO}.git" "$OPENAPI" >/dev/null
fi
git clone --depth 1 -q https://git.hanzo.ai/hanzoai/openapi "$OPENAPI"
fi
# THE DOCUMENT AS AN ARGUMENT. hanzoai/ci's client: lane fetches openapi.yaml at
# the sha hanzoai/cloud just deployed and exports SPEC; the driver projects THAT
# rather than the checkout's own hanzo.yaml. With SPEC unset nothing changes —
# a maintainer regenerating by hand still gets the checkout's document.
# hanzoai/ci's client lane fetches the release document and exports SPEC, so it
# arrives by value, already digest-checked. Without it the driver reads this
# tree's own .spec-lock and fetches the same bytes from git.hanzo.ai, so a hand
# run and a CI run project the same document rather than whatever main is today.
if [ -n "${SPEC:-}" ]; then set -- --spec "$SPEC" "$@"; fi
exec python3 "$OPENAPI/generate.py" python --repo "$PWD" "$@"