# Discovery conventions Where the pipeline looks for work, and how names are derived. These conventions come from the **development-monorepo-pnpm** skill (`references/containers-and-helm.md`) — this file restates only what the pipeline depends on. If the monorepo skill and this file ever disagree, the monorepo skill wins; update this one. --- ## Repository shape the pipeline assumes ```text / ├── applications-backend//Dockerfile # deployable services (NestJS by default) ├── applications-frontend//Dockerfile # deployable browser apps (React + Carbon) ├── helm-charts//Chart.yaml # ALL charts — centralized, not per-app ├── pnpm-workspace.yaml ├── turbo.json └── pnpm-lock.yaml ``` Two independent discovery sets: | Artifact | Glob | Produced by | |---|---|---| | Image | `applications-backend/*/Dockerfile`, `applications-frontend/*/Dockerfile` | `docker build` from repo root | | Chart | `helm-charts/*/Chart.yaml` | `helm package` | ### Charts are centralized — do not look under the app directory A frequent wrong assumption is that a chart lives at `applications-frontend//helm/` or `.../chart/`. It does **not** in this monorepo family. Charts are collected under `helm-charts//` at the repo root. Practical consequences: - Discover images and charts **separately**; there is **no enforced 1:1** mapping. - An app may have a `Dockerfile` and **no** chart (deployed by a shared/umbrella chart, or not yet deployable). - A chart may exist with **no** same-named app (an umbrella chart, or a chart that deploys a third-party image). - Do not infer a chart's existence from an app's, or vice versa. Loop each glob on its own. --- ## Naming ### Image repository = application directory name ``` ${HARBOR_ADDRESS}/${HARBOR_PROJECT}/: # e.g. harbor-v1.apps.lego-cloud.eu/gondor-v1/user-service:9f3a1c2 ``` - The **directory name** under `applications-backend/` or `applications-frontend/` is the image repository name. It is not derived from the package.json `name` / scope — using the directory name keeps the image path stable and needs no Node in the job. - Backend and frontend images share the flat `/` namespace. If two apps across the two roots ever share a directory name they would collide — keep directory names unique across both roots (they already must be, since pnpm workspace names must be unique). ### Chart repository = chart name, under a `charts` subpath ``` oci://${HARBOR_ADDRESS}/${HARBOR_PROJECT}/charts # push target (base) # a chart named "user-service" becomes: # ${HARBOR_ADDRESS}/${HARBOR_PROJECT}/charts/user-service: ``` Charts are pushed under a `charts` subpath so OCI chart artifacts and image artifacts do not share the project's top-level namespace. The chart name is the `name:` field in `Chart.yaml` (which should match its directory name). ### Harbor project `HARBOR_PROJECT` (default `gondor-v1`) is the Harbor project everything is pushed into. It must be a project the robot has **push** on. One project per monorepo is a clean default; if you host several monorepos, either give each its own project (and a per-project push robot) or accept a shared project with distinct `` names. --- ## Tag → deploy handoff The pipeline publishes `:` (immutable) and, on the default branch, `:latest` (moving). The **immutable** `:` is what a GitOps deployment should pin. This skill does not edit deployment values — it hands the image reference and tag to **development-gitops-argo-cd**, where the tag flows through Copier variables into the Helm values Argo CD syncs. --- ## Quick audit of a repo before generating a pipeline ```bash echo "images:"; ls -d applications-backend/*/ applications-frontend/*/ 2>/dev/null \ | while read d; do [ -f "$d/Dockerfile" ] && echo " $d"; done echo "charts:"; ls -d helm-charts/*/ 2>/dev/null \ | while read d; do [ -f "$d/Chart.yaml" ] && echo " $d"; done ``` If either list is empty, confirm you are at the repo root and that the monorepo actually follows this layout before wiring the pipeline — an empty discovery set means the workflow will run green while building nothing.