> ## Documentation Index
> Fetch the complete documentation index at: https://buildcharts.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Build stages

> Model build, test, package, and image stages with target definitions.

Use `targets` in `build.yml` to turn repository sources into Docker Buildx Bake targets.

## Required build target

Each `build.yml` must contain exactly one target with `type: build`.

```yaml theme={"theme":{"light":"plastic","dark":"plastic"}}
targets:
  buildcharts.sln:
    type: build
    with:
      contexts:
        base: docker-image://mcr.microsoft.com/dotnet/sdk:10.0
```

The generator validates this rule during `buildcharts generate`.

## Multiple stages per target

Use a sequence when the same source path should run through multiple stages:

```yaml theme={"theme":{"light":"plastic","dark":"plastic"}}
targets:
  src/App/App.csproj:
    - type: build
      with:
        contexts:
          base: docker-image://mcr.microsoft.com/dotnet/sdk:10.0
    - type: test
      with:
        contexts:
          base: docker-image://mcr.microsoft.com/dotnet/sdk:10.0
    - type: docker
      with:
        contexts:
          base: docker-image://mcr.microsoft.com/dotnet/runtime:10.0
        tags: ["docker.io/example/app:local"]
```

Each `type` must match an alias in `charts/buildcharts/Chart.yaml`.

## Share settings across stages

Use `type: [build, test]` when multiple stages share the same `with` configuration:

```yaml theme={"theme":{"light":"plastic","dark":"plastic"}}
targets:
  src/App/App.csproj:
    type: [build, test]
    with:
      contexts:
        base: docker-image://mcr.microsoft.com/dotnet/sdk:10.0
```

The generator expands this shorthand into separate stage definitions.

## Configure stage settings

The generator recognizes these keys under `with`:

| Key          | What it controls                            |
| ------------ | ------------------------------------------- |
| `contexts`   | Docker Bake named contexts                  |
| `tags`       | Image tags for `docker` stages              |
| `dockerfile` | Override the chart Dockerfile path          |
| `allow`      | BuildKit entitlements                       |
| `args`       | Build args passed into the chart Dockerfile |

Example:

```yaml theme={"theme":{"light":"plastic","dark":"plastic"}}
targets:
  src/Library/Library.csproj:
    - type: nuget
      with:
        args:
          SOURCELINK_STRICT: 0

    - type: docker
      with:
        contexts:
          base: docker-image://mcr.microsoft.com/dotnet/runtime:10.0
        dockerfile: ./Dockerfile
        allow: ["network.host"]
        tags: ["docker.io/example/library:local"]
```

## Configure build contexts

Use `with.contexts` to pass Docker Bake named contexts into a target. The common `base` context lets a chart Dockerfile choose its base image without hardcoding it in the chart:

```yaml theme={"theme":{"light":"plastic","dark":"plastic"}}
targets:
  src/App/App.csproj:
    type: docker
    with:
      contexts:
        base: docker-image://mcr.microsoft.com/dotnet/runtime:10.0
```

Use `types.<type>.contexts` when every target of a type should receive the same context:

```yaml theme={"theme":{"light":"plastic","dark":"plastic"}}
types:
  nuget:
    contexts:
      git: .git
```

The context name `build` is reserved. BuildCharts automatically connects non-`build` targets to the generated `build` target as `target:build`.

## Shared variables

Use top-level `variables` for values reused across generated targets, such as image tags or version metadata.

```yaml theme={"theme":{"light":"plastic","dark":"plastic"}}
variables:
  VERSION: "1.0.0-local"
  COMMIT: "local"
```

Reference variables from stage settings with `${VARIABLE}`:

```yaml theme={"theme":{"light":"plastic","dark":"plastic"}}
targets:
  src/App/App.csproj:
    type: docker
    with:
      tags: ["docker.io/example/app:${VERSION}-${COMMIT}"]
```

Map variables through `with.args` when a chart expects a custom build arg name:

```yaml theme={"theme":{"light":"plastic","dark":"plastic"}}
targets:
  src/App/App.csproj:
    type: docker
    with:
      args:
        APP_VERSION: "${VERSION}"
        SOURCE_COMMIT: "${COMMIT}"
```

