|
| 1 | +# AGENTS.md |
| 2 | + |
| 3 | +This file provides guidance to coding agents when working with code in this repository. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +This repository contains tooling for building and publishing Docker images in various .NET repos. |
| 8 | +The primary tool is **ImageBuilder**, a .NET CLI application that orchestrates Docker image builds based on manifest metadata files. |
| 9 | + |
| 10 | +## Project Structure |
| 11 | + |
| 12 | +This repo contains several projects: |
| 13 | + |
| 14 | +- **`src/ImageBuilder/`** - The main ImageBuilder CLI tool (executable) |
| 15 | +- **`src/ImageBuilder.Models/`** - Shared model definitions for manifest files and image metadata |
| 16 | +- **`src/ImageBuilder.Tests/`** - Unit tests using xUnit, Moq, and Shouldly |
| 17 | +- **`eng/src/file-pusher/`** - Utility for pushing files to storage |
| 18 | +- **`eng/src/yaml-updater/`** - Utility for updating YAML files |
| 19 | + |
| 20 | +## Building and Testing |
| 21 | + |
| 22 | +- To build all projects, run `dotnet build`. |
| 23 | +- To run tests, run `dotnet test`. |
| 24 | +- If you run into permission issues during builds relating to copying `.dll` files, run `dotnet clean` and/or `build.sh -clean` and then build again. |
| 25 | + |
| 26 | +### Build ImageBuilder Container Image |
| 27 | + |
| 28 | +See [src/README.md](src/README.md) for instructions on building single-platform and multi-arch ImageBuilder container images locally. |
| 29 | + |
| 30 | +## ImageBuilder Architecture |
| 31 | + |
| 32 | +ImageBuilder is a command-based CLI tool that operates on manifest files. |
| 33 | +The manifest file (`manifest.json`) is the primary metadata source that defines which Docker images to build, their tags, platforms, and dependencies. |
| 34 | + |
| 35 | +### Key Components |
| 36 | + |
| 37 | +- **Commands** (`src/ImageBuilder/Commands/`) - Each command implements a specific operation (build, publish, generateBuildMatrix, etc.). Commands inherit from `Command<TOptions>` and use System.CommandLine for argument parsing. |
| 38 | +- **Models** (`src/ImageBuilder.Models/Manifest/`) - Defines the manifest schema and image metadata structures |
| 39 | +- **Services** - Abstracted services for Docker operations, Azure Container Registry interactions, Git operations, etc. |
| 40 | + |
| 41 | +### Running ImageBuilder Locally |
| 42 | + |
| 43 | +For quick validation during local development, use `dotnet run`: |
| 44 | + |
| 45 | +```bash |
| 46 | +dotnet run --project src/ImageBuilder -- --help |
| 47 | +``` |
| 48 | + |
| 49 | +## `eng/docker-tools` Infrastructure |
| 50 | + |
| 51 | +The `eng/docker-tools/` directory contains shared PowerShell scripts and Azure Pipelines templates used across all .NET Docker repositories. |
| 52 | +This repository is the source of truth for these files - changes made here are automatically synchronized to consuming repositories. |
| 53 | + |
| 54 | +For comprehensive documentation on the docker-tools infrastructure, pipeline architecture, image building workflows, and troubleshooting, see [eng/docker-tools/DEV-GUIDE.md](eng/docker-tools/DEV-GUIDE.md). |
| 55 | + |
| 56 | +## ImageBuilder Build and Deployment Workflow |
| 57 | + |
| 58 | +ImageBuilder is published as a container image to the Microsoft Artifact Registry (MAR) at `mcr.microsoft.com/dotnet-buildtools/image-builder`. |
| 59 | +The ImageBuilder container image is defined in `src/manifest.json`. |
| 60 | +It is built from Dockerfiles `src/Dockerfile.linux` and `src/Dockerfile.windows`. |
| 61 | + |
| 62 | +ImageBuilder uses itself to build its own container image. |
| 63 | +This means changes to ImageBuilder code and pipeline templates must be coordinated carefully in a two-step process. |
| 64 | +The version of ImageBuilder used by pipelines is specified in `eng/docker-tools/templates/variables/docker-images.yml` (`imageNames.imageBuilder` variable). |
| 65 | + |
| 66 | +### Two-Step Change Process |
| 67 | + |
| 68 | +When making changes that affect both ImageBuilder code and pipeline behavior: |
| 69 | + |
| 70 | +1. **Step 1: Update ImageBuilder code** |
| 71 | + - Make code changes to ImageBuilder source |
| 72 | + - Test locally using `dotnet run --project src/ImageBuilder` |
| 73 | + - Propose changes in a pull request and wait for it to be merged and for CI to run. |
| 74 | + - A pull request will automatically be created that updates `docker-images.yml` with the new ImageBuilder tag. |
| 75 | +2. **Step 2: Update pipeline/manifest to use new ImageBuilder** |
| 76 | + - Once the new ImageBuilder image is published, pipeline templates in `eng/docker-tools/` can reference new features/commands |
| 77 | + - Consuming repositories will get the updated pipeline templates AND the new ImageBuilder image |
| 78 | + |
| 79 | +### Why This Matters |
| 80 | + |
| 81 | +- **Pipeline templates** in `eng/docker-tools/templates/` invoke ImageBuilder commands |
| 82 | +- These templates run using a specific version/tag of the ImageBuilder container image |
| 83 | +- If you add a new ImageBuilder command or change command behavior, pipelines can't use it until a new ImageBuilder image is published |
| 84 | +- This means code changes and pipeline template changes that depend on them must be done in separate steps |
| 85 | + |
| 86 | +### Bootstrap Option for Development |
| 87 | + |
| 88 | +To test ImageBuilder code changes and pipeline template changes together without waiting for the two-step process, use the `bootstrapImageBuilder` parameter in the unofficial pipeline (`eng/pipelines/dotnet-buildtools-image-builder-unofficial.yml`). |
| 89 | + |
| 90 | +When `bootstrapImageBuilder: true`: |
| 91 | + |
| 92 | +- ImageBuilder is built from source at the start of every pipeline job |
| 93 | +- The pipeline uses the freshly-built ImageBuilder instead of pulling from MCR |
| 94 | +- This allows validating ImageBuilder changes and pipeline template changes in a single pipeline run |
| 95 | + |
| 96 | +Once changes are validated together via the bootstrap process, then changes can be proposed via the normal two-step change process described above. |
| 97 | + |
| 98 | +## Key File Formats |
| 99 | + |
| 100 | +### manifest.json (Input) |
| 101 | + |
| 102 | +Manifest files define metadata about which Docker images ImageBuilder will build. The schema is defined by the `Manifest` model in `src/ImageBuilder.Models/Manifest/Manifest.cs`. For detailed documentation, see [documentation/manifest-file.md](documentation/manifest-file.md). |
| 103 | + |
| 104 | +### image-info.json (Output) |
| 105 | + |
| 106 | +Image info files are ImageBuilder's output that describe which images were built. |
| 107 | +The schema is defined by the `ImageArtifactDetails` model in `src/ImageBuilder.Models/Image/ImageArtifactDetails.cs`. |
| 108 | +These files contain: |
| 109 | + |
| 110 | +- Image digests for each built platform |
| 111 | +- Tags applied to each image |
| 112 | +- Dockerfile paths and commit information |
| 113 | +- Build timestamps |
| 114 | + |
| 115 | +Image info files are used by subsequent pipeline stages and are published to the versions repository to track what was built. |
| 116 | +See [eng/docker-tools/DEV-GUIDE.md](eng/docker-tools/DEV-GUIDE.md) for more details on how image info flows through pipelines. |
| 117 | + |
| 118 | +## Documentation Maintenance |
| 119 | + |
| 120 | +When making changes to ImageBuilder, pipeline templates, or infrastructure: |
| 121 | + |
| 122 | +- Update [eng/docker-tools/DEV-GUIDE.md](eng/docker-tools/DEV-GUIDE.md) if you change pipeline architecture, workflows, or add new capabilities |
| 123 | +- Update [src/README.md](src/README.md) if you change how ImageBuilder container images are built |
| 124 | +- Update [documentation/manifest-file.md](documentation/manifest-file.md) if you modify the manifest schema |
| 125 | +- Update this file (AGENTS.md) if you add projects, change fundamental workflows, or modify architecture that affects how developers work with the codebase |
| 126 | + |
| 127 | +Keep documentation synchronized with code changes so future developers have accurate guidance. |
0 commit comments