This post shows how to structure a monorepo for NuGet packages and then automate their build using Azure YAML pipelines.
Project Structure
Use a package’s solution file to define the location of the packages source code and test code. This single solution file can then be passed to the DotNetCoreCLI@2 task to only build and pack that particular package.
Solution files are Common.A.sln and Common.B.sln.
Project file structure for two packages common.A and common.B
/common-nuget-library
   /common
     /common.A
       azure-pipelines.yml
       common.A.sln
       common.A.csproj
       /src
     /common.B  
       azure-pipelines.yml
       common.B.sln
       common.B.csproj
       /src
   /tests  
     common.A.tests
       common.A.tests.csproj
     common.B.tests
       common.B.tests.csproj
Configuring the pipeline for each NuGet package
Next we want to configure a pipeline for each package. The contents of each azure-pipelines.yml are show below.
common.A/azure-pipelines.yml
trigger:
  paths:
    include:
      - common/common.A/*
...
- task: DotNetCoreCLI@2
  displayName: 'DotNet Build'
  inputs:
    command: 'build'
    projects: 'common/common.A/common.A.sln'
- task: DotNetCoreCLI@2
  displayName: 'Dotnet Pack'
  inputs:
    command: 'pack'
    packagesToPack: 'common/common.A/common.A.sln'
    includesymbols: true
    packDirectory: '$(Pipeline.Workspace)/dist'
    configuration: 'Release'
    nobuild: true
    versionEnvVar: 'BUILD_BUILDNUMBER'
    versioningScheme: 'byEnvVar'
    buildProperties: 'SymbolPackageFormat=snupkg'- The pipeline is only triggered when changes occur in common/common.A/*
- The DotNet Build task only builds the packages listed in the solution file ‘common/common.A/common.A.sln’
- The DotNet pack task only packages ‘common/common.A/common.A.sln’
common.B/azure-pipelines.yml
trigger:
  paths:
    include:
      - common/common.B/*
...
- task: DotNetCoreCLI@2
  displayName: 'DotNet Build'
  inputs:
    command: 'build'
    projects: 'common/common.B/common.B.sln'      
- task: DotNetCoreCLI@2
  displayName: 'Dotnet Pack'
  inputs:
    command: 'pack'
    packagesToPack: 'common/common.B/common.B.sln'
    includesymbols: true
    packDirectory: '$(Pipeline.Workspace)/dist'
    configuration: 'Release'
    nobuild: true
    versionEnvVar: 'BUILD_BUILDNUMBER'
    versioningScheme: 'byEnvVar'
    buildProperties: 'SymbolPackageFormat=snupkg'    - The pipeline is only triggered when changes occur in common/common.B/*
- The DotNet Build task only builds the packages listed in the solution file ‘common/common.B/common.B.sln’
- The DotNet pack task only packages ‘common/common.B/common.B.sln’
Create a pipeline for each package
Finally you can create a pipeline to build each package by simply selecting ‘New pipeline’ from the Pipelines tab and providing the the azure-pipelines.yml file for that package.

 
  