.net-coreazure-pipelinesnuget-packageazure-pipelines-build-tasktrusted-signing

Sign internal assemblies of a nuget package with Microsoft's Trusted Signing


Presently hosting NuGet artifacts internally using Azure DevOps, but need to sign the contents (signing the NuGet Package itself is not required). Currently the following pipeline task is used to generate the NuGet package:

- task: DotNetCoreCLI@2
  displayName: 'Build Nuget Package'
  inputs:
    command: 'build'
    projects: '$(solution)'
    arguments: '-c $(buildConfiguration)'

But this automatically generates the *.nupkg file, inside are several assemblies for various runtimes that need to be signed. How can Microsoft's Trusted Signing be used to do this?


Solution

  • The build/package process has to be split. Remove the <GeneratePackageOnBuild>True</GeneratePackageOnBuild> from the *.csproj and run dotnet build {solution}, followed by signing, then lastly running dotnet pack {solution} --no-build will work (for the YAML packaging task you have to specify nobuild: true as adding the actual argument --no-build is ignored).

    Here is the full pipeline for reference:

    trigger:
    - refs/tags/v*.*.*
    
    pool:
      vmImage: 'windows-latest'
    
    variables:
      solution: '**/*.sln'
      buildPlatform: 'Any CPU'
      buildConfiguration: 'Release'
      ARM_CLIENT_ID: ''
      ARM_ID_TOKEN: ''
      ARM_TENANT_ID: ''
      
    steps:
        
    - task: DotNetCoreCLI@2
      displayName: 'Build Solution'
      inputs:
        command: 'build'
        projects: '$(solution)'
        arguments: '-c $(buildConfiguration)'
    
    - task: AzureCLI@2
      displayName: 'Azure Connection'
      inputs:
        azureSubscription: '{ServiceConnectionHere}'
        scriptType: 'ps'
        scriptLocation: 'inlineScript'
        inlineScript: |
          Write-Host "##vso[task.setvariable variable=ARM_CLIENT_ID;issecret=true]$env:servicePrincipalId"
          Write-Host "##vso[task.setvariable variable=ARM_ID_TOKEN;issecret=true]$env:idToken"
          Write-Host "##vso[task.setvariable variable=ARM_TENANT_ID;issecret=true]$env:tenantId"
        addSpnToEnvironment: true
    
    - task: PowerShell@2
      displayName: 'Federated Login'
      inputs:
        targetType: 'inline'
        script: 'az login --service-principal -u $(ARM_CLIENT_ID) --tenant $(ARM_TENANT_ID) --allow-no-subscriptions --federated-token $(ARM_ID_TOKEN)'
    
    - task: TrustedSigning@0
      displayName: 'Trusted Signing'
      inputs:
        ExcludeEnvironmentCredential: true
        ExcludeWorkloadIdentityCredential: true
        ExcludeManagedIdentityCredential: true
        ExcludeSharedTokenCacheCredential: true
        ExcludeVisualStudioCredential: true
        ExcludeVisualStudioCodeCredential: true
        ExcludeAzureCliCredential: false
        ExcludeAzurePowershellCredential: true
        ExcludeAzureDeveloperCliCredential: true
        ExcludeInteractiveBrowserCredential: true
        Endpoint: 'https://eus.codesigning.azure.net'
        TrustedSigningAccountName: '{TrustedSigningAccountNameHere}'
        CertificateProfileName: '{CertificateProfileNameHere}'
        FilesFolder: '$(Build.SourcesDirectory)/src/code/{ProjectNameHere}/bin/$(buildConfiguration)'
        FilesFolderFilter: 'dll'
        FilesFolderRecurse: true
        FileDigest: 'SHA256'
        TimestampRfc3161: 'http://timestamp.acs.microsoft.com'
        TimestampDigest: 'SHA256'
        
    - task: DotNetCoreCLI@2
      displayName: 'Bundle Nuget Package'
      inputs:
        command: 'pack'
        projects: '$(solution)'
        nobuild: true
    
    - task: DotNetCoreCLI@2
      displayName: 'Publish Nuget Package'
      inputs:
        command: 'push'
        packagesToPush: '$(Build.ArtifactStagingDirectory)/*.nupkg'
        nuGetFeedType: 'internal'
        publishVstsFeed: '{publishVstsFeedHere}'