Skip to content
RunDeploy

GitOps repository

One Git repository declares what every environment runs, and every deploy-side command (release, deploy, manifests create) operates through it. This page covers setting it up: the deploy.yaml contract, the directory layout, and onboarding a System’s manifests for the first time.

The repository address is a per-user setting, read from ~/.config/intropy/config.yaml (or $XDG_CONFIG_HOME/intropy/config.yaml):

gitopsRepo: git@gitlab.com:integrio/intropy/customers/acme/gitops.git

The --gitops-repo flag overrides INTROPY_GITOPS_REPO, which overrides the file: flags win over the environment, which wins over configuration. git and kustomize must be on PATH.

The CLI keeps a cached local checkout of the repository and refreshes it under an exclusive lock before reading or writing, so two local deploys cannot edit the same checkout concurrently.

A deploy.yaml at the repository root marks it as deployable. schemaVersion: 1 is required; a repository without a valid deploy.yaml is refused. The verified shape:

schemaVersion: 1
registry: harbor.intropy.io
argocd:
server: argocd.intropy.io
appNamespace: customer-fluxia
environments:
dev: { sync: auto }
staging: { sync: auto, promotesFrom: [dev] }
prod: { sync: manual, promotesFrom: [staging], requireSourceHealthy: true }
Field Meaning
schemaVersion Must be 1.
registry The OCI registry that holds component images and release manifests.
argocd.server The ArgoCD API endpoint. This beats the per-user argocdServer configuration on purpose: it travels with the repository the overlays live in. --argocd-server and ARGOCD_SERVER beat it in turn.
argocd.appNamespace The namespace ArgoCD Application resources live in. Applications are deployed per customer rather than into argocd, so a 404 from ArgoCD is most often a wrong value here; the error says which namespace was tried.
environments.<env>.sync auto: ArgoCD reconciles as soon as a commit lands. manual: a deploy or promotion records intent and stops; a person applies it with deploy sync.
environments.<env>.promotesFrom The legal promotion edges into this environment. deploy promote refuses an undeclared edge; deploy pin only reports against it.
environments.<env>.requireSourceHealthy Promotion into this environment requires the source’s ArgoCD application to be Synced and Healthy at the revision its digests were pinned by.

The environments block is the promotion graph the whole Promote and sync page is about; deploy status also orders its output by it.

Components live at domains/<domain>/<system>/<component>/, each with a component.yaml beside a kustomize base/ and one overlay per environment:

deploy.yaml
domains/
└── orders/
└── order-flow/
├── order-extractor/
│ ├── component.yaml
│ ├── base/
│ └── overlays/
│ ├── dev/
│ ├── staging/
│ └── prod/
└── order-loader/
└── …
component.yaml
schemaVersion: 1
name: order-extractor
sourcePaths: [integrations/domains/orders/order-flow/order-extractor/]
images:
- name: harbor.intropy.io/integrations/order-extractor
environments: [dev, staging, prod]

sourcePaths is what release create and deploy pin check for cleanliness in the source repository; images names what gets pinned; environments limits where. Commands locate a component by searching domains/*/*/<component>, so you only ever pass the name. If it occurs under more than one domain or system, the error lists the candidates and --domain/--system disambiguate.

intropy manifests create renders one environment from the System’s topology and creates whatever files are missing — on a review branch, never on the default branch:

Terminal window
intropy manifests create --env dev --dry-run # report the file plan, touch nothing
intropy manifests create --env dev --diff # print generated file differences, touch nothing
intropy manifests create --env dev # create, commit, push the review branch

Run it from the workspace that holds the System host. The System name comes from the topology; --system selects a host in a multi-system workspace. The domain is inferred from where the System already sits in the GitOps tree, or from the workspace layout; pass --domain on the first run when neither is conclusive. The latest template release is used unless --template-version pins one.

The command is additive by design:

  • The branch is manifests-create/<domain>-<system>-<env>, pushed for review. The default branch is never updated directly.
  • A missing file is created. A byte-identical existing file is accepted, so an interrupted or repeated run is harmless. A differing existing file is a conflict that stops the whole operation: manifest creation never replaces or deletes GitOps source.
  • Once merged, the files are ordinary, editable repository files owned by the GitOps maintainers. Onboarding another environment later is another explicit run (or a plain GitOps edit), not regeneration.

A topology port names an external edge but never decides its deployed adapter, so the binding type, address, and credentials land as explicit REPLACE-ME configuration for maintainers to fill in per environment after the branch is created. This is the connect step as a reviewed configuration act, never a code change. The command says so as it works:

note: port order-extractor-source has no binding for dev; its manifests keep the REPLACE-ME scaffold
note: port order-loader-destination has no binding for dev; its manifests keep the REPLACE-ME scaffold

There is no persisted binding state anywhere else: the filled-in GitOps files are the single source of truth for what a port resolves to in each environment.

Image digests are out of scope here: pinning them is deploy pin’s job. Creation is one-time onboarding for the selected environment.

Full flag detail: intropy manifests create.