Files
python-sdk/.hanzo/workflows/sync-from-github.yml
T
hanzo-dev 7896e36a7f
Hanzo CI/CD / cicd (push) Failing after 56s
CI/CD / cicd (push) Failing after 58s
delete the gate that could not run; start the one that can
We do not use GitHub Actions. `.github/workflows/cicd.yml` asked for
`hanzo-build-linux-amd64`, a label github.com serves with nothing, so every
caller queued 86402s — 24h exactly, GitHub's timeout — and reported
"cancelled". Not a broken gate: a gate on a platform we retired. Deleted rather
than repaired. A file that asserts coverage it cannot deliver is what let this
repo read green while nothing ran.

The forge is where CI lives, and this repo was not wired to it. Two things were
missing and the second is the interesting one.

`.hanzo/workflows/cicd.yml` — the ~7-line caller, hanzo.yml holds the config,
same shape as the sixteen other hanzoai repos already on this path.

And sync-from-github.yml could never have started it. It fast-forwards main
with the workflow token, which by design triggers no workflow, and compensates
by dispatching `deploy.yml` — a workflow this repo has never had, because these
are libraries that publish to PyPI and deploy nothing. The forge returned 404,
`|| echo "build dispatch failed (non-fatal)"` swallowed it, and the sync went
green ten minutes at a time. Every commit arrived having started nothing. That
is the third check this session that was believed and was not running, and it
is why the forge shows zero cicd.yml runs against 775 syncs.

It now names cicd.yml, and a failed dispatch fails the job.

hanzo.yml gains `duplicate-fields`: repeated AnnAssign targets in a class body,
read from the AST. 3.2.0 shipped `integration_config` and `removed_at` declared
twice each in O11yGettableAgentCheckIn — the second binding wins, the first
field silently does not exist, and the value on the wire was read and dropped.
The `cloud-client` import gate was green for it and always would be: measured
here, with the 3.2.0 model restored, it exits 0 and prints "models: 2172
modules imported". Its comment claimed it caught name collisions; that claim is
corrected rather than left to mislead.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-08-05 15:11:42 -07:00

72 lines
3.3 KiB
YAML

name: Sync from GitHub
# git.hanzo.ai is CANONICAL and builds natively; development also lands on
# github.com/hanzoai/python-sdk. Together with the push-mirror going the other way
# (native -> GitHub, sync_on_commit) this is the full bidirectional loop.
#
# The two compose rather than fight: a native commit reaches GitHub via the
# push-mirror, so this job then sees LOCAL == REMOTE and exits "in sync". A
# GitHub commit fast-forwards native here, and the resulting push-mirror is a
# no-op because GitHub already has it. No echo, no loop.
#
# ONE deterministic direction per job: an in-cluster PULL. The runner reaches
# both ends (GitHub outbound, this forge via the instance URL actions/checkout
# already uses), so the sync has no ingress dependency.
#
# Fast-forward ONLY. A divergence fails LOUDLY here rather than force-pushing
# either side and destroying whichever history lost the race.
on:
schedule:
- cron: '*/10 * * * *'
workflow_dispatch: {}
concurrency:
group: sync-from-github
cancel-in-progress: false
jobs:
ff-main:
runs-on: [hanzo-build-linux-amd64]
steps:
- name: Checkout main (full history for the ancestry check)
uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: true
- name: Fast-forward main from github.com/hanzoai/python-sdk
env:
GH_PAT: ${{ secrets.GH_PAT }}
run: |
set -euo pipefail
git fetch --quiet "https://x-access-token:${GH_PAT}@github.com/hanzoai/python-sdk.git" main
LOCAL="$(git rev-parse HEAD)"
REMOTE="$(git rev-parse FETCH_HEAD)"
if [ "$LOCAL" = "$REMOTE" ]; then
echo "in sync at $LOCAL"
exit 0
fi
if git merge-base --is-ancestor "$LOCAL" "$REMOTE"; then
echo "fast-forwarding $LOCAL -> $REMOTE"
git push origin "$REMOTE:refs/heads/main"
# A push made with the workflow token does NOT trigger other workflows
# (loop prevention), so synced commits would never build. Dispatch it
# explicitly — a real fast-forward means real commits arrived.
#
# It dispatched `deploy.yml`, which this repo does not have and never
# had: these are libraries, they publish to PyPI and deploy nothing.
# The forge answered 404 every time, `|| echo ... (non-fatal)` ate it,
# and the job went green. So every commit synced from GitHub landed
# here having triggered NOTHING, and the gate this repo declares in
# hanzo.yml has no runs at all to show for it.
#
# Name the workflow that exists, and let a failed dispatch fail the
# job. A sync that lands commits but cannot start the gate is the
# exact false green this whole exercise is about.
curl -fsS --max-time 20 -X POST \
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-H "Content-Type: application/json" \
"${{ github.server_url }}/v1/repos/${{ github.repository }}/actions/workflows/cicd.yml/dispatches" \
-d '{"ref":"main"}'
else
echo "DIVERGED: native $LOCAL is not an ancestor of GitHub $REMOTE." >&2
echo "Resolve by hand; this job will not force-push either side." >&2
exit 1
fi