Skip to content
Draft
63 changes: 63 additions & 0 deletions eng/docker-tools/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,69 @@ All breaking changes and new features in `eng/docker-tools` will be documented i

---

## 2026-05-22: Mirror registry config refactor

### PublishConfiguration: `InternalMirrorRegistry` and `PublicMirrorRegistry` replaced with `MirrorRegistry`

`PublishConfiguration` no longer exposes separate `InternalMirrorRegistry` and
`PublicMirrorRegistry` properties. Instead, there is a single `MirrorRegistry`
property.

The `--source-repo-prefix` CLI option has also been removed in favor of `PublishConfiguration.MirrorRegistry.RepoPrefix`.

#### How to migrate:

Replace `InternalMirrorRegistry` and `PublicMirrorRegistry` with a pipeline
template conditional:

Before:

```yaml
publishConfig:
...
InternalMirrorRegistry:
server: $(acr-staging.server)
repoPrefix: $(internalMirrorRepoPrefix)
PublicMirrorRegistry:
server: $(public-mirror.server)
repoPrefix: $(publicMirrorRepoPrefix)
...
```

After:

```yaml
publishConfig:
...
${{ if eq(variables['System.TeamProject'], 'internal') }}:
MirrorRegistry:
server: $(acr-staging.server)
repoPrefix: $(internalMirrorRepoPrefix)
${{ else }}:
MirrorRegistry:
server: $(public-mirror.server)
repoPrefix: $(publicMirrorRepoPrefix)
...
```

### Base image override options removed from CLI

The `--base-override-regex` and `--base-override-sub` options have also been
removed from the `build`, `buildMatrix`, `copyBaseImages`, and `getStaleImages`
commands. They are superseded by the properties set in the
`PublishConfiguration`.

#### How to migrate:

Use `PublishConfiguration.MirrorRegistry` instead.

