mirror of
https://github.com/hanzoai/o11y.git
synced 2026-10-15 12:58:33 +00:00
The server moved off /api/vN; the integration suite, handler tests, install.sh's health wait and the docs still called the old tree. Claude-Session: https://claude.ai/code/session_01TUxvfuta1Z44KVNYuAz71F
113 lines
5.8 KiB
YAML
113 lines
5.8 KiB
YAML
# Canonical CI/CD config for hanzoai/o11y — the one file both the hanzoai/ci
|
|
# reusable (.hanzo/workflows/cicd.yml) and platform.hanzo.ai read.
|
|
#
|
|
# THE GATE AND THE IMAGE ARE ONE LANE, and that is the whole point of this file.
|
|
#
|
|
# They were four separate workflows — ci.yaml, cicd.yml, docker.yaml,
|
|
# docker-site.yaml — with no `needs:` between them, because separate workflows
|
|
# cannot have one. So they raced rather than ordered, and a red gate published
|
|
# an image anyway. Not hypothetically: v1.5.61, v1.5.62 and v1.5.63 were each
|
|
# built and pushed on a commit whose gate had ALREADY failed on that same
|
|
# commit, and production ran v1.5.62 for a week.
|
|
#
|
|
# v1.5.61 7faaa81 gate 35417 FAILURE image 35419 success
|
|
# v1.5.62 23945f7 gate 35624 FAILURE image 35625 success <- shipped
|
|
# v1.5.63 0a75f53 gate 46116 FAILURE image 46117 success
|
|
#
|
|
# This is the inverse of the usual CI complaint. A failed publish that looks
|
|
# like a release is loud; a failed GATE that still produces one is silent, and
|
|
# the artifact it leaves behind is a claim that the commit passed.
|
|
#
|
|
# The fix is not to wire four workflows together — that is a second mechanism to
|
|
# keep in step, and the one thing worse than a gate nobody runs is two that
|
|
# disagree. `images:` lives here instead, so the shared lane's single sequential
|
|
# job runs `test:` and only then builds: one job, one order, no wiring.
|
|
#
|
|
# The blocker this file used to record — "docker.yaml mounts a `gh_token` build
|
|
# secret the Dockerfile needs for the PRIVATE hanzoai/sqlite + hanzoai/datastore-go
|
|
# modules" — is stale. The shared lane mounts that secret on every image build
|
|
# from KMS (falling back to the org GH_PAT), which is the same BuildKit
|
|
# `gh_token` this Dockerfile already reads. Nothing had to be given up to fold.
|
|
#
|
|
# `version:` names the release both images publish. bin/imgver publishes it
|
|
# verbatim when it is above what the registry holds, and the next patch of the
|
|
# registry's highest once it is not, so it is stated once and never needs
|
|
# chasing. It is stated at all because each image's series is its own: o11y had
|
|
# reached 1.5.88 and o11y-site 1.5.82 while the git tags stopped at v1.5.75, so
|
|
# derived numbers disagreed between the two images and a git tag — which
|
|
# publishes its own name verbatim, with nothing refusing an existing one — would
|
|
# have overwritten an August image of the same number. Release from main.
|
|
version: 1.5.89
|
|
|
|
images:
|
|
# The headless server (./cmd/community, O11Y_WEB_ENABLED=false). This is the
|
|
# image cloud embeds and the one serving /v1/o11y in production.
|
|
- name: o11y
|
|
context: .
|
|
dockerfile: Dockerfile
|
|
repo: ghcr.io/hanzoai/o11y
|
|
args:
|
|
# The Dockerfile ldflags these into pkg/version, so the binary can name
|
|
# its own release. They are per-build values, so they are the shared
|
|
# lane's placeholders rather than fixed strings — spelled out because an
|
|
# image reporting `dev` while its tag reads v1.5.64 is an image that
|
|
# cannot answer "which build is this", and this one is the thing the rest
|
|
# of the estate asks that question WITH.
|
|
VERSION: "${VERSION}"
|
|
COMMIT_HASH: "${SHA}"
|
|
BUILD_TIME: "${BUILD_TIME}"
|
|
BRANCH: "${BRANCH}"
|
|
VARIANT: community
|
|
|
|
# The browser SPA (frontend/), served by hanzoai/static at the edge while
|
|
# /v1/o11y/* goes to the server above. Takes no build-args and no secrets.
|
|
#
|
|
# It builds on every push now, where docker-site.yaml filtered on
|
|
# `paths: [Dockerfile.site, frontend/**]`. That filter is not expressible in
|
|
# the shared lane and is not worth reintroducing: it saves build minutes by
|
|
# deciding, from a diff, that a commit cannot have broken the SPA — which is
|
|
# the same reasoning that let a red gate ship an image.
|
|
- name: o11y-site
|
|
context: .
|
|
dockerfile: Dockerfile.site
|
|
repo: ghcr.io/hanzoai/o11y-site
|
|
|
|
# The console reaches o11y.hanzo.ai off the Sites plane, not off an image: the
|
|
# ingress serves s3://hanzo-sites/hanzo/o11y-site (universe static-sites.yaml,
|
|
# o11y-site-static) and /v1/o11y alone reaches the pod. The o11y-site image
|
|
# above builds the same export and nothing routes to it; this is the lane that
|
|
# puts the console live. A release tag publishes; so does main.
|
|
site:
|
|
slug: o11y-site
|
|
dir: frontend/build
|
|
build: cd frontend && pnpm install --frozen-lockfile && pnpm build
|
|
on: [main]
|
|
|
|
# The pair that has been green on this fleet already. `go build ./...` fails
|
|
# fast on a break; the test run is `-count=1` so nothing is served from cache,
|
|
# and it skips nothing — a suite the gate is allowed to exclude from is a suite
|
|
# the gate does not measure.
|
|
#
|
|
# There was one skip, `-skip '^TestEmailRejected$'`, and it was stale the day it
|
|
# was written. It blamed emersion/go-smtp v0.24.0 for an error string formatted
|
|
# with quotes. The quoting was Go's own: 1.26 changed net/textproto.Error.Error
|
|
# to `%03d %q`. ef13a025e8 had already stopped the test asserting on rendered
|
|
# text ten days earlier — it unwraps to *textproto.Error and pins Code 501 and
|
|
# Msg "5.5.4 Rejected!" — so there was nothing left to be wrong about. Measured
|
|
# before removing: go test -count=10 -run '^TestEmailRejected$' passes against
|
|
# the pinned v0.24.0, and the full suite passes with no skip at all.
|
|
#
|
|
# This block used to be duplicated in .hanzo/workflows/ci.yaml, which also
|
|
# checked out hanzoai/cloud at a pinned SHA to satisfy a
|
|
# `replace github.com/hanzoai/cloud => ../cloud`. That replace is GONE from
|
|
# go.mod — the module no longer depends on cloud at all — so the checkout was
|
|
# fetching a pinned commit of an unrelated repo to support a directive that no
|
|
# longer exists, and a second gate that can go red for a reason having nothing
|
|
# to do with this repo is how a fleet learns to ignore red.
|
|
test:
|
|
- name: build
|
|
run: |
|
|
set -e
|
|
go build ./...
|
|
go test -count=1 ./...
|