2

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 :)

MagiKruiser
  • 421
  • 1
  • 5
  • 17

2 Answers2

1

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.

Stelios Giakoumidis
  • 1,670
  • 1
  • 3
  • 16
  • Hi, thanks for your reply. The first step "Use .NET Core" inputs comes out with SDK v3.1.201 being installed. This is the matching version on my computer. I tried both win-64 & linux agent. I know it makes very little sense, that's pretty much I'm posting here. ZipAfterPublish could work I guess but it'd zip all files I assume, hiding the issue instead of fixing it ? – MagiKruiser May 12 '20 at 20:03
  • Tried your yaml, same as singlefile, not zip file published, only a bunch of dll :( – MagiKruiser May 12 '20 at 20:14
  • I guessed that you checked that the SDKs versions were matching, locally and remotely, that is why my comment. Regarding ZipAfterPublish, it is supposed to zio all files, but I do not see the "problem". I tested the second solution writing the answer. Can you post your whole yaml file? – Stelios Giakoumidis May 12 '20 at 21:13
  • The first post contains the whole yaml, it's a very simple build pipeline, the problem is that even including your modification, which should produce a .zip file in the published artifact I assume, nothing changes. 120+ files, no zip. Same as SingleFile parameters which doesn't produce a big executable file. (see main post for my new yaml including your suggestions) + feel free to tell me if I missed something, which is possible. – MagiKruiser May 12 '20 at 22:12
  • 1
    I found the problem, you need to specify the command when you do the publish. I will update the answer – Stelios Giakoumidis May 13 '20 at 06:49
  • God you're right, I originally came from a non yaml pipeline, and while messing around I didn't realise I had left the last step as 'build' instead of publish and then forgot to add the command part in the yaml.. As a result it was publishing a build output not the publish result. – MagiKruiser May 13 '20 at 08:14
  • It might actually work the PublishSingleFile=true as well. I deleted my test project to test myself. But it should work now. Happy to hear it helped... – Stelios Giakoumidis May 13 '20 at 08:16
  • It does work with SingleFile as well, when I realised I forgot the publish command part I tested that rightaway and it fixed it. Thanks a lot :) – MagiKruiser May 13 '20 at 08:22
1

I've tested your .yml file, the log showed dotnet build not dotnet publish. You could try the following code:

- task: DotNetCoreCLI@2
  inputs:
    command: 'publish'
    projects: '**/*.csproj'
    arguments: '--configuration Release --output "$(build.artifactstagingdirectory)"'
    modifyOutputPath: true
    zipAfterPublish: true

Or


- task: DotNetCoreCLI@2
  inputs:
    command: 'custom'
    projects: '**/*.csproj'
    custom: 'publish'
    arguments: '--configuration Release --output $(build.artifactstagingdirectory)'
Cece Dong - MSFT
  • 25,734
  • 1
  • 13
  • 30
  • Yeah you're 100% right, I just accepted the above answer that mentionned that, updated the first post with the working yaml. I feel dumb :D – MagiKruiser May 13 '20 at 08:20