skip to Main Content

I am attempting to reproduce as an automated github workfow the steps which allow me to manually publish a package from my local console through an opportune .npmrc file.

If do manually type (from the root folder of my Node.js project):

echo "@myorganization:registry=https://npm.pkg.github.com" > .npmrc
echo "//npm.pkg.github.com/:username=myname" >> .npmrc
echo "//npm.pkg.github.com/:_authToken=xyz" >> .npmrc
npm publish

I succed in publishing my package.

However, if I write in the .yml file:

on:
    release:
        types: [created]
  
jobs:     
   
    build:
        runs-on: ubuntu-latest
        steps:
            - uses: actions/checkout@v3
            - uses: actions/setup-node@v3
              with:
                node-version: 18
            - run: npm ci
            - run: npm test

    publish-gpr: 
        needs: build
        runs-on: ubuntu-latest
        permissions: 
            packages: write
            contents: read
        steps:
            - uses: actions/checkout@v3
            - uses: actions/setup-node@v3 
              with:
                node-version: 16
                registry-url: https://npm.pkg.github.com/              
            - name: npm publish
              env:
                NODE_AUTH_TOKEN: ${{secrets.MY_TOKEN}
              run: |
                echo "myorganization:registry=https://npm.pkg.github.com" > .npmrc
                echo "//npm.pkg.github.com/:username=myname" >> .npmrc
                echo "//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN:?}" >> .npmrc
                npm publish

I get the error:

...
npm notice Publishing to https://npm.pkg.github.com
npm ERR! code E401
npm ERR! 401 Unauthorized - PUT https://npm.pkg.github.com/@myorganization%2fmyrepository - unauthenticated: User cannot be authenticated with the token provided.
...

so that, I suppose, the problem comes from the conversion of the environmental variable NODE_AUTH_TOKEN to the explicit xyz secret value. However, I have not been able to solve such a problem. Can you undestand what is wrong?

2

Answers


  1. Chosen as BEST ANSWER

    Even after having understood how to login non-interactively thorugh .npmrc file (see here) I have still been struggling for hours before succeding in automating the publication of my package. Thus, let me advice anyone else that, in the context of the github workflow, the location of the .nmprc file is referenced by the environmental variable NPM_CONFIG_USERCONFIG, that is, you cannot simply state:

    echo "@myOrg:registry=https://npm.pkg.github.com" > .npmrc
    echo "//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN:?}" >> .npmrc
    

    in your .yml file. You have, instead, to write:

    echo "@myOrg:registry=https://npm.pkg.github.com" > ${NPM_CONFIG_USERCONFIG:?}
    echo "//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN:?}" >> ${NPM_CONFIG_USERCONFIG:?}
    

    Moreover, if you are publishing your packge under some organization scope, you must use an organization token, not your personal token, even if you are the organization owner.

    The working .yml file is below:

    on:
        release:
            types: [created]
      
    jobs:     
       
        build:
            runs-on: ubuntu-latest
            steps:
                - uses: actions/checkout@v3
                - uses: actions/setup-node@v3
                  with:
                    node-version: 18
                - run: |
                    npm ci
                    npm test
    
        publish-gpr: 
            needs: build
            runs-on: ubuntu-latest
            permissions: 
                packages: write
                contents: read
            steps:
                - uses: actions/checkout@v3
                - uses: actions/setup-node@v3 
                  with:
                    node-version: 18
                    registry-url: https://npm.pkg.github.com/  
                    scope: "@org"
                - name: npm publish
                  env:
                    NODE_AUTH_TOKEN: ${{secrets.ORG_TOKEN}}
                  run: |           
                    echo "@org:registry=https://npm.pkg.github.com" > ${NPM_CONFIG_USERCONFIG:?}
                    echo "//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN:?}" >> ${NPM_CONFIG_USERCONFIG:?}
                    npm publish
    

    I hope this can help.


  2. Cause looks to me that the newly introduced parameter NODE_AUTH_TOKEN is missing in the environment.

    This is noticed only later, when npm publish is invoked and errors.

    Some hints and example:

    When you convert into a workflow, start porting your command sequence into a single run: as it belongs together.

    Also always put the env: before the run: so that the environment is visible upfront (and you spot missing parameters more easily).

    Finally, error on required parameters if they are empty (${NODE_AUTH_TOKEN:?}), so it is as early as possible to produce the error and it is easy to localize.

            - name: npm publish
              env:
                NODE_AUTH_TOKEN: ${{secrets.MY_TOKEN}}    
              run: |
                echo "@myorganization:registry=https://npm.pkg.github.com" >> .npmrc
                echo "//npm.pkg.github.com/:username=myname" >> .npmrc
                echo "//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN:?}" >> .npmrc
                npm publish
    

    To make it even more failsafe, you could change the first write to .npmrc create that file by using > instead of >> which is appending. In case the file would exist (unclean build), you would not run into such a problem late. But strictly speaking this is not necessary.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search