Search code examples
.net-coreazure-devopscommand-line-interfaceazure-pipelinespublish

AzureDevOps - Can't publish as single file


Edit: see end of the post for working yaml.

I'm trying to publish a .NET Core 3.1 Console App as single file however I can't seem to succeed through Azure Devops Pipelines:

Self-contained or not, the publish result is always a bunch of dll instead of just being my executable.

Publishing as single fine works just fine on my computer (publishing from VS or the .NET Core CLI with the params I've set in the yaml below)

Here's the yaml responsible for the build:

# Starter pipeline
# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml

trigger:
- feature/linux

pool:
  vmImage: 'ubuntu-latest'

steps:
- task: UseDotNet@2
  displayName: 'Use .Net Core sdk 3.1.x'
  inputs:
    version: 3.1.x

- task: DotNetCoreCLI@2
  displayName: 'dotnet restore'
  inputs:
    command: restore
    projects: './Project/Project.csproj'
    feedsToUse: config
    nugetConfigPath: ./NuGet/NuGet.Config

- task: DotNetCoreCLI@2
  displayName: 'dotnet publish'
  inputs:
    projects: './Project/Project.csproj'
    arguments: '-o $(build.artifactstagingdirectory) -r linux-x64 -c Release -f netcoreapp3.1 -p:PublishSingleFile=true -p:SelfContained=false'

- task: PublishBuildArtifacts@1
  displayName: 'Publish Artifact: drop'

Solution:

I'm dumb, simply forgot the command part under dotnet publish.. the resulting command by default is build. Note that you need to also specify

publishWebProjects: false

For a console project, see full working yaml:

# Starter pipeline
# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml

trigger:
- feature/linux

pool:
  vmImage: 'ubuntu-latest'

steps:
- task: DotNetCoreCLI@2
  displayName: 'dotnet restore'
  inputs:
    command: restore
    projects: '**/Project.csproj'
    feedsToUse: config
    nugetConfigPath: ./NuGet/NuGet.Config

- task: DotNetCoreCLI@2
  displayName: 'dotnet publish'
  inputs:
    command: 'publish'
    publishWebProjects: false
    projects: '**/Project.csproj'
    modifyOutputPath: true
    arguments: '-o $(build.artifactstagingdirectory) -r linux-x64 -c Release -f netcoreapp3.1 -p:PublishSingleFile=true -p:SelfContained=false'

- task: PublishBuildArtifacts@1
  displayName: 'Publish Artifact: drop'
  inputs:
    artifactName: 'drop' 
    PathtoPublish: '$(build.artifactstagingdirectory)'

Any help is welcome :)


Solution

  • It would be very weird the same commands to produce different results locally and on the remote server. You use the same SDK, it does not make any sense. The problem is somewhere else in the pipeline. I would suggest the following solutions.

    1) Try to explicitly state the which folder to publish when publishing build artifacts, it seems like it is trying to publish the linux-x64 folder (one folder up). Like:

    - task: PublishBuildArtifacts@1
      displayName: 'Publish Artifact'
      inputs:
        artifactName: 'drop' 
        PathtoPublish: '$(build.artifactstagingdirectory)'
    

    2) Try instead of PublishSingleFile to zipAfterPublish. Like:

    - task: DotNetCoreCLI@2
      displayName: Publish
      inputs:
        command: publish
        modifyOutputPath: true
        arguments: '--configuration $(BuildConfiguration) --output "$(build.artifactstagingdirectory)"'
        zipAfterPublish: true
    
    - task: PublishBuildArtifacts@1
      displayName: 'Publish Artifact'
      inputs:
    projects: './Project/Project.csproj'
        artifactName: 'drop' 
        PathtoPublish: '$(build.artifactstagingdirectory)'
    

    I hope it helps...

    Updated Answer

    You need to specify in the publish task the command like command: publish.

    yaml worked for me is:

    # Starter pipeline
    # Start with a minimal pipeline that you can customize to build and deploy your code.
    # Add steps that build, run tests, deploy, and more:
    # https://aka.ms/yaml
    
    trigger:
    - feature/linux
    
    pool:
      vmImage: 'ubuntu-latest'
    
    steps:
    - task: DotNetCoreCLI@2
      displayName: 'Restore Nuget Packages'
      inputs:
        command: 'restore'
        projects: './Project/Project.csproj'
        feedsToUse: config
        nugetConfigPath: ./NuGet/NuGet.Config
    
    - task: DotNetCoreCLI@2
      displayName: 'dotnet publish'
      inputs:
        command: publish
        modifyOutputPath: true
        arguments: '--configuration Release --output "$(build.artifactstagingdirectory)"'
        zipAfterPublish: true
    
    - task: PublishBuildArtifacts@1
      displayName: 'Publish Artifact: drop'
      inputs:
        artifactName: 'drop' 
        PathtoPublish: '$(build.artifactstagingdirectory)'
    

    By adding the explicitly the publish command in the publish task I confirmed that a zip file created as an artifact.