mirror of
https://github.com/hanzoai/id.git
synced 2026-11-02 15:00:26 +00:00
The private fleet declarations moved from hanzoai to hanzo-inc; name the repository where it lives.
134 lines
6.8 KiB
YAML
134 lines
6.8 KiB
YAML
# Hanzo ID — the ONE file that says how this repo builds, gates and ships.
|
|
#
|
|
# The only workflow is `.hanzo/workflows/cicd.yml`, ~10 lines that import
|
|
# hanzoai/ci; everything real is here, and platform.hanzo.ai reads this same
|
|
# file. It replaces TWO image lanes that had drifted apart:
|
|
#
|
|
# .hanzo/workflows/deploy.yml the one that worked — buildx, two registry
|
|
# logins, a version read out of package.json and
|
|
# a post-push manifest check. Every line of it is
|
|
# something the reusable already does.
|
|
# .github/workflows/docker.yml a second lane on a plane with no runners for
|
|
# our labels. Already reduced to an echo, but it
|
|
# kept the shape of a build lane alive in a
|
|
# directory Hanzo Git cannot even read.
|
|
#
|
|
# Neither gated anything. This repo has 13 test files and 160 assertions and CI
|
|
# ran none of them, which is how `pkgs/shared/src/org.test.ts` sat RED on main
|
|
# while the code it tested was correct.
|
|
|
|
# Gates run DIRECTLY on the runner, not inside the image build. hanzoai/ci
|
|
# provisions Node 22 and enables corepack; corepack then reads `packageManager`
|
|
# from package.json, so the pnpm this uses is the SAME pnpm the Dockerfile
|
|
# activates — stated once, in package.json, rather than pinned again here.
|
|
#
|
|
# Four gates, because there are four different ways this repo breaks and one
|
|
# combined gate would report all of them as the same failure.
|
|
test:
|
|
- name: install
|
|
# --frozen-lockfile, deliberately stricter than the Dockerfile's
|
|
# `--frozen-lockfile=false`. The image build must not be blocked by a
|
|
# lockfile that drifted; CI is exactly where that drift should be caught.
|
|
run: |
|
|
set -e
|
|
corepack enable
|
|
pnpm install --frozen-lockfile
|
|
- name: typecheck
|
|
# Vite does NOT typecheck — `vite build` transpiles and strips types, so a
|
|
# type error ships a green image. This is the only thing in the pipeline
|
|
# that reads the types across all 7 workspace packages.
|
|
run: |
|
|
set -e
|
|
pnpm -r tc
|
|
- name: unit
|
|
# vitest over pkgs/**/src and apps/**/src (vitest.config.ts). 160 tests,
|
|
# including the org resolver that decides which brand a host authenticates
|
|
# as and which redirect_uri every social hop sends — the surface that
|
|
# produced days of "login is broken" and cannot be verified by looking at it.
|
|
run: |
|
|
set -e
|
|
pnpm test
|
|
- name: e2e
|
|
# The sign-in page as a person meets it: the built export in Chromium on
|
|
# hanzo.id and lux.id, at 1440 and 390 (apps/web/e2e). The runner image
|
|
# (hanzoai/ci runner/Dockerfile) bakes Chromium's shared libraries, and its
|
|
# sandbox refuses sudo, so no --with-deps. The browser matching this repo's
|
|
# @playwright/test goes where the job may write.
|
|
run: |
|
|
set -e
|
|
pnpm --filter @hanzo/id-web build
|
|
export PLAYWRIGHT_BROWSERS_PATH="$RUNNER_TEMP/ms-playwright"
|
|
pnpm --filter @hanzo/id-web exec playwright install chromium
|
|
pnpm e2e
|
|
|
|
images:
|
|
- name: id
|
|
context: .
|
|
dockerfile: Dockerfile
|
|
repo: ghcr.io/hanzoai/id
|
|
platforms: [linux/amd64]
|
|
# NO build secret, and none can be reintroduced without contradicting the
|
|
# Dockerfile: this image is brand-neutral and serves every brand's identity
|
|
# host, so a key chosen at build time attributes all of them to one tenant.
|
|
# It used to take PUBLISHABLE_KEY from KMS (`deploy/PUBLISHABLE_KEY`, env
|
|
# `prod`) and assert it landed in the bundle; the assertion is now the
|
|
# inverse — no publishable key may appear in dist at all.
|
|
#
|
|
# The keys live in the runtime config the pod is served with (SPA_INGEST_
|
|
# KEYRING on the id-tenant-catalog ConfigMap), one per org, and the browser
|
|
# picks its brand's through the same host resolution that already chooses the
|
|
# IAM application and the brand package.
|
|
# The version comes from package.json — hanzoai/ci's bin/imgver reads it as
|
|
# the declared floor, exactly as deploy.yml's `node -p require('./package.
|
|
# json').version` did, so a release is still a version bump and nothing about
|
|
# how this image is named changes.
|
|
#
|
|
# One difference worth stating: imgver takes max(declared, published)+1 patch
|
|
# when the declared version is ALREADY at the registry, where deploy.yml
|
|
# failed the build instead ("bump the version to cut a release"). Both refuse
|
|
# to put a second digest under a tag someone may already be pinning; this one
|
|
# publishes the next patch rather than going red on a docs commit.
|
|
#
|
|
# oci.hanzo.ai is still written to — the reusable crane-copies the exact tag
|
|
# set after the ghcr push. The PATH changes: deploy.yml pushed
|
|
# `oci.hanzo.ai/id`, the reusable writes the org-qualified
|
|
# `oci.hanzo.ai/hanzoai/id`, which is the fleet convention. Nothing live
|
|
# pulls either one; charts/app/values/hanzo/id.yaml pins
|
|
# `ghcr.io/hanzoai/id` by tag AND digest.
|
|
|
|
# The same export as a site: s3://hanzo-sites/hanzo/hanzo-id, served by the
|
|
# edge's staticFiles middleware on every identity host with /v1 and /.well-known
|
|
# left to cloud. apps/web/public/config.json is the per-host catalog and ingest
|
|
# keyring the SPA reads at boot -- the file the pod otherwise writes from its
|
|
# SPA_* env -- so the export needs no runtime of its own.
|
|
#
|
|
# The slug is hanzo-id, not id: `id` is a reserved label on the Sites plane
|
|
# (cloud apps/sites/reserved.go), so POST /v1/projects refuses it with 400 and
|
|
# the lane never publishes. hanzo.id's own name is the next one, as hanzo.team
|
|
# is hanzo-team.
|
|
site:
|
|
slug: hanzo-id
|
|
dir: apps/web/dist
|
|
build: corepack enable && pnpm install --frozen-lockfile && pnpm --filter @hanzo/id-web build
|
|
on: [main]
|
|
|
|
# No `deploy:` ON PURPOSE, and this is deploy.yml's own rule, not a new one.
|
|
#
|
|
# id is governed by Hanzo CD. The tag it runs is declared in
|
|
# hanzo-inc/universe (charts/app/values/hanzo/id.yaml, tag + digest together), and
|
|
# the in-cluster reconcile restores that within ~60-90s. A CI-side `kubectl
|
|
# patch` therefore CANNOT stick — and the reason to refuse it is not that it
|
|
# fails, it is that it LOOKS like it works: the patch applies, the pod rolls, and
|
|
# CD quietly puts the old tag back a minute later.
|
|
#
|
|
# It would also be actively wrong here. The reusable's deploy step guards a
|
|
# semver pin against a transient branch build by reading the current tag out of
|
|
# `infra/k8s/operator/crs/<svc>.yaml` — a path this service does not use — so the
|
|
# guard would not fire and a `sha-<short>-amd64` tag would be written over a
|
|
# reviewed semver+digest pin on the live sign-in surface for every property in
|
|
# the fleet.
|
|
#
|
|
# Build and deploy are separate concerns: this emits an immutable image, git
|
|
# declares desired state, CD applies it. To ship a build, set image.tag AND
|
|
# image.digest in universe and push.
|