• Stars
    star
    126
  • Rank 284,543 (Top 6 %)
  • Language
    C#
  • License
    MIT License
  • Created over 4 years ago
  • Updated over 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Shows how to do deterministic builds with .NET

Deterministic Builds

This repo shows how to get a fully deterministic build using Source Link. Deterministic builds are important as they enable verification that the resulting binary was built from the specified source and provides traceability.

Deterministic builds require a property to be set to true during CI: ContinuousIntegrationBuild. These should not be enabled during local dev or the debugger won't be able to find the local source files.

Therefore, you should use your CI system's variable to set them conditionally. For Azure Pipelines, it looks like this

<PropertyGroup Condition="'$(TF_BUILD)' == 'true'">
  <ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
</PropertyGroup>

For GitHub Actions, the variable is GITHUB_ACTIONS, so the result would be:

<PropertyGroup Condition="'$(GITHUB_ACTIONS)' == 'true'">
  <ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
</PropertyGroup>

Or another option is to pass it to msbuild or dotnet with /p:ContinuousIntegrationBuild=true

Also EmbedUntrackedSources should be enabled so that compiler-generated source, like AssemblyInfo, are included in the PDB.

Add in your .csproj under <PropertyGroup>:

 <EmbedUntrackedSources>true</EmbedUntrackedSources>

Work around for .NET SDK prior 3.1.300

Note that there's a workaround needed for many SDK's prior to 3.1.300. You'll need to add a Directory.Build.targets file with the following:

<Project>
  <PropertyGroup>
    <TargetFrameworkMonikerAssemblyAttributesPath>$([System.IO.Path]::Combine('$(IntermediateOutputPath)','$(TargetFrameworkMoniker).AssemblyAttributes$(DefaultLanguageSourceExtension)'))</TargetFrameworkMonikerAssemblyAttributesPath>
  </PropertyGroup>
  <ItemGroup>
    <EmbeddedFiles Include="$(GeneratedAssemblyInfoFile)"/>
  </ItemGroup>
</Project>

Building locally

To see/test this locally, build with dotnet build /p:ContinuousIntegrationBuild=true. After uploading to nuget.org, you could check it with NuGet Package Explorer:

image