Skip to content

Provide guidance around an idiomatic way to configure "official" / CI builds #46743

Open
@MattKotsenas

Description

@MattKotsenas

Summary

There doesn't seem to be a standard practice or idiomatic way to specify an "official" build that optional / expensive operations should key off of. Some common types of operations that would benefit from this type of practice:

Different codebases create drastically different methods for configuring similar sets of properties, which makes new developer onboarding more difficult. My goal with this issue is to reach consensus and provide guidance for the ecosystem to increase discoverability.

Example scenario

To ground the conversation, I'll use the common example of enabling warnings as errors when doing an official build. I'm picking this example because it is both one that teams often set, and it's a common source of contention for developers. Some developers want it off while hacking around code; some developers want it on to prevent surprises in CI. @jaredpar has a good summary of the tradeoffs here: dotnet/runtime#78414 (comment).

Note

Specifically for code analysis there's https://learn.microsoft.com/en-us/dotnet/core/project-sdk/msbuild-props#optimizeimplicitlytriggeredbuild, which would let Visual Studio handle the most common case here, however:

  1. it is VS-centric
  2. it doesn't appear to be open to extension
  3. It can be confusing for users, as a build may pass and then fail with no user changes

Based on my experience and a quick review of public GitHub code, here's a sampling of the options folks use today.

Configuration Options

Configuration == Release

<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
  <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>

This one is probably the oldest and most straightforward to understand. However, most devs operate in Debug most of the time, and often CI pipelines run CI tests in Debug in addition to Release.

Pros

  • Simple to understand

Cons

  • Only applies to release
  • Can lead to bit rot in Debug
  • Ties together unrelated concerns

BuildingInVisualStudio

<PropertyGroup Condition=" '$(BuildingInVisualStudio)' != 'true' ">
  <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>

Another one I've seen occasionally is using the BuildingInVisualStudio property as a proxy for "is in dev inner loop". However, it only works for developers using Visual Studio. Additionally, setting this property on the command line to reproduce CI-only issues is likely to break other things.

Pros

  • Automatic proxy for the dev's inner loop

Cons

  • VS-centric
  • Unpopular (only 4 hits in GitHub)

ContinuousIntegrationBuild

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

ContinuousIntegrationBuild is provided by the dotnet/reproducible-builds: Contains the DotNet.ReproducibleBuilds package package, and is consumed by some tools like Source Link, and also mentioned in a few blog posts. The RPB implementation specifically has the issue of being a computed property, requiring consumption in a .targets file, which is confusing for users.

Pros

  • Relatively popular - 3k hits -- Code search results
  • Used by some dotnet projects like SourceLink and official blog posts

Cons

  • Slightly awkward name
  • Requires manual plumbing or adopting RPB

Next steps

Where do we go from here? Ideally we could answer these questions:

  • Are there other options we should consider?
  • Are there any other important pros / cons to call out?
  • What guidance do we want to give?

I think I'm leaning towards having ContinuousIntegrationBuild automatically set by the SDK (ideally this part: https://github.com/dotnet/reproducible-builds/blob/7cf65de99f502a5238065a420b772ba737ab96f5/src/DotNet.ReproducibleBuilds/DotNet.ReproducibleBuilds.props#L15-L38) and then publishing guidance that it's the preferred way to do this sort of customization.

As always, I'm sure there's a lot that I'm missing, so thoughts, suggestions, and alternatives all welcome. Tagging @baronfel as someone who may be an owner here? Also tagging @jaredpar who I assume has opinions in this space, and @rainersigwald for FYI as well.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions