| MSBuild-6 :👈 | 👉:MSBuild-With-AI |
Day 7 – Real-World MSBuild Automation Scenarios |
This final lesson brings together everything learned during Days 1–6 and applies it to real-world scenarios used in modern .NET applications, MAUI apps, DevOps pipelines, and enterprise builds.
Many teams automate version numbers using MSBuild properties.
<PropertyGroup> <Major>1</Major> <Minor>0</Minor> <Patch>$([System.DateTime]::Now.DayOfYear)</Patch> <Version>$(Major).$(Minor).$(Patch)</Version> </PropertyGroup>
This produces versions like 1.0.123 (123 = day of year).
<Target Name="GitVersion" BeforeTargets="Build">
<Exec Command="git rev-parse --short HEAD > gitversion.txt" />
<ReadLinesFromFile File="gitversion.txt">
<Output TaskParameter="Lines" PropertyName="GitHash" />
</ReadLinesFromFile>
<Message Text="Git Commit: $(GitHash)" />
</Target>
You can switch logic based on environment variables or custom properties.
<PropertyGroup> <Environment>$(BUILD_ENVIRONMENT)</Environment> </PropertyGroup> <Target Name="ShowEnv"> <Message Text="Building for environment: $(Environment)" /> </Target>
Call with:
dotnet build -p:BUILD_ENVIRONMENT=Production
DevOps pipelines often use MSBuild targets to create artifacts, run scripts, and modify output folder structure.
<Target Name="PackageArtifacts" AfterTargets="Publish">
<MakeDir Directories="artifacts" />
<Copy
SourceFiles="@(PublishFiles)"
DestinationFolder="artifacts" />
</Target>
- task: DotNetCoreCLI@2
inputs:
command: 'build'
projects: '**/*.csproj'
arguments: '-t:PackageArtifacts'
MSBuild can generate files on the fly before compilation.
<Target Name="GenerateVersionFile" BeforeTargets="Compile">
<WriteLinesToFile
File="VersionInfo.cs"
Lines="public static class VersionInfo { public const string Build = "$(Version)"; }" />
</Target>
<ItemGroup>
<Compile Include="VersionInfo.cs" />
</ItemGroup>
This file is included in the project automatically.
MAUI uses MSBuild heavily for platform-specific builds. You can hook into different targets depending on platform.
<Target Name="AndroidPreBuild"
BeforeTargets="Build"
Condition=" '$(TargetFramework)' == 'net8.0-android' ">
<Message Text="Running Android pre-build logic..." />
</Target>
<Target Name="iOSBundleStep"
AfterTargets="Build"
Condition=" '$(TargetFramework)' == 'net8.0-ios' ">
<Message Text="iOS custom packaging step..." />
</Target>
Use Exec to run external tools like linters, bundlers, or CLI utilities.
<Target Name="CheckFormatting" BeforeTargets="Build">
<Exec Command="dotnet format --verify-no-changes" />
</Target>
If formatting issues exist, the build fails.
Reorganize the publish folder using post-publish logic.
<Target Name="ReorganizeOutput" AfterTargets="Publish"> <MakeDir Directories="publish\static" /> <Copy SourceFiles="wwwroot\**\*" DestinationFolder="publish\static" /> </Target>
To override built-in behavior, keep the original logic and append your own.
<PropertyGroup>
<BuildDependsOn>
CustomCheck;
$(BuildDependsOn)
</BuildDependsOn>
</PropertyGroup>
<Target Name="CustomCheck">
<Message Text="Performing custom checks before Build..." />
</Target>
<Target Name="GenInfo" BeforeTargets="Compile">
<WriteLinesToFile
File="BuildInfo.txt"
Lines="Build: $([System.DateTime]::Now)" />
</Target>
<Target Name="CopyBuildInfo" AfterTargets="Publish">
<Copy
SourceFiles="BuildInfo.txt"
DestinationFolder="$(PublishDir)" />
</Target>
dotnet publish
Check the publish folder for BuildInfo.txt.
You now understand the full power of MSBuild — from basics to advanced automation. You can design custom pipelines, reuse build logic, integrate with DevOps, and control platform-specific behavior.
| MSBuild-6 :👈 | 👉:MSBuild-With-AI |