doc/dev/Building.md
Building management plane and data plane libraries is already covered in our root CONTRIBUTING.md. This document is focused on understanding how projects are automatically assigned derived properties and how pipelines within this repository interact with common engineering pipelines prevalent across all Azure SDK language repos.
All our SDKs for .NET use SDK-style project files - typically .csproj files. There's typically little to author in these projects because many properties like the assembly name and package name are derived automatically by the C# project system targets. These same targets also find the first Directory.Build.props (processed before the contents of the .csproj file) and Directory.Build.targets (processed after the content of the .csproj file) in ancestor directories. In most cases, that will find those files in the repo root. If you add either of these files in any directory below the root, be sure to add something like the following in an order that makes sense for your use case:
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory).., Directory.Build.props))\Directory.Build.props" />
The root Directory.Build.props and Directory.Build.targets files do little more than include eng/Directory.Common.Build.props and eng/Directory.Common.Build.props, respectively. Within those files is where most of the repo-specific automatic customization happens. Because this repo contains both track 1 (typically Microsoft.Azure.* packages) and track 2 (typically Azure.* packages), most track 2 customizations depend on the property IsClientLibrary, which that and related properties you can find set near the top of eng/Directory.Common.Build.props.
This is also where, for example, the $(RequiredTargetFrameworks) property is set and maintained for both production and test projects, and why that's one of the few properties you have to set in each package project e.g.,
<PropertyGroup>
<TargetFrameworks>$(RequiredTargetFrameworks)</TargetFrameworks>
</PropertyGroup>
Always set the plural <TargetFrameworks> standard property for the correct behavior when building any project whether you are multi-targeting or not.
Detailed more in our root CONTRIBUTING.md, it's notable that contributors will typically run dotnet build or dotnet test in a service directory of package directory, but the pipelines described below typically build using eng/service.proj or eng/mgmt.proj which uses traversal SDK to enumerate all packages within a specified service directory. This means that any solution files are ignored, so you can use them or put them wherever make sense for your SDK.
If you need to customize the collection of projects discovered by either of those traversal projects, you can put a service.projects file in your service direectory with contents like this:
<Project>
<ItemGroup>
<!-- Make sure backup/restore tests in the Administration package do not run parallel with other tests. -->
<ProjectReference Update="$(MSBuildThisFileDirectory)Azure.Security.KeyVault.Administration\tests\Azure.Security.KeyVault.Administration.Tests.csproj">
<TestInParallel>false</TestInParallel>
</ProjectReference>
</ItemGroup>
</Project>
Similar to how all projects require minimal authoring, various Azure Pipelines for each package also require very little authoring and all start from the following files in a service directory:
These pipeline definitions typically contain the necessary triggers, paths to watch, and package information. See existing SDKs' files for examples to avoid duplicating information that may change here. tests.yml might also contain additional matrix generation options to change or add testing environments particular to a service directory.
If you're working on engineering system changes for the .NET repo within one of the files above, you can follow the template directives. Currently, for example, a ci.yml would include a chain of templates like so:
eng/pipelines/variables/globals.yml
eng/pipelines/templates/jobs/ci.yml
This is where a lot of common pipelines under eng/common get included and passed various objects that those pipelines use, including calling back into repo-specific pipelines including jobs, steps, etc.
eng/pipelines/templates/stages/archetype-net-release.yml
Same as above: common pipelines get included and passed various objects here too.
Any changes to the eng directory outside of the common subdirectory are owned by the Azure SDK for .NET team, but you should still coordinate with the central Engineering Systems team to discuss how your changes will work, go over any problems they might think of, and determine whether the changes should actually be common. Any changes within the eng/common subdirectory should be discussed with the central EngSys team and should be made in the https://github.com/Azure/azure-sdk-tools/tree/main/eng/common directory. See here for more information.