.netblazorazure-pipelineswinui-3dotnet-publish

.NET Publish in Azure Pipelines overwrites first publish on second run


I have the following code in azure-pipelines.yml to publish 2 projects:

trigger:
  branches:
    include:
      - main

pool:
  vmImage: 'windows-latest'

steps:
- task: UseDotNet@2
  displayName: 'Use .NET'
  inputs:
    packageType: 'sdk'
    version: '8.0.x'

- task: NuGetToolInstaller@1
  displayName: 'NuGet Installer'


- task: VSBuild@1
  displayName: 'Restore WinUI3Project'
  inputs:
    solution: 'src/WinUI3Project/WinUI3Project.csproj'
    msbuildArgs: '/restore /p:Configuration=Release /p:Platform="x64"'

- task: VSBuild@1
  displayName: 'Restore BlazorServerProject'
  inputs:
    solution: 'src/BlazorServerProject/BlazorServerProject.csproj'
    msbuildArgs: '/restore /p:Configuration=Release /p:Platform="x64"'


- task: DotNetCoreCLI@2
  displayName: 'Publish WinUI3Project'
  inputs:
    command: 'publish'
    arguments: '--configuration Release --output $(Build.BinariesDirectory)\WinUI3Project'
    projects: 'src/WinUI3Project/WinUI3Project.csproj'

- task: CopyFiles@2
  displayName: 'Copy WinUI3Project Files to Staging Directory'
  inputs:
    SourceFolder: '$(Build.BinariesDirectory)\WinUI3Project'
    Contents: '**'
    TargetFolder: '$(Build.ArtifactStagingDirectory)\WinUI3Project'


- task: DotNetCoreCLI@2
  displayName: 'Publish BlazorServerProject'
  inputs:
    command: 'publish'
    arguments: '--configuration Release --output $(Build.BinariesDirectory)\BlazorServerProject'
    projects: 'src/BlazorServerProject/BlazorServerProject.csproj'

- task: CopyFiles@2
  displayName: 'Copy BlazorServerProjectFiles to Staging Directory'
  inputs:
    SourceFolder: '$(Build.BinariesDirectory)\BlazorServerProject'
    Contents: '**'
    TargetFolder: '$(Build.ArtifactStagingDirectory)\BlazorServerProject'


- task: PublishBuildArtifacts@1
  displayName: 'Publish Build Artifacts'
  inputs:
    pathToPublish: '$(Build.ArtifactStagingDirectory)'
    artifactName: 'drop'
    publishLocation: 'Container'

However, when I look at my published artifacts, I get this:

drop
├─ WinUI3Project
|   └─ BlazorServerProject.zip
└─ BlazorServerProject
   └─ BlazorServerProject.zip

Both zip files contain the same project/files, i.e. they are identical. If I re-order the yaml file such that the blazor server project is built, published, and copied first, I get the same result: blazor server project both times.

I've tried publishing both projects using the same DotNetCoreCLI@2 step, but could not find a syntax that worked to publish 2 specific projects in the same step. Passing **/*.csproj is not appropriate for my use case, as the repository contains other projects which should not be built in the pipeline.

I'm not looking for workarounds (e.g. creating a new .sln file that contains only the projects I want to build), but instead an understanding of why the pipeline is behaving in this way and a way to specifically target 2 .csproj files for publishing to the build artifacts.


Solution

  • Refer to this doc: DotNetCoreCLI@2 - .NET Core v2 task

    publishWebProjects - Publish web projects

    boolean. Optional. Use when command = publish. Default value: true.

    If this input is set to true, the projects property value is skipped, and the task tries to find the web projects in the repository and run the publish command on them.

    When you use the dotnet publish task to build your project, you need to set the publishWebProjects to false. Then the projects field value will work as expected. If the value is true, it will ignore the projects field and publish web projects in the repo.

    For example:

    - task: DotNetCoreCLI@2
      displayName: 'Publish WinUI3Project'
      inputs:
        command: 'publish'
        publishWebProjects: false
        arguments: '--configuration Release --output $(Build.BinariesDirectory)\WinUI3Project'
        projects: 'src/WinUI3Project/WinUI3Project.csproj'
    

    Here is the full YAML:

    trigger:
      branches:
        include:
          - main
    
    pool:
      vmImage: 'windows-latest'
    
    steps:
    - task: UseDotNet@2
      displayName: 'Use .NET'
      inputs:
        packageType: 'sdk'
        version: '8.0.x'
    
    - task: NuGetToolInstaller@1
      displayName: 'NuGet Installer'
    
    
    - task: VSBuild@1
      displayName: 'Restore WinUI3Project'
      inputs:
        solution: 'src/WinUI3Project/WinUI3Project.csproj'
        msbuildArgs: '/restore /p:Configuration=Release /p:Platform="x64"'
    
    - task: VSBuild@1
      displayName: 'Restore BlazorServerProject'
      inputs:
        solution: 'src/BlazorServerProject/BlazorServerProject.csproj'
        msbuildArgs: '/restore /p:Configuration=Release /p:Platform="x64"'
    
    
    - task: DotNetCoreCLI@2
      displayName: 'Publish WinUI3Project'
      inputs:
        command: 'publish'
        publishWebProjects: false
        arguments: '--configuration Release --output $(Build.BinariesDirectory)\WinUI3Project'
        projects: 'src/WinUI3Project/WinUI3Project.csproj'
    
    - task: CopyFiles@2
      displayName: 'Copy WinUI3Project Files to Staging Directory'
      inputs:
        SourceFolder: '$(Build.BinariesDirectory)\WinUI3Project'
        Contents: '**'
        TargetFolder: '$(Build.ArtifactStagingDirectory)\WinUI3Project'
    
    
    - task: DotNetCoreCLI@2
      displayName: 'Publish BlazorServerProject'
      inputs:
        command: 'publish'
        publishWebProjects: false
        arguments: '--configuration Release --output $(Build.BinariesDirectory)\BlazorServerProject'
        projects: 'src/BlazorServerProject/BlazorServerProject.csproj'
    
    - task: CopyFiles@2
      displayName: 'Copy BlazorServerProjectFiles to Staging Directory'
      inputs:
        SourceFolder: '$(Build.BinariesDirectory)\BlazorServerProject'
        Contents: '**'
        TargetFolder: '$(Build.ArtifactStagingDirectory)\BlazorServerProject'
    
    
    - task: PublishBuildArtifacts@1
      displayName: 'Publish Build Artifacts'
      inputs:
        pathToPublish: '$(Build.ArtifactStagingDirectory)'
        artifactName: 'drop'
        publishLocation: 'Container'
    

    In this case, the contents in the two zip files will be different.