An evaluation of downstream usage of these parameters found only one usage, in
[dotnet-buildtools-prereqs-docker](https://github.com/dotnet/dotnet-buildtools-prereqs-docker/blob/f2842d71c33c10fc5a736988e66911c13d59fb32/eng/pipelines/steps/set-base-image-override-options.yml),
and the usage does not match any current Dockerfiles in that repo, so its
removal will not cause any changes in behavior.

---

## 2026-04-02: Extra Docker build options can be passed through ImageBuilder

- Pull request: [#2063](https://github.com/dotnet/docker-tools/pull/2063)
Expand Down
2 changes: 1 addition & 1 deletion eng/docker-tools/templates/jobs/build-images.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ jobs:
- powershell: |
$images = "$(BuildImages.builtImages)"
if (-not $images) { return 0 }
$syftImageName = "${{ parameters.publishConfig.PublicMirrorRegistry.server }}/$(imageNames.syft)"
$syftImageName = "$(public-mirror.server)/$(imageNames.syft)"
& $(engDockerToolsPath)/Pull-Image.ps1 $syftImageName
$images -Split ',' | ForEach-Object {
echo "Generating SBOM for $_";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,5 @@ jobs:
customInitSteps: ${{ parameters.customInitSteps }}
customCopyBaseImagesInitSteps: ${{ parameters.customCopyBaseImagesInitSteps }}
additionalOptions: ${{ parameters.additionalOptions }}
acr: ${{ parameters.publishConfig.InternalMirrorRegistry }}
acr: ${{ parameters.publishConfig.MirrorRegistry }}
versionsRepoRef: ${{ parameters.versionsRepoRef }}
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,14 @@ stages:
# publishConfig schema is defined in src/ImageBuilder/Configuration/PublishConfiguration.cs.
# This will get converted to JSON and placed in appsettings.json to be loaded by ImageBuilder at runtime.
publishConfig:
InternalMirrorRegistry:
server: $(acr-staging-test.server)
repoPrefix: $(internalMirrorRepoPrefix)

PublicMirrorRegistry:
server: $(public-mirror.server)
repoPrefix: $(publicMirrorRepoPrefix)
${{ if eq(variables['System.TeamProject'], 'internal') }}:
MirrorRegistry:
server: $(acr-staging-test.server)
repoPrefix: $(internalMirrorRepoPrefix)
${{ else }}:
MirrorRegistry:
server: $(public-mirror.server)
repoPrefix: $(publicMirrorRepoPrefix)

BuildRegistry:
server: $(acr-staging-test.server)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,14 @@ stages:
# publishConfig schema is defined in src/ImageBuilder/Configuration/PublishConfiguration.cs.
# This will get converted to JSON and placed in appsettings.json to be loaded by ImageBuilder at runtime.
publishConfig:
InternalMirrorRegistry:
server: $(acr-staging.server)
repoPrefix: $(internalMirrorRepoPrefix)

PublicMirrorRegistry:
server: $(public-mirror.server)
repoPrefix: $(publicMirrorRepoPrefix)
${{ if eq(variables['System.TeamProject'], 'internal') }}:
MirrorRegistry:
server: $(acr-staging.server)
repoPrefix: $(internalMirrorRepoPrefix)
${{ else }}:
MirrorRegistry:
server: $(public-mirror.server)
repoPrefix: $(publicMirrorRepoPrefix)

BuildRegistry:
server: $(acr-staging.server)
Expand Down
17 changes: 7 additions & 10 deletions eng/docker-tools/templates/steps/init-common.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,20 +86,17 @@ steps:
condition: and(succeeded(), ${{ parameters.condition }})

# Build Registry Configuration
# Extends commonMatrixAndBuildOptions with registry-specific settings:
# - Internal builds: Use internal mirror registry prefix and build registry
# server to pull/push from private ACR instead of public MCR
# - Public builds: Override non-MCR base images to use public mirror, reducing
# external dependencies and improving build reliability
# Extends commonMatrixAndBuildOptions with registry-specific settings for
# internal builds:
# - Internal builds push outputs to the build registry instead of MCR.
# - Source mirror selection (for pulling external base images) happens
# automatically inside ImageBuilder based on PublishConfiguration loaded
# from appsettings.json.
- ${{ if parameters.publishConfig }}:
- powershell: |
$commonMatrixAndBuildOptions = "$(commonMatrixAndBuildOptions)"
if ("$(System.TeamProject)" -eq "internal" -and "$(Build.Reason)" -ne "PullRequest") {
$commonMatrixAndBuildOptions = "$commonMatrixAndBuildOptions --source-repo-prefix ${{ parameters.publishConfig.InternalMirrorRegistry.repoPrefix }} --registry-override ${{ parameters.publishConfig.BuildRegistry.server }}"
}

if ("$(System.TeamProject)" -eq "public" -and "$(public-mirror.server)" -ne "") {
$commonMatrixAndBuildOptions = "$commonMatrixAndBuildOptions --base-override-regex '^(?!mcr\.microsoft\.com)' --base-override-sub '$(public-mirror.server)/'"
$commonMatrixAndBuildOptions = "$commonMatrixAndBuildOptions --registry-override ${{ parameters.publishConfig.BuildRegistry.server }}"
}

Write-Host "Setting commonMatrixAndBuildOptions to '$commonMatrixAndBuildOptions'"
Expand Down
11 changes: 11 additions & 0 deletions eng/pipelines/check-base-image-updates.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
trigger: none
pr: none

parameters:
- name: bootstrapImageBuilder
displayName: >
Build ImageBuilder from source at the start of every job instead of pulling
the pre-built image from MCR. Use this option during development to
validate changes to ImageBuilder and pipeline templates at the same time.
type: boolean
default: false

schedules:
- cron: "0 0,4,8,12,16,20 * * *"
displayName: Daily build
Expand All @@ -21,3 +30,5 @@ extends:
- template: /eng/docker-tools/templates/stages/dotnet/publish-config-prod.yml@self
parameters:
stagesTemplate: /eng/pipelines/templates/stages/check-base-image-updates.yml@self
stagesTemplateParameters:
bootstrapImageBuilder: ${{ parameters.bootstrapImageBuilder }}
23 changes: 15 additions & 8 deletions eng/pipelines/templates/jobs/check-base-image-updates.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@ parameters:
# Schema is defined in src/ImageBuilder/Configuration/PublishConfiguration.cs.
- name: publishConfig
type: object
# Additional arguments to pass to the getStaleImages command (optional).
- name: customGetStaleImagesArgs
type: string
default: ""
# When true, build ImageBuilder from source instead of pulling from MCR. Used
# during development to validate ImageBuilder and pipeline template changes
# together before a new ImageBuilder image is published.
- name: bootstrapImageBuilder
type: boolean
default: false

jobs:
- job: ${{ parameters.jobName }}
Expand All @@ -37,32 +39,37 @@ jobs:
parameters:
dockerClientOS: linux
publishConfig: ${{ parameters.publishConfig }}
${{ if eq(parameters.bootstrapImageBuilder, true) }}:
customInitSteps:
- template: /eng/pipelines/templates/steps/bootstrap-imagebuilder.yml@self

- template: /eng/docker-tools/templates/steps/reference-service-connections.yml@self
parameters:
publishConfig: ${{ parameters.publishConfig }}
usesRegistries:
- ${{ parameters.publishConfig.InternalMirrorRegistry.server }}
- ${{ parameters.publishConfig.MirrorRegistry.server }}

- template: /eng/docker-tools/templates/steps/copy-base-images.yml@self
parameters:
acr: ${{ parameters.publishConfig.InternalMirrorRegistry }}
acr: ${{ parameters.publishConfig.MirrorRegistry }}
additionalOptions: "--subscriptions-path '${{ parameters.subscriptionsPath }}'"

- script: >
$(runImageBuilderCmd)
$(runAuthedImageBuilderCmd)
getStaleImages
$(dotnetDockerBot.userName)
$(dotnetDockerBot.email)
--gh-token $(BotAccount-dotnet-docker-bot-PAT)
staleImagePaths
${{ parameters.customGetStaleImagesArgs }}
--subscriptions-path ${{ parameters.subscriptionsPath }}
--os-type '*'
--architecture '*'
$(dockerHubRegistryCreds)
displayName: Get Stale Images
name: GetStaleImages
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
SYSTEM_OIDCREQUESTURI: $(System.OidcRequestUri)

- script: >
$(runImageBuilderCmd)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ jobs:
image: $(default1ESInternalPoolImage)
os: linux
publishConfig: ${{ parameters.publishConfig }}
acr: ${{ parameters.publishConfig.PublicMirrorRegistry }}
acr:
server: $(public-mirror.server)
repoPrefix: $(publicMirrorRepoPrefix)
customInitSteps: ${{ parameters.customInitSteps }}
additionalOptions: '--subscriptions-path ${{ parameters.subscriptionsPath }}'
forceDryRun: ${{ parameters.dryRun }}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ parameters:
# The name of the public Azure DevOps project (e.g., "public").
- name: publicProjectName
type: string
# When true, build ImageBuilder from source instead of pulling from MCR. Used
# during development to validate ImageBuilder and pipeline template changes
# together before a new ImageBuilder image is published.
- name: bootstrapImageBuilder
type: boolean
default: false

stages:
- stage: CheckBaseImages
Expand All @@ -26,12 +32,13 @@ stages:
publicProjectName: ${{ parameters.publicProjectName }}
internalProjectName: ${{ parameters.internalProjectName }}
publishConfig: ${{ parameters.publishConfig }}
bootstrapImageBuilder: ${{ parameters.bootstrapImageBuilder }}

- template: /eng/pipelines/templates/jobs/check-base-image-updates.yml@self
parameters:
jobName: CheckBaseImages_BuildTools
subscriptionsPath: eng/check-base-image-subscriptions-buildtools.json
customGetStaleImagesArgs: --base-override-regex '^((centos|debian|ubuntu):.+)' --base-override-sub '$(overrideRegistry)/$1'
publicProjectName: ${{ parameters.publicProjectName }}
internalProjectName: ${{ parameters.internalProjectName }}
publishConfig: ${{ parameters.publishConfig }}
bootstrapImageBuilder: ${{ parameters.bootstrapImageBuilder }}
6 changes: 4 additions & 2 deletions eng/pipelines/templates/stages/cleanup-acr-images.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ stages:
publishConfig: ${{ parameters.publishConfig }}
usesRegistries:
- ${{ parameters.publishConfig.BuildRegistry.server }}
- ${{ parameters.publishConfig.PublicMirrorRegistry.server }}
- $(public-mirror.server)
serviceConnections:
- name: $(marStatus.serviceConnectionName)
- script: mkdir -p $(Build.ArtifactStagingDirectory)/eol-annotation-data
Expand All @@ -96,7 +96,9 @@ stages:
acr: ${{ parameters.publishConfig.BuildRegistry }}
- template: /eng/pipelines/templates/steps/set-eol-annotations.yml@self
parameters:
acr: ${{ parameters.publishConfig.PublicMirrorRegistry }}
acr:
server: $(public-mirror.server)
repoPrefix: $(publicMirrorRepoPrefix)
- template: /eng/docker-tools/templates/steps/publish-artifact.yml@self
parameters:
path: $(Build.ArtifactStagingDirectory)/eol-annotation-data
Expand Down
Loading
Loading