Search code examples
githubnpmyarnpkggithub-actionsgithub-package-registry

Github actions, 401 unauthorized when installing a Github Package with npm or yarn


When I try to install my npm modules from a GitHub action I get the following error:

npm ERR! 401 Unauthorized - GET https://npm.pkg.github.com/@xxxx%2fxxxx-analytics - Your request could not be authenticated by the GitHub Packages service. Please ensure your access token is valid and has the appropriate scopes configured.

Before you comment, I have configured the .npmrc correctly with the scope and access token, and everything works fine when installing the private package locally.

Here is my GitHub workflow action:

name: JavaScript workflow

on: [push]

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v1
      - name: Use Node.js 12.x
        uses: actions/setup-node@v1
        with:
          node-version: '12.x'
      - name: npmrc
        run: cat .npmrc
      - name: npm install
        run: |
          npm install
        env:
          CI: true
          NPM_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}

here is my .npmrc

@fortawesome:registry=https://npm.fontawesome.com/
//npm.fontawesome.com/:_authToken=XXXXXXXXX
@colonynetworks:registry=https://npm.pkg.github.com
//npm.pkg.github.com:_authToken=XXXXXXXXX
always-auth=true
@react-admin:registry=https://registry.marmelab.com
//registry.marmelab.com:
_auth=XXXXXXXXX
[email protected]
always-auth=true

It's a private repo and the authTokens are currently hardcoded in the .npmrc file.

However while trying to find a solution for this, I did come across this random comment from a Github staff member: https://github.community/t/netlify-getting-401-from-github-package-registry-with-auth-token/16415/3

It's a bit vague, but it sounds like it doesn't accept a hardcoded authToken in the .npmrc file.

So first thing I tried was to use our env variable instead like so:

@xxxx=https://npm.pkg.github.com
//npm.pkg.github.com:_authToken=${NPM_AUTH_TOKEN}

The env variable is correct in our Github repo secrets, and supplied by the workflow.

However this still resulted in the same 401 Unauthorized error.

From looking at other solutions I then tried to generate the .npmrc manually inside the Github action before the install step, like so:

- name: npmrcgen
        run: |
          echo "//npm.pkg.github.com/:_authToken=XXXXXXX" > .npmrc
          echo "@xxxxx=https://npm.pkg.github.com/" >> .npmrc
          echo "@react-admin:registry=https://registry.marmelab.com" >> .npmrc
          echo "//registry.marmelab.com:" >> .npmrc
          echo "_auth=XXXXXXX" >> .npmrc
          echo "[email protected]" >> .npmrc
          echo "always-auth=true" >> .npmrc

During the logging step I added, it the _authToken (only for Github) still shows up as ***, and I still got a 401 Unauthorized error.

At this point I wanted to confirm the .npmrc was even being used, so I removed the second private registry we used for marmelab.com, and sure enough, I got an error saying it was no longer able to install their ra-realtime package. This proves the .npmrc file is indeed being read and used by my Github action, but it's not accepting my Github personal access token.

I have tried to generate a new token as well. It has full access to everything under repo: as well as write:packages and read:packages which is what should be required.

Still 401 Unauthorized in the Github action, and still works fine locally.

Lastly I have tried to install it with yarn instead of npm. Unsurprisingly this did not fix it either.

I have seen and tried the following solutions without any success:

One thing I have not tried, as I have seen no recommendations on how or this being a good idea, but I have not done an npm login within the Github action. Since no one else has done this, and somehow have it working, I assume this is not necessary.


Solution

  • I contacted GitHub support and they managed to figure out what the problem was.

    Github workflows are more strict than local environments and require an extra / before the auth token:

    spot the difference:

    //npm.pkg.github.com:_authToken=XXXXXXXXX. # broken
    //npm.pkg.github.com/:_authToken=XXXXXXXXX # works
    

    adding the extra / before :_authToken= solved the issue for me.