Skip to main content
.ankra/ankra.yaml is an application’s descriptor. Ankra writes it into the setup pull request beside .ankra/manifests/ and .ankra/pipeline.yaml, and reads it back from the tracked branch on every analysis run, so what the file says in Git is what the application is:
  • metadata describes the application, in the shape of a Helm Chart.yaml.
  • options is the application’s deploy-time contract: the inputs the deploy form asks for and the deploy endpoint validates.
  • components (optional) declares the application’s deployable components, for a repository whose layout Ankra cannot infer correctly on its own.

Full example

The descriptor of a repository with a Go API at the root, built from deploy/docker/Dockerfile, and a web app in web/:
A generated descriptor lists all thirteen default options (below); the example shows two to stay short.

Top-level keys

Any other top-level key is ignored. A descriptor with the wrong apiVersion or kind, an options value that is not a list, or an option without a name does not parse. Ankra reports the parse failure on the run and reads nothing from the file: the deploy options stay as they were, and so do the recorded components. Keep the file at .ankra/ankra.yaml, outside .ankra/manifests/: the files in that directory are the manifests a deploy applies to the cluster.

Metadata

Every field except name is optional. Ankra fills them from the repository’s GitHub metadata when it generates the file and leaves out the ones it could not read. When you publish the application as an add-on, the descriptor travels with the manifests into the add-on version.

Options

options is the application’s deploy contract. The deploy form renders one input per option, the deploy endpoint validates the values against it, and a manifest under .ankra/manifests/ reads a value as ${{ ankra.<name> }}. A non-empty options list replaces the application’s stored contract on the next analysis run, so editing the list in Git and running setup again changes the deploy form. An empty or absent list keeps the contract Ankra generated: there is no way to declare a deliberately empty contract.

Default options

A generated descriptor declares these thirteen options. target_port defaults to the port the analysis detected. An application with a detected database carries that database’s sizing options as well.

Components

components declares the application’s deployable components. Without it, Ankra infers them from the repository (see Monorepos). Inference cannot see every layout: a repository whose API builds from deploy/docker/Dockerfile at the root and whose web app sits in web/ reads as one app, because detection needs two subdirectory Dockerfiles and ignores deploy/. The declaration is how such a repository states its components. subdir and dockerfile are both paths from the repository root, like context and dockerfile in a pipeline build stage. Neither may be absolute or contain ...

The declaration outranks inference

Ankra decides an application’s components in this order, and the first signal that holds wins:
  1. The components block of .ankra/ankra.yaml.
  2. The per-component build workflows the repository already carries.
  3. The apps the analysis proposed on this run.
  4. The repository’s structure.
So a declaration outranks the existing workflows, the AI proposal and structural detection. It is also the only signal that can remove a component: when inference finds fewer components than a monorepo already records, Ankra keeps the recorded ones, because finding less is not evidence that a component is gone. To drop a component, declare the ones you keep. A declaration of one component at the repository root is a single-app application, and the component takes the repository’s name.

A declaration Ankra cannot honour

The block is validated on its own and is refused as a whole, never partly applied. Ankra refuses it when:
  • components is not a list, or is an empty list (remove the key instead to let Ankra infer)
  • an entry is not a mapping, has no name, or has a key other than name, subdir, app_subdir, dockerfile, container_port and port
  • a name is not lower-case letters and digits joined by hyphens or periods
  • two entries share a name, or build from the same subdir
  • an entry sets both subdir and app_subdir, or both container_port and port, to different values
  • a path is absolute or leaves the repository with ..
  • a port is not a number from 1 to 65535
A refused declaration is reported as the failed setup task read_declared_components, with the reason, in the application’s jobs. The run keeps the components the application already records rather than inferring new ones over a declaration it could not read, and the deploy options are still read from the same file. Fix the block and reconcile the application. A successful read reports the same task as Using the 2 component(s) declared in .ankra/ankra.yaml: api, web. A declared dockerfile that the repository does not contain is reported rather than built, and Ankra does not generate a Dockerfile over it. When Ankra rewrites the descriptor, for example to change the generated options, it copies your components block back exactly as you wrote it, refused or not.

Declared components and the pipeline

Each declared component gets its own build in .ankra/pipeline.yaml, attributed by its build-<component> stage name or by build.component. ankra pipeline validate reports two kind: build stages that publish to the same repository as a fatal pipeline_build_component: finding when both always run, because each run’s commit tag would be overwritten by whichever stage publishes last. When at least one of them runs only under a condition (if, when or matrix, or an on_failure or finally stage), the finding is a warning. See Validation.

Applications

How Ankra analyses a repository, generates its packaging and deploys it.

pipeline.yaml reference

Every key of the pipeline definition that sits beside the descriptor.