headroom/.github/workflows
Rod Boev 5568d738af
fix(ci): publish latest from the root Docker manifest (#2252)
## Description

A successful root Docker image can miss `:latest` when any optional
variant manifest fails. The release workflow currently gates the
standalone `promote-latest` job on the aggregate `docker-manifest`
matrix, so one sibling failure skips promotion even when the signed root
amd64+arm64 manifest exists.

This moves `:latest` promotion into the successful root manifest cell.
Optional variant failures remain visible and continue to fail their
jobs, but they no longer suppress the image used by `headroom install`,
which defaults to `ghcr.io/headroomlabs-ai/headroom:latest`.

Refs #1583

## Type of Change

- [x] Bug fix (non-breaking change that fixes an issue)
- [ ] New feature (non-breaking change that adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Documentation update
- [ ] Performance improvement
- [ ] Code refactoring (no functional changes)

## Changes Made

- Publish `:latest` from the root `docker-manifest` matrix cell after
its versioned multi-architecture manifest is created and signed.
- Remove the aggregate `promote-latest` dependency that allowed
unrelated variant failures to suppress publication.
- Keep all existing root, slim, code, and nonroot variants.
- Preserve native linux/amd64 and linux/arm64 manifest assembly.
- Add a focused workflow-contract regression test.

## Testing

- [x] Unit tests pass (`uv run pytest tests/test_release_workflows.py -q
-k "docker or latest"`)
- [x] Linting passes (`uv run ruff check
tests/test_release_workflows.py`)
- [x] Formatting passes (`uv run ruff format --check
tests/test_release_workflows.py`)
- [x] New tests added for new functionality
- [ ] Manual testing performed

### Test Output

```text
Focused checks pass: `5 passed, 34 deselected` for `uv run pytest tests/test_release_workflows.py -q -k "docker or latest"`; the full test file has one unrelated Windows `FileNotFoundError` in `test_no_native_tls_in_wheel_build_tree` because its external command is unavailable. `uv run ruff check tests/test_release_workflows.py` and `uv run ruff format tests/test_release_workflows.py --check` pass. The repository-wide format check reports eight pre-existing files outside this target. Proof report: `D:\Repos\.claude\pr-sweep\headroom-PR-TARGET-1583-PROOF.md`.
```

## Real Behavior Proof

- Environment: Windows, Python managed by `uv`, repository
workflow-contract tests; production publication owned by GitHub Actions
and GHCR.
- Exact command / steps: run the focused release-workflow tests; after
merge, inspect the next Docker release run and execute `docker buildx
imagetools inspect ghcr.io/headroomlabs-ai/headroom:latest` without
registry login.
- Observed result: local workflow-contract proof passes for root-owned
promotion and both native architecture inputs; live GHCR publication
remains unverified until the next release.
- Not tested: production GHCR publication before merge.

## Review Readiness

- [x] I have performed a self-review
- [x] This PR is ready for human review

## Checklist

- [ ] My code follows the project's style guidelines
- [ ] I have performed a self-review of my code
- [x] Workflow comments explain the non-obvious root-only promotion
boundary
- [x] Documentation outside the changelog is unchanged because the CLI
image reference is already correct
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective
- [x] New and existing focused tests pass locally with my changes

## Screenshots (if applicable)

Not applicable.

## Additional Notes

Release run
https://github.com/headroomlabs-ai/headroom/actions/runs/28404020512
demonstrated the cascade: the root manifest succeeded, a nonroot
manifest failed during Buildx setup, and `promote-latest` was skipped.

PR CI can prove the workflow dependency and architecture-preservation
contracts. GHCR availability and anonymous package visibility require
the next production release plus an unauthenticated registry inspection.
2026-08-11 23:40:02 -05:00
..
changelog-guard.yml ci(changelog): stop the CHANGELOG cascade — release-please owns it (#2329) 2026-07-16 14:28:57 -07:00
ci.yml fix(ci): restrict Codecov shard uploads (#2745) 2026-08-03 14:20:17 -07:00
devcontainers.yml ci: bump actions/checkout from 4 to 7 (#1414) 2026-07-09 11:09:14 -05:00
docker.yml fix(ci): publish latest from the root Docker manifest (#2252) 2026-08-11 23:40:02 -05:00
docs.yml chore(docs): one documentation site, not two (#2784) 2026-08-04 16:42:49 -07:00
eval.yml feat(evals): weekly HotpotQA answer-recall report on the prose path (#1188) 2026-07-15 21:40:55 +00:00
init-e2e.yml ci: scope native/wheel/dashboard jobs to relevant paths (unstarve the queue) (#2155) 2026-07-13 23:50:26 -04:00
init-native-e2e.yml ci: bump actions/checkout from 4 to 7 (#1414) 2026-07-09 11:09:14 -05:00
install-native-e2e.yml ci: bump actions/checkout from 4 to 7 (#1414) 2026-07-09 11:09:14 -05:00
merge-conflicts.yml ci: concurrency-cancel Docker + Merge Conflicts to stop merge-spree pileups (#2138) 2026-07-13 13:47:59 -04:00
network-diff-capture.yml ci: require ONNX Runtime >= 1.24 and fail fast when it is missing or too old (#2591) 2026-07-27 08:04:53 -07:00
opencode-plugin.yml fix(opencode): ship the transport hook-shim so wheel installs route Node child traffic 2026-08-11 09:10:38 -07:00
pr-health.yml ci: preserve merge labels while state is unknown 2026-07-09 19:51:41 -05:00
publish.yml ci: bump actions/checkout from 4 to 7 (#1414) 2026-07-09 11:09:14 -05:00
release-metadata-sync.yml fix(release): sync generated version metadata on the release branch (#2659) 2026-07-29 15:12:04 -07:00
release-please.yml ci(release-please): use a PAT so releases trigger the publish workflows (#1920) 2026-07-09 09:07:19 -07:00
release.yml fix(release): publish Windows wheel + sdist (disable PyPI attestations, #112) (#2405) 2026-07-18 20:56:31 -07:00
rust.yml ci: require ONNX Runtime >= 1.24 and fail fast when it is missing or too old (#2591) 2026-07-27 08:04:53 -07:00
security.yml ci: bump actions/checkout from 4 to 7 (#1414) 2026-07-09 11:09:14 -05:00
stale.yml ci: bump actions/stale from 9 to 10 (#850) 2026-06-11 12:53:46 -05:00
wrap-e2e.yml fix: remove rtk and lean-ctx CLI context tools (#2677) 2026-07-30 22:59:41 -07:00
wrap-native-e2e.yml fix: remove rtk and lean-ctx CLI context tools (#2677) 2026-07-30 22:59:41 -07:00