Variables become Bake variables and are also passed to chart Dockerfiles as build args through the generated `_common` target.

## Use built-in build args

Every generated target also gets a small set of built-in build args.

For example:

```yaml theme={"theme":{"light":"plastic","dark":"plastic"}}
targets:
  src/MyApp/MyApp.csproj:
    type: build
```

The generator injects:

| Variable           | Meaning                                                      |
| ------------------ | ------------------------------------------------------------ |
| `BUILDCHARTS_SRC`  | The target source path, for example `src/MyApp/MyApp.csproj` |
| `BUILDCHARTS_TYPE` | The generated target type, for example `build`               |

## Pass custom build arguments

Use `with.args` for chart-specific Dockerfile `ARG`s. Values can be literals or variable references.

Dockerfile example:

```dockerfile theme={"theme":{"light":"plastic","dark":"plastic"}}
ARG SOURCELINK_STRICT=1
ARG APP_VERSION
```

`build.yml` example:

```yaml theme={"theme":{"light":"plastic","dark":"plastic"}}
variables:
  VERSION: "1.0.0-local"

targets:
  src/Library/Library.csproj:
    - type: nuget
      with:
        args:
          SOURCELINK_STRICT: 0
          APP_VERSION: "${VERSION}"
```

The generator writes these values into the generated Bake target, so the chart Dockerfile receives them as standard build args at execution time.

## Expand stages with a matrix

Use `types.<type>.matrix` when every target of the same type should fan out across a matrix:

```yaml theme={"theme":{"light":"plastic","dark":"plastic"}}
types:
  docker:
    matrix:
      platform: ["linux/amd64", "linux/arm64"]
```

Each matrix axis is expanded into multiple generated Bake variants for that type, and every axis value is exposed to the chart as an uppercase build arg.

For example, this metadata:

```yaml theme={"theme":{"light":"plastic","dark":"plastic"}}
targets:
  src/dotnet-krp/dotnet-krp.csproj:
    - type: publish

types:
  publish:
    matrix:
      runtime: ["win-x64", "win-arm64"]
```

becomes a generated Bake matrix for `publish` where:

* The same source target is reused
* The `runtime` axis expands into one variant per value
* The generated target name includes the matrix value
* The chart receives `RUNTIME` as a build arg

In practice, that one `type: publish` entry turns into two generated publish variants, one for `win-x64` and one for `win-arm64`.

This is conceptually similar to:

* [Azure DevOps strategy matrix](https://learn.microsoft.com/en-us/azure/devops/pipelines/yaml-schema/jobs-job-strategy?view=azure-pipelines)
* [GitHub Actions matrix strategy](https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs)

The difference is that BuildCharts expands the matrix into Docker Buildx Bake targets instead of CI jobs. Matrix values become Bake target variants and build args that chart Dockerfiles can consume.

Read more about [Docker matrix targets](https://docs.docker.com/build/bake/matrices/).

## Read values in a chart Dockerfile

Declare an `ARG` for each built-in arg, shared variable, or `with.args` value the chart needs to consume:

```dockerfile theme={"theme":{"light":"plastic","dark":"plastic"}}
###################################
# Target: sample
###################################
FROM build AS sample

# The target source path, for example `src/MyApp/MyApp.csproj`
ARG BUILDCHARTS_SRC

# The generated target type, for example `build`
ARG BUILDCHARTS_TYPE

# Top-level variables from build.yml
ARG VERSION
ARG COMMIT

# Values mapped through with.args
ARG APP_VERSION
ARG SOURCE_COMMIT

RUN echo "BUILDCHARTS_SRC=$BUILDCHARTS_SRC" && \
    echo "BUILDCHARTS_TYPE=$BUILDCHARTS_TYPE" && \
    echo "VERSION=$VERSION" && \
    echo "COMMIT=$COMMIT" && \
    echo "APP_VERSION=$APP_VERSION" && \
    echo "SOURCE_COMMIT=$SOURCE_COMMIT"
```
