Restore NuGet package created in another repo

I’m trying to push NuGet packages to a GitHub package feed but currently can’t restore GitHub NuGet packages during the build that were created from Actions in another repo:

Your request could not be authenticated by the GitHub Packages service. Please ensure your access token is valid and has the appropriate scopes configured.

NuGet auth token is set with actions/setup-dotnet:

      # https://github.com/actions/setup-dotnet
      -
        name: Setup .NET
        uses: actions/setup-dotnet@v1
        with:
          dotnet-version: '3.1.x'
          source-url: ${{ env.NUGET_URL }}
        env:
          NUGET_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

I also tried using the same token used when pushing the packages that are attempting to be restored here but it’s the same result.

I’m assuming I need to modify NuGet.config so it has the credentials like:

  <packageSourceCredentials>
        <github>
            <add key="Username" value="${USER}" />
            <add key="ClearTextPassword" value="${PAT}" />
        </github>
    </packageSourceCredentials>

However I thought that wouldn’t be required within the context of GitHub actions in the same org?

If it is required, what’s the practical way of doing it? Configuring dotnet CLI for use with GitHub Packages suggest setting these but overlooks the fact that nuget.config is needed locally and in source control and we don’t want the tokens committed to source control. That means hacks of dynamically creating / altering nuget.config or creating a duplicate CI templated version that can be set dynamically in Actions with repo secrets.

1 Like

Hi @ghudik-cas,

However I thought that wouldn’t be required within the context of GitHub actions in the same org?

The ${{ secrets.GITHUB_TOKEN }} token is scoped to the workflow repository. What you can do is create an org level secret containing a PAT with the read:packages scope. You can then use something like ${{ secrets.READ_PACKAGES_TOKEN }} from your workflow.

I’m assuming I need to modify NuGet.config so it has the credentials like

Almost. If you’re using .NET Core 3.1 or above, you can create a nuget.config (all lowercase) file at the base of your repository like:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <packageSources>
        <add key="github" value="https://nuget.pkg.github.com/OWNER/index.json" />
    </packageSources>
    <packageSourceCredentials>
        <github>
            <add key="Username" value="token" />
            <add key="ClearTextPassword" value="%READ_PACKAGES_TOKEN%" />
        </github>
    </packageSourceCredentials>
</configuration>

You can then set the READ_PACKAGES_TOKEN env var on your local machine and when restoring packages using your GitHub Actions workflow.

You could also create a Directory.Build.targets file to check that READ_PACKAGES_TOKEN actually exists.

I hope that helps!

1 Like

Thanks @jcansdale. That helps. Why does it need to be an org level secret though? I thought that was only if you needed to not duplicate secrets between repos (just being used in one repo here). Also org level secrets require Admin I believe which most devs won’t have so it’s a bit more hassle to create having to route through an Admin.

As I mentioned I had also tried replacing ${{ secrets.GITHUB_TOKEN }} with a token that has proper package access but the result was the same. Perhaps there was something else at play or the fact that it wasn’t an org level secret.

The restore is currently working (after populating nuget.config creds) but the push is failing; at the moment I’m using one token with read/write packages (and repo) for both the auth and restore as well as the push but the push result is warn : *** does not have the correct permissions to execute 'CreatePackageVersion'. It also has SSO enabled.

For the time being I’ve removed actions/setup-dotnet and my workflow looks like this:

name: 'Build, Pack, Push'

on:
  workflow_dispatch:
  push:
    branches:
    - develop
  pull_request:
    branches:
    - develop

env:
  DOTNET_CLI_TELEMETRY_OPTOUT: true

jobs:
  build-push:
    runs-on: ubuntu-latest

    steps:
      -
        name: Prep
        run: |
          echo "::set-env name=BUILD_VER::2.3.$GITHUB_RUN_NUMBER"
          echo "::set-env name=CONFIG::Release"
          echo "::set-env name=NUGET_URL::https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json"
          echo "::set-env name=SLN::MyApp.sln"

      -
        name: Checkout
        uses: actions/checkout@v2

      -
        name: Adjust NuGet Config Credentials
        run: |
          rm -f ./nuget.config
          mv nuget.ci.config nuget.config
          echo $(sed -e "s/\${USER}/${{ secrets.PACKAGE_USER }}/" -e "s@\${PAT}@${{ secrets.PACKAGE_TOKEN }}@" nuget.config) >nuget.config

      -
        name: Build
        run: |
          dotnet build \
            ${{ env.SLN }} \
            /p:VersionPrefix=${{ env.BUILD_VER }} \
            --configuration ${{ env.CONFIG }}

      # Sadly we can't use a glob pattern with NuGet pack like we could in Azure DevOps
      -
        name: NuGet Pack
        run: |
          PROJECTS=**/*.csproj

          shopt -s nullglob
          shopt -s globstar

          for p in $PROJECTS
          do
            echo "Packing $p"
            dotnet pack $p \
              --configuration ${{ env.CONFIG }} \
              --no-build \
              /p:Version=${{ env.BUILD_VER }}
          done

      -
        name: NuGet Push
        run: |
          dotnet nuget list source
          dotnet nuget push **/*.nupkg \
            --source ${{ env.NUGET_URL }} \
            --api-key ${{ secrets.PACKAGE_TOKEN }} \
            --skip-duplicate

In any event the GH documentation around this area seems very lacking IMO but maybe I’m missing something.

1 Like

Why does it need to be an org level secret though? I thought that was only if you needed to not duplicate secrets between repos (just being used in one repo here).

You’re right, it doesn’t need to be an org level secret. I find doing it this way convenient for the read:packages PAT. This way workflows have easy access to all of the orgs packages.

I’m using one token with read/write packages (and repo) for both the auth and restore as well as the push but the push result is warn : *** does not have the correct permissions to execute

The access is a combination of the PAT scopes and the read/write access the PAT’s owner has to the associated repository. Could you check that the owner of the PAT has write access to the repository associated with the package?

my workflow looks like this

Here are a few minor suggestions.

env:
  DOTNET_CLI_TELEMETRY_OPTOUT: true

You can use the following to quieten down dotnet (I think this includes telemetry opt out).

env:
  DOTNET_NOLOGO: true

Unfortunately this is ignored. All it will do is suppress the warning, which is misleading.

--api-key ${{ secrets.PACKAGE_TOKEN }}

Could you let me know the name of the repository this is in so I can investigate further? You can send a message using this link:

Thanks,
Jamie.

@jcansdale:

  • Thanks for the cleanup tips - implemented.
  • I sent you a private message though I figured out the problem immediately after (of course)
  • It turns out I forgot to add the Team to the repo that the service account user is in.

Small forgotten thing that wasn’t obvious to me from original error messages.

Thanks for the help

1 Like