ci/fleet-operator-release-pipeline #300

Open
johnride wants to merge 6 commits from ci/fleet-operator-release-pipeline into master
Owner
No description provided.
johnride added 3 commits 2026-05-26 19:03:34 +00:00
One git tag `harmony-fleet-operator-v*` now produces both the
container image and a hydrated helm chart at the same version,
pushed to hub.nationtech.io. release.sh is a 5-line wrapper around a
new `harmony-fleet-operator-release` binary in harmony-fleet-deploy
that orchestrates docker build/push, chart hydration via the
existing `build_chart()`, and `helm package`/`helm push`. CI is
reduced to a thin trigger calling the same script developers run
locally.

- chart.rs: ChartOptions gains an optional chart_version (None
  preserves the previous CARGO_PKG_VERSION behavior).
- operator_release.rs: new binary.
- release.sh: thin wrapper.
- .gitea/workflows/harmony-fleet-operator.yaml: rewritten to fire
  on `harmony-fleet-operator-v*` tags (and workflow_dispatch with a
  manual version input).
Two findings from the k3d smoke-test of the release pipeline:

1. `HelmChart::new(name, version)` is misleading — the second arg sets
   appVersion only, while the chart-level `version` is a separate pub
   field defaulting to "0.1.0". The first run produced
   `harmony-fleet-operator-0.1.0.tgz` instead of
   `harmony-fleet-operator-<tag>.tgz`. Set both fields to the released
   tag so one tag → one image + one chart at one matching version.

2. Add `--no-push` to the release binary so the same code path that
   CI exercises is usable locally for k3d smoke-tests without pushing
   to Harbor. The packaged chart tgz is copied into the caller's CWD
   so it survives the binary's tempdir cleanup, and the binary prints
   both artifact paths at the end.

Verified end-to-end on k3d: helm install brings up CRDs, RBAC, and
the operator Deployment; the operator pod reaches Running 1/1 and
starts retrying NATS connect (expected — no NATS deployed in this
smoke-test).
refactor: chart is now namespace-neutral; add dashboard roadmap
Some checks failed
Run Check Script / check (pull_request) Failing after 59s
cc41f190d2
The k3d smoke-test surfaced that the operator chart baked
`fleet-system` into every namespaced manifest (Deployment,
ServiceAccount, Secret) and into the ClusterRoleBinding subject.
Installing into any other namespace failed with helm
release-namespace mismatch.

Fixed by making the chart genuinely namespace-neutral:

- Removed `namespace` from `ChartOptions` entirely.
- `service_account()` and `operator_deployment(opts)` no longer
  set `metadata.namespace`; helm assigns the release namespace at
  install time, and the direct-apply path injects the namespace
  through `K8sResourceScore::single(.., Some(ns))`.
- `operator_secret(opts)` likewise drops `metadata.namespace`; the
  Secret is applied with an explicit namespace by its caller.
- `cluster_role_binding(subject_namespace)` keeps a namespace
  argument because the CRB subject must point at a concrete
  namespace; the chart path passes the literal helm template
  `{{ .Release.Namespace }}` so helm substitutes the release
  namespace at install time. The direct-apply path passes the
  real namespace string.
- `FleetOperatorScore::new()` defaults its own `namespace` field
  (no longer sourced from `ChartOptions::default()`); the chart
  itself carries no namespace default at all.

Verified on k3d by installing the released chart into a
deliberately non-default namespace (`my-fleet`): all resources
land in `my-fleet`, ClusterRoleBinding subject resolves to
`my-fleet`, operator pod runs.

Also adds `ROADMAP/fleet_platform/dashboard_ingress.md` capturing
the three-step dependency chain (build with web-frontend feature →
implement real FleetService → add Service + Ingress to chart) that
the k3d test surfaced when looking for the dashboard. Unnumbered
file per project convention; numbered ones are versioned
milestones.
johnride added 1 commit 2026-05-26 19:16:19 +00:00
style: cargo fmt the operator-release binary
All checks were successful
Run Check Script / check (pull_request) Successful in 2m23s
87e142c73d
Collapses a chained `current_dir()?.join(..)` per rustfmt's
preferred layout. Caught by ./build/check.sh's fmt step; no
behavior change.
johnride added 1 commit 2026-05-26 19:39:46 +00:00
refactor: use tracing instead of eprintln in operator-release
All checks were successful
Run Check Script / check (pull_request) Successful in 2m26s
b29d466240
eprintln! was the wrong tool for a long-running CLI invoked from
shell scripts and CI. The rest of the codebase (operator,
fleet-e2e harness, etc.) uses tracing::info!, and a release tool
should honor RUST_LOG.

Initializes a stderr tracing subscriber defaulting to info so the
progress lines show up without configuration, while still letting
operators silence (`RUST_LOG=warn`) or expand (`RUST_LOG=debug`)
the output. The final summary uses structured fields (image=,
chart=) so downstream tools can grep for them deterministically.
johnride added 1 commit 2026-05-26 20:21:54 +00:00
refactor: app-scoped release binary harmony-fleet-release
All checks were successful
Run Check Script / check (pull_request) Successful in 2m41s
Release harmony-fleet-operator (image + chart) / release (push) Successful in 4m38s
81bf8a9257
Renames `harmony-fleet-operator-release` to `harmony-fleet-release`
and adds a `--component <operator|agent|nats-callout>` flag. The
binary's surface is now app-scoped (one binary per app, all fleet
components behind a flag) rather than component-scoped (one binary
per component), matching ADR-023's "deploy binary statically lists
its supported components" guidance.

Why: adding the agent and nats-callout release pipelines later
would otherwise mean three near-identical binaries with copy-pasted
docker/helm orchestration. Folding them under one binary keeps the
shared 90% in one place and reduces each new component to:

  - a new `Component` enum variant
  - a `Component::spec` arm naming the Dockerfile + image
  - a `hydrate_chart` arm pointing at the component's `build_chart`

`agent` and `nats-callout` variants exist today but bail with an
actionable error pointing at the roadmap; this keeps `--help`
honest about what's coming without lying about what works.

The per-component `release.sh` wrapper pattern stays: each
component's script (today `fleet/harmony-fleet-operator/release.sh`,
tomorrow agent's and callout's) is a 1-line wrapper that pre-fills
`--component`. This lets a tag like `harmony-fleet-operator-v0.1.0`
route to the right component via the existing CI workflow without
the operator having to remember a flag.

File renamed via `git mv` so blame history is preserved. Verified
on k3d with `--component operator --no-push`: produces the same
image + chart pair as before.
All checks were successful
Run Check Script / check (pull_request) Successful in 2m41s
Release harmony-fleet-operator (image + chart) / release (push) Successful in 4m38s
This pull request has changes conflicting with the target branch.
  • .gitea/workflows/harmony-fleet-operator.yaml
  • examples/fleet_e2e_demo/src/lib.rs
  • fleet/harmony-fleet-deploy/Cargo.toml
  • fleet/harmony-fleet-deploy/src/operator/chart.rs
  • fleet/harmony-fleet-deploy/src/operator/score.rs
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin ci/fleet-operator-release-pipeline:ci/fleet-operator-release-pipeline
git checkout ci/fleet-operator-release-pipeline
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: NationTech/harmony#300
No description provided.