MSBuild Gitlab CI Docker

For some reason, and I’m assuming it has something to do with licensing, Microsoft doesn’t actually provide an official “MSBuild” docker image. However, they do provide a really simple 5 step process to build one yourself. Generally this wouldn’t be an issue at all however there are some quirks in the GitLab CI workflow that don’t actually allow you to build and use a Dockerfile in a pipeline, it has to be pulled from a registry or a local image. I’ll cover both scenarios in this post.

# escape=

# Use the latest Windows Server Core image with .NET Framework 4.8.
FROM mcr.microsoft.com/dotnet/framework/sdk:4.8-windowsservercore-ltsc2019

# Restore the default Windows shell for correct batch processing.
SHELL ["cmd", "/S", "/C"]

# Download the Build Tools bootstrapper.
ADD https://aka.ms/vs/16/release/vs_buildtools.exe C:\TEMP\vs_buildtools.exe

# Install Build Tools excluding workloads and components with known issues.
RUN C:\TEMP\vs_buildtools.exe --quiet --wait --norestart --nocache 
    --installPath C:\BuildTools 
    --add Microsoft.VisualStudio.Workload.AzureBuildTools 
    --add Microsoft.Component.MSBuild 
    --add Microsoft.VisualStudio.Component.NuGet.BuildTools 
    --add Microsoft.Net.Component.3.5.DeveloperTools 
    --add Microsoft.Net.ComponentGroup.4.7.DeveloperTools 
    --add Microsoft.Net.ComponentGroup.4.8.DeveloperTools 
    --add Microsoft.NetCore.Component.Runtime.3.1 
    --add Microsoft.NetCore.Component.SDK 
    --add Microsoft.VisualStudio.Component.VC.CoreBuildTools 
    --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 
    --add Microsoft.VisualStudio.Component.VC.140 
    --add Microsoft.VisualStudio.Component.VC.v141.x86.x64 
    --add Microsoft.VisualStudio.Component.VC.ATL 
    --add Microsoft.VisualStudio.Component.VC.ATLMFC 
    --add Microsoft.VisualStudio.Workload.AzureBuildTools 
    --add Microsoft.VisualStudio.Workload.AzureBuildTools 
    --remove Microsoft.VisualStudio.Component.Windows10SDK.10240 
    --remove Microsoft.VisualStudio.Component.Windows10SDK.10586 
    --remove Microsoft.VisualStudio.Component.Windows10SDK.14393 
    --remove Microsoft.VisualStudio.Component.Windows81SDK `
 || IF "%ERRORLEVEL%"=="3010" EXIT 0

# A few utility things to install
RUN powershell.exe "iwr -useb get.scoop.sh | iex"
RUN powershell.exe "scoop install aria2 git git-lfs 7zip nuget gcc msys2"

# Define the entry point for the docker container.
# This entry point starts the developer command prompt and launches the PowerShell shell.
ENTRYPOINT ["C:\\BuildTools\\Common7\\Tools\\VsDevCmd.bat", "&&", "powershell.exe","-NoLogo", "-ExecutionPolicy", "Bypass"]

Container Registry

The GitLab container registry, or any registry really, is pretty convenient if you find yourself in a situation where you are having to build docker images that other images depend on across multiple systems. A registry just allows you to pull the image and use it.

Local Image

For some reason, and I’m assuming it has something to do with license, Microsoft doesn’t actually provide an official “MSBuild” docker image. However, they do provide a really simple 5 step process to build one yourself. Generally this wouldn’t be an issue at all however there are some quirks in the GitLab CI workflow that don’t actually allow you to build and use a Dockerfile in a pipeline, it has to be pulled from a registry or a local image, Since I only have a single windows build machine I’m going to just build and store the docker image directly on that rather than pulling it from a registry.

This will require a change to the GitLab runner config file, specifically allowing the runner to check for local images before pulling if it is not found, and this is done by adding the following pull_policy line in the [runners.docker] section.

[[runners]]
  [runners.custom_build_dir]
  [runners.cache]
  [runners.docker]
    pull_policy = "if-not-present"

References

– https://docs.microsoft.com/en-us/visualstudio/install/build-tools-container?view=vs-2019