Onboarding flow: repo-created → scaffold PR + factory PR + cluster resources #10
Labels
No labels
ready-for-agent
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
lab/automation#10
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What to build
The repo-creation onboarding flow (repurposing the existing
create-repo-ciflow in the automation repo):laborg (designed so it can be widened to other orgs later without rework).lab:<owner>-<repo>, RFC1123-safe) + destination service account + curated Role on mini (workloads, core resources, networkpolicy, gateway-api routes, cert-manager listener kinds; no RBAC or cluster-scoped kinds);.ci/(kustomization + repo-prefixed tag-build sensor +apps.yamlrepo-declared app config) +k8s/starter, in the shape proven by the authz-bridge ticket, parameterized by owner/repo (sensor filter, labels, prefixed names);lab/dev-apps-source: the per-repo directory with the CI Application (static:.ci/→ mini/ci, SAci-argocd,allowEmpty: false), a per-repo ApplicationSet that generates the app Application from the repo's.ci/apps.yaml(see design notes below), and the AppProject (destinations:ci+<owner>-<repo>) with anappRBACrule for the repo creator.Design notes: app Application via ApplicationSet (repo-declared manifest location)
The app Application is not a static factory object — its source path is declared by the repo itself, so the repo stays the source of truth for its own layout. System-service repos (like authz-bridge, deployed by Flux from
deployments/) have no app Application at all; app-style repos declare their manifest path in the repo.Mechanism: one Argo CD ApplicationSet per repo (Git file generator,
goTemplate: true,goTemplateOptions: ["missingkey=error"]) pointing at the app repo's.ci/apps.yaml. The file is a YAML array; each element generates one Application:Template:
projectpinned statically in the ApplicationSet (never repo-templated — with a templated project field, repos could grant themselves projects with excessive permissions; Argo CD docs require the source of truth to be admin-controlled in that case).destination.name: mini,source.path: '{{.sourcePath}}',destination.namespace: '{{.namespace}}', destination SA from the provisioning convention,allowEmpty: true(a fresh scaffold with an emptyk8s/is a valid state).Placement: ApplicationSet objects live in the
argocdnamespace (the controller enforces generated-app namespace = appset namespace) — the existingprojects/→argocdFlux Kustomization from #9 covers this; the factory PR adds them alongside the AppProject.Naming constraint: a file-content key literally named
pathoverwrites the generator's ownpathparams (verified inapplicationset/generators/repo_path_utils.go) — usesourcePath.Failure semantics (verified in argo-cd v3 source,
applicationset/controllers/applicationset_controller.go): a broken config file (bad YAML / missing key undermissingkey=error) fails generation and the reconcile aborts before the create/prune phase — last-good Applications keep running, the ApplicationSet gets anErrorOccurredstatus condition, and it requeues on the next poll. A typo in the repo cannot delete a live app; apps are pruned only when their file entry is deliberately removed.Latency: the Git generator polls every 3 min by default (
requeueAfterSecondstunable per ApplicationSet). Forgejo is not in the tested ApplicationSet webhook list (GitHub/GitLab only), so config changes propagate on the poll interval; theargocd.argoproj.io/application-set-refreshannotation forces an immediate refresh.CI Application stays static in the factory entry (100% conventional:
.ci/→cins, SAci-argocd) — the CI chain is decoupled from ApplicationSet generation, and the repo-declared file only covers the variable (app) half.Acceptance criteria
laborg triggers the onboarding workflow.ci/apps.yamlpresent)lab/dev-apps-sourcewith the CI Application, the per-repo ApplicationSet, and the AppProject carrying the creator's appRBAC rule.ci/apps.yaml(picked up by Argo CD, empty starter tolerated viaallowEmpty).ci/apps.yaml(e.g.sourcePath) updates the generated Application within the poll interval; a broken file leaves the last-good Application running with anErrorOccurredcondition on the ApplicationSetBlocked by