Files
zeekayandHanzo Dev 999a5bcd75 ci: a runner label names the platform, not the org
hanzo-build-linux-amd64, lux-build-linux-amd64, zoo-build-linux-amd64 and
every other org-prefixed spelling all meant the same machine. Which org a
job belongs to does not change which host can build it, so the org bought
one pool name per org per arch and each could go stale on its own -- the
evo host alone answered to fourteen names for one label.

One vocabulary now: linux-amd64, linux-arm64, macos-arm64, win-amd64. The
generic labels every plain workflow uses (ubuntu-latest, self-hosted) are
untouched, so naive CI keeps working.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-08 12:08:05 -07:00

105 lines
3.9 KiB
YAML

name: Release
# Cuts the GitHub release for a v* tag, on the native runners
# (git.hanzo.ai → git-runner).
#
# This replaces the `release` job that lived inside .github/workflows/ci.yml,
# which named `runs-on: lux-build-amd64`. No runner on this forge carries that
# label — the pools are `lux-build-linux-<arch>` — and a job naming a label
# nothing carries does not fail, it waits. No tag has produced a release.
#
# It is a separate workflow rather than a tag-gated job inside CI so that the
# two can have the concurrency they each need: CI cancels superseded runs, a
# release must not be cancelled by whatever lands behind it. It therefore builds
# its own binaries rather than downloading CI's artifacts — the same matrix, run
# for the tag it is releasing.
on:
push:
tags: ['v*']
workflow_dispatch:
permissions:
contents: write
# A corrective tag supersedes a release still in flight. Keep the publisher on
# the newest immutable version instead of running obsolete tags in parallel.
# One release, one artifact. Keyed on the REF, not the repository: a repo-wide
# group means pushing v1.36.80 cancels v1.36.79's build, so a batch of tags
# leaves versions that promise an artifact nobody can pull. Re-running the same
# tag still supersedes its own run.
concurrency:
group: release-${{ github.repository }}-${{ github.ref }}
cancel-in-progress: true
jobs:
verify:
runs-on: [linux-amd64]
timeout-minutes: 30
env:
GOWORK: off
CGO_ENABLED: '0'
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup-go-for-project
# CI owns the expensive race gate for this commit. Repeating it here made
# two 18-minute crypto suites contend on shared runners and could exceed
# this job's 30-minute limit. Release still tests the exact tagged tree.
- run: go test -timeout=20m ./... -count=1
build:
needs: verify
# Cross-compilation, all from the one Linux runner: the matrix sets GOOS and
# GOARCH, it does not select a runner.
runs-on: [linux-amd64]
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
os: [linux, darwin, windows]
arch: [amd64, arm64]
exclude:
- os: windows
arch: arm64
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup-go-for-project
- name: Build ${{ matrix.os }}/${{ matrix.arch }}
env:
GOOS: ${{ matrix.os }}
GOARCH: ${{ matrix.arch }}
run: go build -v -o consensus-${{ matrix.os }}-${{ matrix.arch }} ./cmd/consensus
# v3, not v4+: this workflow runs on git.hanzo.ai, which presents as
# GHES, and the v4 action refuses outright -- "GHESNotSupportedError:
# @actions/artifact v2.0.0+ ... not currently supported on GHES". The
# job builds its artifact and then discards it at the last step, so a
# successful build reads as a failed run.
- uses: actions/upload-artifact@v3
with:
name: consensus-${{ matrix.os }}-${{ matrix.arch }}
path: consensus-${{ matrix.os }}-${{ matrix.arch }}
release:
needs: build
runs-on: [linux-amd64]
timeout-minutes: 20
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/download-artifact@v3
with:
path: dist/
- uses: softprops/action-gh-release@v2
with:
files: dist/**/*
# generate_release_notes is NOT set: it makes the action call
# POST <api>/repos/<o>/<r>/releases/generate-notes
# which is a GitHub-only endpoint. This forge does not route it and
# answers Go's bare `404 page not found`, which the action surfaces
# verbatim as `::error::404 page not found`. Everything builds, and
# then the release step alone fails -- so the run reads as a release
# problem when it is one unsupported flag.
draft: false
prerelease: false