How to push nuget package in GitHub actions

Second Update: I got an answer in the GitHub issue from jcansdale that says (haven't tested this):

Support for the dotnet nuget push --api-key option has now been added to GitHub Packages. For some reason this works consistently, but using basic auth (password in nuget.config file) fails randomly!

Example:

  - name: Publish Nuget to GitHub registry
    run: dotnet nuget push ./<project>/out/*.nupkg -k ${GITHUB_TOKEN} -s https://nuget.pkg.github.com/<organization>/index.json --skip-duplicate --no-symbols 
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Update: Based on Dids answer on GitHub my configuration works now like this:

name: NuGet Generation

on:
  push:
    branches:
      - master
  pull_request:
    types: [closed]
    branches:
      - master

jobs:
  build:
    runs-on: ubuntu-18.04
    name: Update NuGet package
    steps:

      - name: Checkout repository
        uses: actions/checkout@v1

      - name: Setup .NET Core @ Latest
        uses: actions/setup-dotnet@v1
        with:
          source-url: https://nuget.pkg.github.com/<organization>/index.json
        env:
          NUGET_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}        
          
      - name: Build solution and generate NuGet package
        run: |  
          cd <project>
          dotnet pack -c Release -o out  

      - name: Push generated package to GitHub registry
        run: dotnet nuget push ./<project>/out/*.nupkg --skip-duplicate --no-symbols true

Note: At the time of writing I needed to use --no-symbols true instead of --no-symbols to prevent exceptions in the dotnet NuGet client.


Old answer:

I switched to the Windows image and got it to work based on the example of @anangaur. This is my final code:

name: NuGet Generation

on:
  push:
    branches:
      - master

jobs:
  build:
    runs-on: windows-latest
    name: Update NuGet 
    steps:

      - name: Checkout repository
        uses: actions/checkout@master

#  latest image has .NET already installed!
#      - name: Setup .NET environment
#        uses: actions/setup-dotnet@v1
#        with:
#          dotnet-version: '2.2.105' 
          
      - name: Build solution and generate NuGet package
        run: |  
          cd SOLUTION_FOLDER
          dotnet pack -c Release -o out  

      - name: Install NuGet client
        uses: warrenbuckley/Setup-Nuget@v1
        
      - name: Add private GitHub registry to NuGet
        run: nuget sources add -name "GPR" -Source https://nuget.pkg.github.com/ORGANIZATION_NAME/index.json -Username ORGANIZATION_NAME -Password ${{ secrets.GITHUB_TOKEN }}
        
      - name: Push generated package to GitHub registry
        run: nuget push .\SOLUTION_FOLDER\PROJECT_FOLDER\out\*.nupkg -Source "GPR" -SkipDuplicate


You can use the dotnet nuget add source command:

    - name: NuGet push
      run: |
        dotnet nuget add source https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json --name github --username ${{ github.repository_owner }} --password ${{ github.token }} --store-password-in-clear-text
        dotnet nuget push **/*.nupkg --source github

The --store-password-in-clear-text option was required for me when running in a linux environment.

With this method, there's no need to modify the actions/setup-dotnet task. Also, this method would allow you to push to multiple NuGet streams if needed.


Here is a workaround that works on all platforms:

name: prerelease NuGet

on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    # also works with windows-latest and macos-latest
    steps:
    - name: Checkout repository
      uses: actions/checkout@v1
    - name: Build with dotnet
      run: dotnet build --configuration Release --version-suffix prerelease-$(date +%Y%m%d%H%M%S)
      shell: bash
    - name: Publish nuget
      run: |
           for f in ./[repository]/bin/Release/*.nupkg
           do
             curl -vX PUT -u "[user]:${{ secrets.GHPackagesToken }}" -F package=@$f https://nuget.pkg.github.com/[user]/
           done
      shell: bash

Notes:

  • this creates a datestamped prerelease build for every git push and uploads it to nuget
    • for the suffix to work, you need to set <VersionPrefix> instead of <Version> in your .csproj
    • if you don't want the prerelease suffix, remove the --version-suffix parameter
  • the shell is explicitly set as bash in order to allow compatibility with building on windows
  • you will need to replace [user] and [repository] above with your own specific values
    • you will need to create a personal access token with the permissions of write:packages
    • then create a GitHub Secret named GHPackagesToken and put the token created above in there
    • using GitHub Secrets eliminates the need for a separate file containing your token
  • this assumes you're have <GeneratePackageOnBuild>true</GeneratePackageOnBuild> in your .csproj
    • if you don't, then you will need an additional step running dotnet pack
  • make sure to specify <RepositoryUrl>...</RepositoryUrl> in your .csproj
  • for a working example if you can't get the above code working, see https://github.com/vslee/IEXSharp/blob/master/.github/workflows/dotnetcore.yml, which pushes to https://github.com/vslee/IEXSharp/packages (ignore all of my extraneous comments there)
    • I posted this bc I tried both the examples from jwillmer above, as well as @anangaur and @marza91 on the GH issue thread but neither worked for me (on any platform)
  • once GitHub fixes the issue of not being able to use the API key directly in the dotnet nuget push command (see initial post of GH issue), then we won't need this workaround anymore