mirror of
https://github.com/hanzoai/kms.git
synced 2026-10-17 11:18:16 +00:00
ci: run every lane on the forge, leave sync.yml on the mirror
git.hanzo.ai is canonical and reads .hanzo/workflows, so build.yml, build-kms-fetch.yml and pr-preview.yml move there by changing directory and nothing else — same GitHub Actions syntax, same runs-on, byte-identical files. Three more lanes had been deleted from .github/workflows without a replacement anywhere, which silently removed this repo's only gate and the only producer of its release binaries and semver image tags. There was no red run to show it, because a workflow that does not exist cannot fail. Restored byte-for-byte from history at the path the forge reads: ci.yml go test -race ./... + builds kmsd and kms release.yml v* tags: 4-way binary matrix, release, multi-arch image check-fe-ts-and-lint.yml frontend typecheck on PRs release.yml's notify-universe job is left exactly as it was; it is already continue-on-error, so a missing UNIVERSE_DISPATCH_TOKEN on the forge degrades to a yellow job instead of failing the release. Not restored: validate-pr-title.yml, a conventional-commit title gate inherited with an upstream PR template. Dropped: workflow-sanity.yml, which triggers on paths .github/workflows/** and so can never fire again once the lanes live under .hanzo. Neither builds, tests or publishes anything. sync.yml is replaced with the canonical copy — the variant here predated it and had drifted. Co-authored-by: Hanzo Dev <[email protected]>
This commit is contained in:
+87
-45
@@ -1,60 +1,102 @@
|
||||
name: Sync to git.hanzo.ai
|
||||
# DIRECTION: this repo on git.hanzo.ai is a PULL MIRROR fetching github.com/hanzoai/kms.
|
||||
# GitHub is UPSTREAM, git.hanzo.ai is DOWNSTREAM. The giveaway is what this file does:
|
||||
# mirror-sync tells Gitea to PULL, which only makes sense if GitHub is the source.
|
||||
name: sync
|
||||
|
||||
# Carries pushed refs to git.hanzo.ai, the canonical forge, and does nothing
|
||||
# else: build, test and release run natively there.
|
||||
#
|
||||
# This matters beyond labeling: a pull mirror force-updates its refs from upstream on
|
||||
# every fetch, so anything committed directly on git.hanzo.ai is DISCARDED on the next
|
||||
# sync. Do not treat the mirror as writable, and do not reword this into a "native on
|
||||
# git.hanzo.ai" claim — that is the intended end state, not today's.
|
||||
#
|
||||
# What IS true: CI/CD runs on git.hanzo.ai — arcd executes .hanzo/workflows/ on the
|
||||
# Hanzo git-runner. Making git.hanzo.ai canonical means converting the repo
|
||||
# pull-mirror -> native and flipping the write path; an ops migration, not a config edit.
|
||||
#
|
||||
# So this nudge is a LATENCY fix, not a canonicality one: it asks Gitea to pull now
|
||||
# instead of waiting out the ~10-minute mirror interval, so arcd sees the new commit
|
||||
# sooner. Without this file the repo still mirrors — just later.
|
||||
#
|
||||
# IDEMPOTENT: mirror-sync just tells Gitea to pull HEAD, so N nudges == 1 (same latest
|
||||
# state); concurrency coalesces a burst of pushes to a single in-flight sync. FAST: no
|
||||
# checkout, one bounded curl, hard timeouts. FAIL-SOFT: a missing token or hiccup never
|
||||
# fails the push (the App webhook still mirrors). Set HANZO_GIT_TOKEN to enable the nudge.
|
||||
# Repo-agnostic. owner/name come from ${{ github.repository }}, so this file is
|
||||
# dropped into every repo unchanged as .github/workflows/sync.yml and is the
|
||||
# only workflow GitHub is permitted to run.
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
# '**' matches slashes; '*' does not, and would skip feature/foo.
|
||||
branches: ['**']
|
||||
tags: ['**']
|
||||
workflow_dispatch:
|
||||
|
||||
# Only the newest push's sync needs to run — cancel any older in-flight one (it would
|
||||
# pull a now-stale HEAD). This is what makes rapid pushes idempotent + cheap.
|
||||
# Serialize per ref. Never cancel: a cancelled run drops that ref and nothing
|
||||
# reconciles it afterwards.
|
||||
concurrency:
|
||||
group: sync-git-hanzo-ai
|
||||
cancel-in-progress: true
|
||||
group: sync-${{ github.ref }}
|
||||
cancel-in-progress: false
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
sync:
|
||||
# `.github/workflows` is also on Gitea's WORKFLOW_DIRS, so with Actions enabled on
|
||||
# the mirror this file runs THERE too on every sync — where asking git.hanzo.ai to
|
||||
# pull is circular. github.server_url is setting.AppURL on Gitea
|
||||
# (services/actions/context.go:89), so this is the exact test for "am I upstream".
|
||||
if: ${{ github.server_url == 'https://github.com' }}
|
||||
# .github/workflows is also on the forge's own workflow search path, so this
|
||||
# file executes there too in any repo without .hanzo/workflows, where it
|
||||
# would push the forge to itself. server_url is the forge's AppURL, which
|
||||
# makes this the test for "running on GitHub".
|
||||
if: github.server_url == 'https://github.com'
|
||||
# GitHub-hosted on purpose. This is the one workflow that must run ON GitHub,
|
||||
# and the self-hosted pool that used to serve it is retired — a job asking for
|
||||
# it now queues forever against a label nothing answers. Carrying refs is a
|
||||
# push, not a build, so it does not belong on the build fabric anyway: builds
|
||||
# run natively on git.hanzo.ai, which is the whole point of this file.
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 2
|
||||
timeout-minutes: 15
|
||||
|
||||
steps:
|
||||
- name: Nudge git.hanzo.ai to pull HEAD (mirror-sync)
|
||||
continue-on-error: true
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-tags: true
|
||||
persist-credentials: false
|
||||
|
||||
- name: Push refs to git.hanzo.ai
|
||||
env:
|
||||
HANZO_GIT_TOKEN: ${{ secrets.HANZO_GIT_TOKEN }}
|
||||
FORGE: https://git.hanzo.ai
|
||||
GIT_TOKEN: ${{ secrets.GIT_TOKEN }}
|
||||
run: |
|
||||
set -u
|
||||
if [ -z "${HANZO_GIT_TOKEN:-}" ]; then
|
||||
echo "HANZO_GIT_TOKEN not set — relying on the mirror App webhook. Skipping nudge."
|
||||
exit 0
|
||||
set -euo pipefail
|
||||
|
||||
if [ -z "${GIT_TOKEN}" ]; then
|
||||
echo "::error::GIT_TOKEN is unset, so this push never reached the canonical forge. Add the org secret."
|
||||
exit 1
|
||||
fi
|
||||
if curl -fsS --max-time 20 --retry 2 --retry-delay 2 -X POST \
|
||||
-H "Authorization: token ${HANZO_GIT_TOKEN}" \
|
||||
"https://git.hanzo.ai/api/v1/repos/hanzoai/kms/mirror-sync"; then
|
||||
echo "git.hanzo.ai mirror-sync triggered"
|
||||
else
|
||||
echo "mirror-sync nudge failed (non-fatal) — the App webhook still mirrors"
|
||||
|
||||
REMOTE="${FORGE}/${GITHUB_REPOSITORY}.git"
|
||||
|
||||
# The forge reads the token from the basic-auth password and ignores
|
||||
# the username. base64 of a secret is not masked automatically.
|
||||
AUTH="$(printf 'x-access-token:%s' "${GIT_TOKEN}" | base64 -w0)"
|
||||
echo "::add-mask::${AUTH}"
|
||||
# Host-scoped, so the forge token is never sent to github.com.
|
||||
git config --local "http.${FORGE}/.extraheader" "Authorization: Basic ${AUTH}"
|
||||
|
||||
# Reachability is the only transient failure here, so it is the only
|
||||
# thing retried. ls-remote exits 0 on an existing empty repo and
|
||||
# non-zero when the forge is down or the repo is absent.
|
||||
ERR="$(mktemp)"
|
||||
REACHED=""
|
||||
for attempt in 1 2 3; do
|
||||
if git ls-remote "${REMOTE}" >/dev/null 2>"${ERR}"; then
|
||||
REACHED=1
|
||||
break
|
||||
fi
|
||||
echo "forge probe failed (attempt ${attempt}/3): $(cat "${ERR}")"
|
||||
if [ "${attempt}" -lt 3 ]; then
|
||||
sleep $((attempt * 5))
|
||||
fi
|
||||
done
|
||||
if [ -z "${REACHED}" ]; then
|
||||
echo "::error::git.hanzo.ai is unreachable or ${GITHUB_REPOSITORY} does not exist there. $(cat "${ERR}")"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Additive and fast-forward-only: no leading '+', no --force, no
|
||||
# --prune, no --mirror. Tags go every run so a tag that missed its own
|
||||
# event still lands; git refuses to move one that already differs.
|
||||
REFS=('refs/tags/*:refs/tags/*')
|
||||
case "${GITHUB_REF}" in
|
||||
refs/heads/*) REFS+=("${GITHUB_REF}:${GITHUB_REF}") ;;
|
||||
esac
|
||||
|
||||
# Not --atomic: a diverged ref must not hold back the refs that are
|
||||
# clean. Rejections still fail the job.
|
||||
if ! git push "${REMOTE}" "${REFS[@]}"; then
|
||||
echo "::error::git.hanzo.ai rejected a ref for ${GITHUB_REPOSITORY}. The forge is canonical and is never force-updated from here; reconcile the diverged branch or tag by hand."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
name: Workflow Sanity
|
||||
on:
|
||||
pull_request:
|
||||
paths: ['.github/workflows/**']
|
||||
jobs:
|
||||
sanity:
|
||||
uses: hanzoai/.github/.github/workflows/workflow-sanity.yml@main
|
||||
@@ -0,0 +1,35 @@
|
||||
name: Check Frontend Type and Lint check
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize]
|
||||
paths:
|
||||
- "frontend/**"
|
||||
- "!frontend/README.md"
|
||||
- "!frontend/.*"
|
||||
- "frontend/.eslintrc.js"
|
||||
|
||||
jobs:
|
||||
check-fe-ts-lint:
|
||||
name: Check Frontend Type and Lint check
|
||||
runs-on: hanzo-build-linux-amd64
|
||||
timeout-minutes: 15
|
||||
|
||||
steps:
|
||||
- name: Checkout source
|
||||
uses: actions/checkout@v4
|
||||
- uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 9.15.4
|
||||
- name: Setup Node 22
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "22"
|
||||
cache: "pnpm"
|
||||
cache-dependency-path: frontend/pnpm-lock.yaml
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
working-directory: frontend
|
||||
- name: Type check
|
||||
run: pnpm run typecheck
|
||||
working-directory: frontend
|
||||
@@ -0,0 +1,39 @@
|
||||
name: CI Pipeline
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["*"]
|
||||
pull_request:
|
||||
branches: ["*"]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: hanzo-build-linux-amd64
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: "1.26"
|
||||
|
||||
- name: Cache Go modules
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ hashFiles('go.sum') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-go-
|
||||
|
||||
- name: Download dependencies
|
||||
run: go mod download
|
||||
|
||||
- name: Run unit tests
|
||||
run: go test -v -race ./...
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
CGO_ENABLED=0 go build -v ./cmd/kmsd
|
||||
CGO_ENABLED=0 go build -v ./cmd/kms
|
||||
@@ -0,0 +1,221 @@
|
||||
name: Release
|
||||
|
||||
# Multi-arch release pipeline triggered by semver tags.
|
||||
#
|
||||
# Produces:
|
||||
# * kms-{linux,darwin}-{amd64,arm64} — admin CLI (cmd/kms)
|
||||
# * kmsd-{linux,darwin}-{amd64,arm64} — server daemon (cmd/kmsd)
|
||||
# * ghcr.io/hanzoai/kms:vX.Y.Z — multi-arch manifest
|
||||
#
|
||||
# Uses GitHub-hosted runners exclusively (ubuntu-24.04 / ubuntu-24.04-arm /
|
||||
# macos-14 / macos-14). The legacy backend/ kms-core binaries are still
|
||||
# produced by build-binaries.yml — this workflow only covers the Go CLI
|
||||
# + daemon.
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag:
|
||||
description: 'Tag to release (e.g. v1.0.0). Must already exist.'
|
||||
required: true
|
||||
type: string
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
packages: write
|
||||
id-token: write
|
||||
|
||||
jobs:
|
||||
binaries:
|
||||
name: Build binaries (${{ matrix.goos }}/${{ matrix.goarch }})
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- goos: linux
|
||||
goarch: amd64
|
||||
runner: hanzo-build-linux-amd64
|
||||
- goos: linux
|
||||
goarch: arm64
|
||||
runner: ubuntu-24.04-arm
|
||||
- goos: darwin
|
||||
goarch: amd64
|
||||
runner: macos-14
|
||||
- goos: darwin
|
||||
goarch: arm64
|
||||
runner: macos-14
|
||||
runs-on: ${{ matrix.runner }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ inputs.tag || github.ref }}
|
||||
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
cache-dependency-path: go.sum
|
||||
|
||||
- name: Resolve version
|
||||
id: version
|
||||
run: |
|
||||
ref="${{ inputs.tag || github.ref_name }}"
|
||||
echo "tag=${ref}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Build kms + kmsd (${{ matrix.goos }}/${{ matrix.goarch }})
|
||||
env:
|
||||
CGO_ENABLED: '0'
|
||||
GOOS: ${{ matrix.goos }}
|
||||
GOARCH: ${{ matrix.goarch }}
|
||||
GOEXPERIMENT: jsonv2
|
||||
VERSION: ${{ steps.version.outputs.tag }}
|
||||
# luxfi (+ hanzoai) modules are first-party/private: resolve them
|
||||
# directly via git and skip the public checksum DB — force-moved
|
||||
# upstream tags never match sum.golang.org. GH_PAT carries luxfi read
|
||||
# access; the repo GITHUB_TOKEN is the fallback for public modules.
|
||||
GOPRIVATE: github.com/luxfi/*,github.com/hanzoai/*
|
||||
GONOSUMDB: github.com/luxfi/*,github.com/hanzoai/*
|
||||
GH_PAT: ${{ secrets.GH_PAT }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
token="${GH_PAT:-$GITHUB_TOKEN}"
|
||||
if [ -n "$token" ]; then
|
||||
git config --global url."https://x-access-token:${token}@github.com/".insteadOf "https://github.com/"
|
||||
fi
|
||||
mkdir -p dist
|
||||
go build -trimpath \
|
||||
-ldflags="-s -w -X main.version=${VERSION}" \
|
||||
-o "dist/kms-${GOOS}-${GOARCH}" ./cmd/kms
|
||||
go build -trimpath \
|
||||
-ldflags="-s -w -X main.version=${VERSION}" \
|
||||
-o "dist/kmsd-${GOOS}-${GOARCH}" ./cmd/kmsd
|
||||
# shasum is available on both linux and macos runners
|
||||
(cd dist && shasum -a 256 "kms-${GOOS}-${GOARCH}" "kmsd-${GOOS}-${GOARCH}" \
|
||||
> "kms-${GOOS}-${GOARCH}.sha256")
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: binaries-${{ matrix.goos }}-${{ matrix.goarch }}
|
||||
path: dist/*
|
||||
if-no-files-found: error
|
||||
retention-days: 7
|
||||
|
||||
github-release:
|
||||
name: GitHub Release
|
||||
needs: [binaries]
|
||||
runs-on: hanzo-build-linux-amd64
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ inputs.tag || github.ref }}
|
||||
fetch-depth: 0
|
||||
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: dist
|
||||
merge-multiple: true
|
||||
|
||||
- name: Resolve version
|
||||
id: version
|
||||
run: |
|
||||
ref="${{ inputs.tag || github.ref_name }}"
|
||||
echo "tag=${ref}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Create GitHub Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
tag_name: ${{ steps.version.outputs.tag }}
|
||||
name: ${{ steps.version.outputs.tag }}
|
||||
generate_release_notes: true
|
||||
files: |
|
||||
dist/kms-linux-amd64
|
||||
dist/kms-linux-arm64
|
||||
dist/kms-darwin-amd64
|
||||
dist/kms-darwin-arm64
|
||||
dist/kmsd-linux-amd64
|
||||
dist/kmsd-linux-arm64
|
||||
dist/kmsd-darwin-amd64
|
||||
dist/kmsd-darwin-arm64
|
||||
dist/kms-linux-amd64.sha256
|
||||
dist/kms-linux-arm64.sha256
|
||||
dist/kms-darwin-amd64.sha256
|
||||
dist/kms-darwin-arm64.sha256
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
docker:
|
||||
name: Multi-arch Docker (ghcr.io/hanzoai/kms)
|
||||
needs: [binaries]
|
||||
runs-on: hanzo-build-linux-amd64
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
id-token: write
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ inputs.tag || github.ref }}
|
||||
|
||||
- name: Resolve version
|
||||
id: version
|
||||
run: |
|
||||
ref="${{ inputs.tag || github.ref_name }}"
|
||||
echo "tag=${ref}" >> "$GITHUB_OUTPUT"
|
||||
echo "semver=${ref#v}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- uses: docker/setup-qemu-action@v3
|
||||
- uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to GHCR
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push multi-arch image
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: Dockerfile
|
||||
platforms: linux/amd64,linux/arm64
|
||||
provenance: false
|
||||
push: true
|
||||
tags: |
|
||||
ghcr.io/hanzoai/kms:${{ steps.version.outputs.tag }}
|
||||
ghcr.io/hanzoai/kms:${{ steps.version.outputs.semver }}
|
||||
ghcr.io/hanzoai/kms:latest
|
||||
build-args: |
|
||||
GO_EXPERIMENT=jsonv2
|
||||
GITHUB_TOKEN=${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
|
||||
notify-universe:
|
||||
name: Notify universe (auto-bump pin)
|
||||
needs: [docker]
|
||||
runs-on: hanzo-build-linux-amd64
|
||||
if: github.repository == 'hanzoai/kms'
|
||||
continue-on-error: true
|
||||
steps:
|
||||
- name: Resolve version
|
||||
id: version
|
||||
run: |
|
||||
ref="${{ inputs.tag || github.ref_name }}"
|
||||
echo "tag=${ref}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Repository dispatch
|
||||
uses: peter-evans/repository-dispatch@v3
|
||||
with:
|
||||
token: ${{ secrets.UNIVERSE_DISPATCH_TOKEN }}
|
||||
repository: hanzoai/universe
|
||||
event-type: kms
|
||||
client-payload: |
|
||||
{
|
||||
"service": "kms",
|
||||
"version": "${{ steps.version.outputs.tag }}",
|
||||
"image": "ghcr.io/hanzoai/kms:${{ steps.version.outputs.tag }}",
|
||||
"sha": "${{ github.sha }}"
|
||||
}
|
||||
@@ -37,8 +37,44 @@ KMS_ENV=dev ./kmsd # HTTP :8443, ZAP :9999 (dev tolerates missing JWT config
|
||||
|
||||
Non-`dev`/`devnet`/`local` `KMS_ENV` refuses to boot without
|
||||
`KMS_EXPECTED_ISSUER` + `KMS_EXPECTED_AUDIENCE` + `KMS_JWKS_URL`. Fail-closed.
|
||||
CI: `hanzoai/.github/.github/workflows/docker-build.yml@main` → `ghcr.io/hanzoai/kms`,
|
||||
`linux/amd64` on the `hanzo-build-linux-amd64` ARC pool, semver `v*` tags (never `:latest`).
|
||||
|
||||
## How this ships
|
||||
|
||||
One way, and it runs on our own stack:
|
||||
|
||||
push -> github.com/hanzoai/kms (a mirror)
|
||||
.github/workflows/sync.yml carries refs onward
|
||||
-> git.hanzo.ai/hanzoai/kms CANONICAL
|
||||
.hanzo/workflows/ci.yml go test -race + builds kmsd/kms
|
||||
.hanzo/workflows/build.yml ghcr.io/hanzoai/kms on main
|
||||
.hanzo/workflows/release.yml v* tags: binaries + release + image
|
||||
.hanzo/workflows/build-kms-fetch.yml ghcr.io/hanzoai/kms-fetch
|
||||
.hanzo/workflows/check-fe-ts-and-lint.yml frontend typecheck on PRs
|
||||
.hanzo/workflows/pr-preview.yml ephemeral PR preview env
|
||||
|
||||
**git.hanzo.ai is canonical; GitHub is a mirror.** `.github/workflows/` holds
|
||||
exactly one file, `sync.yml`, and its only job is getting refs to the forge. Every
|
||||
build, check and deploy is a workflow under `.hanzo/workflows/`, which the forge
|
||||
reads. `.hanzo/workflows` uses GitHub Actions syntax, so a workflow moves between
|
||||
the two by changing directory and nothing else.
|
||||
|
||||
`ci.yml`, `release.yml` and `check-fe-ts-and-lint.yml` had been deleted from
|
||||
`.github/workflows` with no replacement anywhere — which silently removed the
|
||||
repo's only gate and the only producer of the release binaries and semver image
|
||||
tags, with no red run to show it, because a workflow that does not exist cannot
|
||||
fail. They are restored here at the path the forge reads.
|
||||
|
||||
`release.yml` is the heaviest lane: a 4-way binary matrix
|
||||
(linux/darwin × amd64/arm64) for `cmd/kms` + `cmd/kmsd`, a GitHub Release with
|
||||
12 assets, a multi-arch `ghcr.io/hanzoai/kms:{vX.Y.Z, X.Y.Z, latest}`, and a
|
||||
final best-effort `notify-universe` job. That last job is
|
||||
`continue-on-error: true`, so a missing `UNIVERSE_DISPATCH_TOKEN` on the forge
|
||||
degrades to a yellow job and never fails the release.
|
||||
|
||||
`build.yml`, `build-kms-fetch.yml` and `pr-preview.yml` are thin callers of
|
||||
`hanzoai/.github/.github/workflows/*@main`. Those references resolve by path, so
|
||||
they break the day the reusable workflows themselves move to `.hanzo/workflows` —
|
||||
worth inlining then, not now.
|
||||
|
||||
## Entry points
|
||||
|
||||
|
||||
Reference in New Issue
Block a user