docs(ci): sharpen CI/CD spec to shared-engine/separate-projects principle
Operator's principle: fxhnt and bizworx are different projects — use the shared bizworx platform infra (Gitea, Argo engine, registry, node-pools) but keep fxhnt-owned objects (WorkflowTemplate, build/deploy pods, secrets, RBAC) in the foxhunt ns. Only the Sensor lives in argo-events (unavoidable, kept minimal). No cross-ns RBAC, no fxhnt secrets in platform ns. Adds a deployed-sha annotation for git-sync reproducibility. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -13,9 +13,28 @@ fast rollout (git-sync re-pulls src); only dependency/Dockerfile changes trigger
|
||||
|
||||
The operator's insight: **code changes often, the image changes rarely.** git-sync already pulls fresh `src/`
|
||||
on every (re)start, so a code-only push needs only a rollout — not a 5-minute Kaniko build. A rebuild is needed
|
||||
only when `pyproject.toml` / `fxhnt.Dockerfile` / lock change. This is exactly the `mode=build` vs `mode=deploy`
|
||||
split the retired `infra/argo/cockpit-build-deploy.yaml` already encoded — we reanimate and fix it, rather than
|
||||
adopt the generic `build-image` template (which lacks the split and fxhnt's deploy specifics).
|
||||
only when `pyproject.toml` / `fxhnt.Dockerfile` change. This is exactly the `mode=build` vs `mode=deploy` split
|
||||
the retired `infra/argo/cockpit-build-deploy.yaml` already encoded — we reanimate and fix it, rather than adopt
|
||||
the generic `build-image` template (which lacks the split and fxhnt's deploy specifics).
|
||||
|
||||
## Governing principle: shared engine, separate projects
|
||||
|
||||
fxhnt and bizworx are **different projects**. fxhnt should *use* bizworx's heavy shared platform infra but not
|
||||
*pollute* the platform namespaces with fxhnt-specific objects or secrets:
|
||||
|
||||
- **SHARE (bizworx platform, use as-is):** the one Gitea (webhook source), the Argo Events eventbus +
|
||||
`gitea-webhook` eventsource, the Argo Workflows controller (the build *engine*), external-secrets/openbao,
|
||||
the `large` node-pool, the Scaleway registry.
|
||||
- **SEPARATE (fxhnt-owned, live in `foxhunt`):** the `WorkflowTemplate`, all build+deploy pods, fxhnt's
|
||||
secrets (`argo-git-ssh-key`, `scw-registry` — already in `foxhunt`), and fxhnt's RBAC.
|
||||
- **The ONE unavoidable object in a platform ns:** the Sensor. A Sensor must live in `argo-events` to hear the
|
||||
shared eventbus. Keep its footprint minimal — it only matches fxhnt pushes and *submits* a Workflow that runs
|
||||
in `foxhunt`. No fxhnt secrets, no fxhnt logic beyond the trigger, live in `argo-events`.
|
||||
|
||||
This is NOT the old "everything in foxhunt because the secrets were there" (path of least resistance) — it's the
|
||||
same placement for the *right* reason: respecting the project boundary. It also means **no cross-namespace RBAC**
|
||||
(the deploy runs in `foxhunt`, where the app + its permissions already are) and **no fxhnt secrets replicated
|
||||
into `argo`**.
|
||||
|
||||
## Verified current state (all components already exist on bizworx)
|
||||
|
||||
@@ -36,31 +55,36 @@ adopt the generic `build-image` template (which lacks the split and fxhnt's depl
|
||||
## Architecture
|
||||
|
||||
```
|
||||
git push → gitadmin/fxhnt (master)
|
||||
│ Gitea webhook ──────────────► argo-events `gitea-webhook` eventsource (/push)
|
||||
git push → gitadmin/fxhnt (master) [SHARED: Gitea]
|
||||
│ Gitea webhook ──────────────► argo-events `gitea-webhook` eventsource [SHARED: platform eventbus]
|
||||
▼
|
||||
Sensor `build-fxhnt` — filters: ref==refs/heads/master, pusher != argocd-image-updater
|
||||
Sensor `build-fxhnt` (ns argo-events — the ONE fxhnt object in a platform ns, kept minimal)
|
||||
│ filters: ref==refs/heads/master, pusher != argocd-image-updater
|
||||
│ path-filter on the pushed commits' modified files decides the mode:
|
||||
│ • touched pyproject.toml OR infra/docker/fxhnt.Dockerfile → param mode=build
|
||||
│ • otherwise (src/, infra/k8s/, config) → param mode=deploy
|
||||
│ (NB: the repo has NO lock file — the Dockerfile `pip install`s straight from pyproject.toml,
|
||||
│ so pyproject.toml + the Dockerfile are the ONLY dependency sources that require a rebuild.)
|
||||
▼
|
||||
Argo Workflow (WorkflowTemplate `fxhnt-cockpit`, reanimated) — DAG:
|
||||
├─ mode=build: git-clone(sha) → Kaniko build → rg.fr-par.scw.cloud/bizworx/fxhnt-cockpit:<sha7>+:latest
|
||||
▼ submits a Workflow into ns `foxhunt` ─────────────────────────────── [FXHNT-OWNED from here down]
|
||||
Argo Workflow (WorkflowTemplate `fxhnt-cockpit`, ns foxhunt, SA argo-workflow, node-pool `large`) — DAG:
|
||||
├─ mode=build: git-clone(sha) → Kaniko → rg.fr-par.scw.cloud/bizworx/fxhnt-cockpit:<sha7>+:latest
|
||||
└─ (build skipped when mode=deploy)
|
||||
→ deploy step: kubectl apply manifests + refresh the daemons (git-sync re-pulls src)
|
||||
→ deploy step (in foxhunt, no cross-ns RBAC): kubectl apply manifests + refresh daemons (git-sync re-pulls src)
|
||||
```
|
||||
|
||||
## Components to build/fix
|
||||
|
||||
### 1. WorkflowTemplate `fxhnt-cockpit` (reanimate `infra/argo/cockpit-build-deploy.yaml`)
|
||||
- Fix `nodeSelector` `ci-compile-cpu` → `large` (both build + deploy templates).
|
||||
### 1. WorkflowTemplate `fxhnt-cockpit` (reanimate `infra/argo/cockpit-build-deploy.yaml`, ns `foxhunt`)
|
||||
- Fix `nodeSelector` `ci-compile-cpu` → `large` (both build + deploy templates — `ci-compile-cpu` pool is gone;
|
||||
only `large`/`sfs` exist).
|
||||
- Keep the `mode` DAG: `build` (Kaniko rebuild + deploy) vs `deploy` (skip build, deploy only).
|
||||
- Keep the Kaniko dest `rg.fr-par.scw.cloud/bizworx/fxhnt-cockpit` but ADD an immutable `:<sha7>` tag next to
|
||||
`:latest` (reproducibility — image == commit; matches the msp pattern). Cache stays on.
|
||||
- Clone via the in-cluster Gitea (`ssh://…gitea…/gitadmin/fxhnt.git`) using `argo-git-ssh-key`; push via
|
||||
`scw-registry`. Verify both secrets resolve from the namespace the workflow runs in.
|
||||
`:latest` (matches the msp pattern). Cache stays on.
|
||||
- Clone via the in-cluster Gitea using `argo-git-ssh-key`; push via `scw-registry`. Both already exist in
|
||||
`foxhunt` — the workflow runs there, so they resolve locally (no replication into a platform ns).
|
||||
- **Reproducibility despite git-sync:** the deploy step stamps the deployed commit sha onto the daemon
|
||||
Deployments as an annotation (`fxhnt.io/deployed-sha=<sha7>`), so "which commit is this pod running" is always
|
||||
answerable — closing the one real gap of git-sync-first without adopting full image-based deploys.
|
||||
|
||||
### 2. Sensor `build-fxhnt` (new, model on `build-msp-portal`)
|
||||
- Dependency: `gitea-webhook` push, filter `body.ref == refs/heads/master` AND
|
||||
@@ -87,11 +111,16 @@ succeeded cleanly. **The plan must verify which external route is live** before
|
||||
simpler and correct; drop the scale-dance.
|
||||
Dagster has no external-proxy race → `rollout restart deploy/dagster` either way.
|
||||
|
||||
## Non-goals (YAGNI)
|
||||
## Non-goals (YAGNI) — deliberately NOT doing, with the reason
|
||||
|
||||
- **No ArgoCD GitOps app for fxhnt.** That would force fxhnt's manifests into the bizworx monorepo. git-sync +
|
||||
the mode-split deliver auto-deploy while keeping manifests in the fxhnt repo. A declarative ArgoCD migration
|
||||
is a separate, later decision.
|
||||
- **No ArgoCD GitOps app for fxhnt.** Chosen over declarative GitOps: it would add a second source of truth for
|
||||
the pod's src (ArgoCD-synced manifests vs git-sync'd code) and needs a git.fxhnt.ai repo registration. The
|
||||
imperative `kubectl apply` from the foxhunt workflow fits git-sync-first and keeps manifests in the fxhnt repo.
|
||||
- **No registry unification.** fxhnt stays on Scaleway `rg.fr-par.scw.cloud/bizworx` (not the shared
|
||||
`registry.bizworx.nl/bizworx-ops`). Migrating would mean re-pointing the dashboard + reconciling old images
|
||||
for zero pipeline benefit — a separate, riskier task.
|
||||
- **No CI workloads in a platform namespace.** Only the Sensor lives in `argo-events` (unavoidable). The
|
||||
WorkflowTemplate + all build/deploy pods run in `foxhunt` — no fxhnt secrets in `argo`, no cross-ns RBAC.
|
||||
- **No image-updater for fxhnt.** The sensor writes the `:sha7`+`:latest` tags; the deploy step points the
|
||||
daemons at the fresh image. No git-write-back loop needed.
|
||||
- **No change to the execution CronJobs** (ucits/bybit/ibkr rebalancers) — they git-sync per run already.
|
||||
|
||||
Reference in New Issue
Block a user