JS-DevTools/npm-publish

Action modifies user's npmrc

honzabilek4 opened this issue ยท 7 comments

I get the following error when using this action as github workflow using self hosted runner. It doesn't fail the build and it happens to all npm commands in the job.

Run npm ci
Error: Failed to replace env in config: ${INPUT_TOKEN}
    at /home/ubuntu/actions-runner/_work/_tool/node/14.13.0/x64/lib/node_modules/npm/lib/config/core.js:415:13
    at String.replace (<anonymous>)
    at envReplace (/home/ubuntu/actions-runner/_work/_tool/node/14.13.0/x64/lib/node_modules/npm/lib/config/core.js:411:12)
    at parseField (/home/ubuntu/actions-runner/_work/_tool/node/14.13.0/x64/lib/node_modules/npm/lib/config/core.js:389:7)
    at /home/ubuntu/actions-runner/_work/_tool/node/14.13.0/x64/lib/node_modules/npm/lib/config/core.js:330:24
    at Array.forEach (<anonymous>)
    at Conf.add (/home/ubuntu/actions-runner/_work/_tool/node/14.13.0/x64/lib/node_modules/npm/lib/config/core.js:328:23)
    at ConfigChain.addString (/home/ubuntu/actions-runner/_work/_tool/node/14.13.0/x64/lib/node_modules/npm/node_modules/config-chain/index.js:244:8)
    at Conf.<anonymous> (/home/ubuntu/actions-runner/_work/_tool/node/14.13.0/x64/lib/node_modules/npm/lib/config/core.js:316:10)
    at /home/ubuntu/actions-runner/_work/_tool/node/14.13.0/x64/lib/node_modules/npm/node_modules/graceful-fs/graceful-fs.js:123:16

Here's my workflow file:

name: CI
on: [push, pull_request]
jobs:
  execute:
    runs-on: self-hosted
    steps:
    - name: Set work folder permissions    
      run: pwd && sudo chown -R $USER:$USER ./
    - uses: actions/checkout@v2
    - name: Setup Node.js environment
      uses: actions/setup-node@v1.4.4
      with:
        node-version: 14.x
    - name: Cache node modules
      uses: actions/cache@v1
      env:
        cache-name: cache-node-modules
      with:
        path: ~/.npm # npm cache files are stored in `~/.npm` on Linux/macOS
        key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
        restore-keys: |
          ${{ runner.os }}-build-${{ env.cache-name }}-
          ${{ runner.os }}-build-
          ${{ runner.os }}-
    - name: Install dependencies
      run: npm ci
    - name: Run linter
      run: npm run lint
    - name: Run unit tests
      run: npm run test    
    - name: Build project
      run: npm run build
    - name: Publish to npm 
      uses: JS-DevTools/npm-publish@v1
      if: github.ref == 'refs/heads/master'
      with:
        token: ${{ secrets.NPM_AUTH_TOKEN }}

Edit:
After playing around a bit, I was able to do a workaround by setting INPUT_TOKEN to empty string.

    env: 
      INPUT_TOKEN: ''

For security reasons, this GitHub Action does not write your NPM auth token to the ~/.npmrc file like some other GitHub Actions do. Instead, it writes an environment variable placeholder named INPUT_TOKEN.

However, the bug that you've discovered is that this action leaves that placeholder in your ~/.npmrc file even after the publish step has finished. In many workflows this is fine, since the publish step is the final step of the workflow. But in your case, you're using the cache action as well, and I believe that action is caching the ~/.npmrc file, which results in subsequent runs of your workflow failing because the ~/.npmrc file references a non-existent environment variable named INPUT_TOKEN.

Ultimately, this is a bug ๐Ÿ› in this GitHub Action. It should restore the ~/.npmrc file to its original state after running. But, in the meantime, there are a couple workarounds you could use:

Workarounds

  1. Define an environment variable named INPUT_TOKEN in your workflow.

-- OR --

  1. Remove the cache action from your workflow, so each build starts with a fresh state

I am also getting the same problem when writing any command related to npm. So I solved by node or nodemon. so when you want to start your server use the node and when you want to install any package just remove this and then install it will work.

//registry.npmjs.org/:_authToken=${INPUT_TOKEN}
It will work in both react and node.js for me. Run react also by node by creating own server.js file like in node.js By this, I successfully deployed my application on Heroku.
And in production give your env variable on the server where your are deploying and in your own machine put it in .bash_profile and put it in .gitignore

I am also getting this problem but I find a solution when I am pushing my repo on Heroku so I notice that Heroku run the command react-script start or build

//registry.npmjs.org/:_authToken=${INPUT_TOKEN}
so this syntax didn't give the error but when I use the same syntax in my system and run the command it gives me.
Because usually when we run in our system we use cmd npm or yarn but if you use react-script then it will not gives an error

as @JamesMessinger say this definitely a bug ๐Ÿ›

was able to fix this by setting up the ~/.npmrc file and defining INPUT_TOKEN in the job:

jobs:
  build_test_deploy:
    env:
      INPUT_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: ๐Ÿ”ง Setup .npmrc file for publish
  uses: actions/setup-node@v2
  with:
    node-version: ${{ matrix.node-version }}
    registry-url: 'https://registry.npmjs.org'

you can also replace the INPUT_TOKEN with your own GitHub generated personal token

This would be great it if it was documented, I was bashing my head as to why npm dist-tags commands after this publish action weren't working with NODE_AUTH_TOKEN as set by setup-node until I realised this uses a different envvar name. Maybe instead you could align it with setup-node to NODE_AUTH_TOKEN andpartially prevent this unexpected behaviour

Related fix https://github.com/matrix-org/matrix-js-sdk/pull/2717/files

mcous commented

Rough plan for this bug:

  • Create a separate .npmrc in a temporary directory rather than overwriting ~/.npmrc that may be created by setup-node (or someone else)
  • Align on the NODE_AUTH_TOKEN environment variable internally, as suggested

This is the same exact strategy used by actions/setup-node