Skip to content
This repository has been archived by the owner on Dec 12, 2020. It is now read-only.

Failing to replace ${NPM_AUTH} variable #725

Closed
nimmoadam opened this issue Jun 28, 2020 · 31 comments
Closed

Failing to replace ${NPM_AUTH} variable #725

nimmoadam opened this issue Jun 28, 2020 · 31 comments

Comments

@nimmoadam
Copy link

nimmoadam commented Jun 28, 2020

Which Renovate are you using?

Renovate Open Source CLI

Other (please write below)

Which platform are you using?

GitHub Enterprise

Have you checked the logs? Don't forget to include them if relevant

Error: Failed to replace env in config: ${NPM_AUTH}
    at /home/jenkins/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/Node_12.16.3/lib/node_modules/npm/lib/config/core.js:415:13
    at String.replace (<anonymous>)
    at envReplace (/home/jenkins/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/Node_12.16.3/lib/node_modules/npm/lib/config/core.js:411:12)
    at parseField (/home/jenkins/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/Node_12.16.3/lib/node_modules/npm/lib/config/core.js:389:7)
    at /home/jenkins/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/Node_12.16.3/lib/node_modules/npm/lib/config/core.js:330:24
    at Array.forEach (<anonymous>)
    at Conf.add (/home/jenkins/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/Node_12.16.3/lib/node_modules/npm/lib/config/core.js:328:23)
    at ConfigChain.addString (/home/jenkins/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/Node_12.16.3/lib/node_modules/npm/node_modules/config-chain/index.js:244:8)
    at Conf.<anonymous> (/home/jenkins/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/Node_12.16.3/lib/node_modules/npm/lib/config/core.js:316:10)
    at /home/jenkins/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/Node_12.16.3/lib/node_modules/npm/node_modules/graceful-fs/graceful-fs.js:115:16
/home/jenkins/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/Node_12.16.3/lib/node_modules/npm/lib/npm.js:59
      throw new Error('npm.load() required')
      ^

Error: npm.load() required
    at Object.get (/home/jenkins/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/Node_12.16.3/lib/node_modules/npm/lib/npm.js:59:13)
    at process.errorHandler (/home/jenkins/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/Node_12.16.3/lib/node_modules/npm/lib/utils/error-handler.js:205:32)
    at process.emit (events.js:310:20)
    at process._fatalException (internal/process/execution.js:164:25)

What would you like to do?

Renovate Bot is set up and it works fine until I have added repositories with npm dependencies. So, I have a few repositories with package.json file.

Configuration
I have a separate repository for renovate bot, where I have config.js and jenkinfile and a renovate.sh script to trigger the bot.

Note -
In jenkinsfile, NPM_AUTH value is called and when the job runs I see this in the console logs.
image

In config.js - It will only the list of repo to be scanned.

  1. renovate.sh script is
renovate --log-level debug --host-rules 

which has host-rules for authenticating with maven and docker artifactories.

So in this file, I have added an entry for authenticating NPM. - IT DIDN"T WORK (I saw the exception that I passed above)

  1. In the renovate doc, I also saw one other approach for authentication with NPM private repo.

copy an .npmrc file to the home dir of the bot and it will work for all repositories
So copied a .npmrc from one of my repo to the root of renovate bot's repository.
During the Jenkins job execution, I still saw the same exception.
.npmrm will have these values

_auth = ${NPM_AUTH}
registry=<URL>
always-auth=true

Problem is, there are other env variables that are called from jenkinsfile. They are all getting replaced properly, except NPM_AUTH.

So in both the approaches, I am getting the same issue.

Error: Failed to replace env in config: ${NPM_AUTH}

Should the value NPM_AUTH needs to be called from somewhere else? or Am I missing something else?

Can you please help in resolving this issue. Thanks!

@rarkins
Copy link
Collaborator

rarkins commented Jun 28, 2020

Renovate uses NPM_TOKEN. Can you switch to that?

@nimmoadam
Copy link
Author

nimmoadam commented Jun 28, 2020

Oh!! Okay thanks. I'm trying it out.

  1. Change form NPM_AUTH to NPM_TOKEN
  2. For the failed PRs, this option should be checked
  • If you want to rebase/retry this PR, check this box
  1. Run the job

Ignore the Jenkins logs -- But if this works, then in the PR, what am I supposed to expect? I mean how can I verify if this is resolved?

@rarkins
Copy link
Collaborator

rarkins commented Jun 28, 2020

You should see the artifacts error log comment removed from the PR

@nimmoadam
Copy link
Author

Okay. I still see the same error in the logs and the error log is not removed from the comment.

20:00:50  DEBUG: lock file error (repository=abc, branch=renovate/<package-name>)
20:00:50         "err": {
20:00:50           "killed": false,
20:00:50           "code": 7,
20:00:50           "signal": null,
20:00:50           "cmd": "npm install --package-lock-only --ignore-scripts --no-audit",
20:00:50           "stdout": "",
20:00:50           "stderr": "Error: Failed to replace env in config: ${NPM_AUTH}\n    at /home/jenkins/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/Node_12.16.3/lib/node_modules/npm/lib/config/core.js:415:13\n    at String.replace (<anonymous>)\n    at envReplace 

@rarkins
Copy link
Collaborator

rarkins commented Jun 28, 2020

And I still see NPM_AUTH in your logs, so I'm not surprised

@nimmoadam
Copy link
Author

Nope, it is removed from the renovate bot's repo. Nowhere it is referenced as NPM_AUTH.

But in the abc repository, it is referenced in .npmrc. Is the bot reading that .npmrc file and throwing this error?

If yes, how can we avoid this? Because the NPM_AUTH is called in abc repo and if that needs to be changed, then I guess there are lot of files to touch upon.

@rarkins
Copy link
Collaborator

rarkins commented Jun 28, 2020

Yes, it's being read from every repository you run Renovate in. You can try setting ignoreNpmrcFile=true in your bot config and then configuring npmToken or npmrc fields in your config to override the repository's .npmrc file.

@stale
Copy link

stale bot commented Jul 2, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed soon if no further activity occurs.

@stale stale bot added the pending-closure label Jul 2, 2020
@nimmoadam
Copy link
Author

Hi @rarkins sorry for the delay in testing it out. I have added ignoreNpmrcFile=true in renovate.json (in the abc repository). Also, in the renovate bot repository, I have a renovate.json file and there is an entry for ignoreNpmrcFile=true .

I see the same issue.

13:25:00  DEBUG: npmrc file found in repository (repository=abc, branch=renovate/postcss-loader-3.x)
13:25:00  DEBUG: Generating package-lock.json for ui (repository=abc, branch=renovate/postcss-loader-3.x)
13:25:00  DEBUG: Spawning npm install to create /tmp/renovate/repos/github/abc/<PATH>/package-lock.json (repository=abc, branch=renovate/postcss-loader-3.x)
13:25:00  DEBUG: Updating lock file only (repository=abc, branch=renovate/postcss-loader-3.x)
13:25:00  DEBUG: No node constraint found - using latest (repository=abc, branch=renovate/postcss-loader-3.x)
13:25:00  DEBUG: Executing command (repository=abc, branch=renovate/postcss-loader-3.x)
13:25:00         "command": "npm install --package-lock-only --ignore-scripts --no-audit"
13:25:00  DEBUG: lock file error (repository=abc, branch=renovate/postcss-loader-3.x)
13:25:00         "err": {
13:25:00           "killed": false,
13:25:00           "code": 7,
13:25:00           "signal": null,
13:25:00           "cmd": "npm install --package-lock-only --ignore-scripts --no-audit",
13:25:00           "stdout": "",
13:25:00           "stderr": "Error: Failed to replace env in config: ${NPM_AUTH}\n    at /home/jenkins/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/Node_12.16.3/lib/node_modules/npm/lib/config/core.js:415:13\n    at String.replace (<anonymous>)\n    at envReplace 

renovate.json in renovate-bot repository

image

renovate.json in abc repository

image

@stale stale bot removed the pending-closure label Jul 2, 2020
@viceice
Copy link
Member

viceice commented Jul 2, 2020

@nimmoadam If you configure the same env var NPM_AUTH before running renovate, you need to set trustLevel to high, so renovate will pass it to child processes.

Did you have a .npmrc file in jenkins slave user home dir?

@rarkins I think we have a bug somehow, so ignoreNpmrcFile doesn't work as expected. 🤔

@nimmoadam
Copy link
Author

Hi @viceice -- To make myself clear:

  1. I had replaced NPM_AUTH with NPM_TOKEN in renovate bot's repository.
  2. .npmrc file is present in both renovate bot repo and the abc repository.
  3. ignoreNpmrcFile=true is set in renovate.json of both renovate repo and abc repository
  4. In abc repository, we use both jenkinfile and Travis file for the build purpose. In travis file, we have NPM_AUTH value set as an environment variable.
  5. Based on this comment - Failing to replace ${NPM_AUTH} variable #725 (comment)
    I thought, irrespective of what .npmrc is referring to from the abc repo - the variables used in renovate bot's config & the .npmrc file in the renovate bot will be used.

Please correct me if am wrong. What is the next thing that I can try to resolve this?

Thanks!!

@viceice
Copy link
Member

viceice commented Jul 2, 2020

Renovate will only replace the token in npmrc while decrypt

so you should configure you config.js like (need to be in CWD while starting renovate):

{
  npmrc: `_auth=${process.env.NPM_AUTH}\nregistry=<URL>\nalways-auth=true`
}

or call renovate like (not sure it will work):

renovate --npmrc "_auth=${NPM_AUTH}\nregistry=<URL>\nalways-auth=true"

you you don't need to hardcode the token to your repo. can you please share your current config.js ?

@nimmoadam
Copy link
Author

nimmoadam commented Jul 2, 2020

My config.js will only have the list of repo for scanning. (in renovate bot repo)

module.exports = {
endpoint: 'https://<github-domain>/api/v3/',
repositories: [
'repo1',
'repo2'
],
  };

renovate.json (in renovate bot repo) - all the renovate configurations are done in the respective repositories

{
"extends": ["config:base"],
"ignoreNpmrcFile": true
}

.npmrc (in renovate bot repo)

_auth = ${NPM_TOKEN}
registry=https://<URL>/artifactory/api/npm
always-auth=true

renovate.sh script (in renovate bot repo) - This script will be triggered to run the bot.

renovate --log-level debug --host-rules "[{\"hostType\": \"maven\",\"endpoint\": \"https:\/\/ARTIFACTORY_URL\/\",\"username\": \"${ID}\",\"password\": \"${PASSWORD}\"}, {\"hostType\": \"docker\",\"hostName\": \"<HOSTNAME_DOCKER>\",\"username\": \"${ID}\",\"password\": \"${PASSWORD}\"}, {\"hostType\": \"npm\",\"baseUrl\": \"https:\/\/<REPO_URL>\/\",\"token\": \"${NPM_TOKEN}\"}]"

JenkinsFile (in renovate bot repo)

----
----
environment {
RENOVATE_TOKEN = credentials('token')
PASSWORD = credentials('password')
ID = <USERNAME>
NPM_TOKEN = credentials('npm-auth')
}
----
----

sh './renovate.sh'

What does this mean?

need to be in CWD while starting renovate

@rarkins
Copy link
Collaborator

rarkins commented Jul 2, 2020

Where do you plan to supply the token? e.g. env or CLI?

@nimmoadam
Copy link
Author

Updated the previous comment - #725 (comment)
Please check.

@viceice
Copy link
Member

viceice commented Jul 2, 2020

Cwd is the current working directory. I guess it's the path to the renovate git repo checkout on Jenkins build.

As you already configure a hostRule for npm, you simply need to add --npmrc 'registry=<URL> to your renovate cmd. This should overwrite any .npmrc before running npm install

@stale
Copy link

stale bot commented Jul 6, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed soon if no further activity occurs.

@stale stale bot added the pending-closure label Jul 6, 2020
@nimmoadam
Copy link
Author

nimmoadam commented Jul 7, 2020

Hi, thanks. I did the changes and I don't see this exception in the Jenkins logs any more.

Error: Failed to replace env in config: ${NPM_AUTH}

But I have the concern. I am not sure if this worked. because the PRs are auto-closed without merging. Why does it auto-close the PRs? There are many such PRs that are auto-closed without merging. How to resolve this?

  • Also, @rarkins mentioned that error log comment will be removed from the PR. But it didn't remove anything.

image

Console logs

[2020-07-06T07:11:54.201Z] DEBUG: Found PR #3373 (repository=abc)
[2020-07-06T07:11:54.201Z] DEBUG: getBranchPr(renovate/react-intl-5.x) (repository=abc)
[2020-07-06T07:11:54.201Z] DEBUG: findPr(renovate/react-intl-5.x, undefined, open) (repository=abc)
[2020-07-06T07:11:54.201Z] DEBUG: Found PR #3373 (repository=abc)
[2020-07-06T07:11:54.201Z] DEBUG: Skipping unsupported graphql PullRequests.mergeStateStatus query on GHE (repository=abc)
[2020-07-06T07:11:54.201Z] DEBUG: PR not found in open or closed PRs list - trying to fetch it directly (repository=abc)
[2020-07-06T07:11:54.201Z]        "prNo": 3373
[2020-07-06T07:11:54.777Z] DEBUG: 1 commit matches configured gitAuthor so can rebase (repository=abc)
[2020-07-06T07:11:54.777Z]        "prNo": 3373
[2020-07-06T07:11:54.777Z] DEBUG: updatePr(3373, Update dependency react-intl to v5 - autoclosed, body) (repository=abc)
[2020-07-06T07:11:55.364Z] DEBUG: PR updated (repository=abc)
[2020-07-06T07:11:55.364Z]        "pr": 3373
[2020-07-06T07:11:55.364Z] DEBUG: Deleting orphan branch (repository=abc, branch=renovate/react-intl-5.x)
[2020-07-06T07:11:59.565Z] DEBUG: Deleted remote branch (repository=abc)
[2020-07-06T07:11:59.565Z]        "branchName": "renovate/react-intl-5.x"
[2020-07-06T07:11:59.565Z] DEBUG: No local branch to delete (repository=abc)
[2020-07-06T07:11:59.565Z]        "branchName": "renovate/react-intl-5.x"
[2020-07-06T07:11:59.565Z]  INFO: PR autoclosed (repository=abc)
[2020-07-06T07:11:59.565Z]        "prNo": 3373,
[2020-07-06T07:11:59.565Z]        "prTitle": "Update dependency react-intl to v5"

@stale stale bot removed the pending-closure label Jul 7, 2020
@rarkins
Copy link
Collaborator

rarkins commented Jul 7, 2020

Autoclosing indicates that Renovate itself fails to do a lookup for these packages (prior to any attempt to update the lock file).

@nimmoadam
Copy link
Author

Yea so, this means it won't look up for those packages again? How to resolve this? How do we know, if the NPM has authenticated successfully?

@viceice
Copy link
Member

viceice commented Jul 7, 2020

You need to look at the debug logs at extraction phase

@nimmoadam
Copy link
Author

Yeah. I see the errors now. But I get both 401 and 403.

DEBUG: Dependency lookup failure: unauthorized (repository=abc)
authInfoType": "Basic",
"authInfoToken": "un*****ed",
"err": {
"name": "HTTPError",
"statusCode": 401,
"statusMessage": "Unauthorized"
"body": {
"errors": [
{"status": 401, "message": "Failed to decode basic authentication token"}
]
},
DEBUG: Dependency lookup failure: unauthorized (repository=abc)
"statusCode": 403,
"statusMessage": "Forbidden",
"body": {
"errors": [
{
"status": 403,
"message": "This request is blocked due to recurrent login failures, please try again in 1 seconds"
}
]
},
"message": "Response code 403 (Forbidden)",
"stack": "HTTPError: Response code 403 (Forbidden)\n    at EventEmitter.<anonymous> (/home/jenkins/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/Node_12.16.3/lib/node_modules/renovate/node_modules/got/source/as-promise.js:74:19)\n    at runMicrotasks (<anonymous>)\n    at processTicksAndRejections (internal/process/task_queues.js:97:5)"

What is missing in the configuration?

renovate.json

{
	"extends": ["config:base"],
	"ignoreNpmrcFile": true,
	"npmrc": "registry=<url>\nalways-auth=true\n_auth=${process.env.NPM_TOKEN}"
}

config.js

module.exports = {
  endpoint: '<G_URL>',
  npmrc: 'registry=<URL>\nalways-auth=true\n_auth=${process.env.NPM_TOKEN}',
  repositories: [
    'abc'
  ],
};

@viceice
Copy link
Member

viceice commented Jul 7, 2020

@nimmoadam remove "npmrc": "registry=<url>\nalways-auth=true\n_auth=${process.env.NPM_TOKEN}" from renovate.json otherwise it will override npmrc from config.json

@nimmoadam
Copy link
Author

nimmoadam commented Jul 7, 2020

I did, but it doesn't make any difference. Does the auth code need to be encrypted or something?

In the target repo (abc repo), I have this

renovate.json
"ignoreNpmrcFile": true,

This error in the console log.

"body": {
12:21:23             "errors": [
12:21:23               {"status": 401, "message": "Failed to decode basic authentication token"}
12:21:23             ]
12:21:23           },
12:21:23           "message": "Response code 401 (Unauthorized)",

@viceice
Copy link
Member

viceice commented Jul 7, 2020

@nimmoadam Are you sure NPM_TOKEN is set as env variable? because your log "authInfoToken": "un*****ed", shows, that the token is equal to undefined.

You also need to add a trailing newline \n to your npmrc config, otherwise it will not work.

rc is used under the hood by registry-auth-token for parsing the file.

@nimmoadam
Copy link
Author

nimmoadam commented Jul 7, 2020

@viceice Sorry to bother. But I have tried whatever I can and this error never got resolved.

In the renovate-bot repository, I have this under .npmrc

_auth='${env.NPM_TOKEN}'
registry=https://ARTIFACTORY-URL
always-auth=true

In the renovate-bot repository, the jenkinsfile contains

environment {
    RENOVATE_TOKEN = credentials('git-token')
    NPM_TOKEN = credentials('npm-auth')
  }
    
    stages {
    stage('Trigger CI Pipeline') {
      steps {
        sh 'env'
        echo "${env.NPM_TOKEN}"
        sh 'npm install -g yarn pnpm'
        sh 'npm i -g renovate'
        sh './renovate.sh'
      }
    }
    }

In the renovate-bot repository, config.js has this

module.exports = {
  endpoint: '<GIT_URL>',
  repositories: [
    'abc'
  ],
};

In the renovate-bot repository, renovate.json has

{
"extends": ["config:base"],
"ignoreNpmrcFile": true
}

in renovate-bot repository, renovate.sh is the one which does the work.

renovate --log-level debug --host-rules "[{\"hostType\": \"maven\",\"endpoint\": \"<MAVEN_URL>\",\"username\": \"${INTRANET_ID}\",\"password\": \"${INTRANET_PASSWORD}\"}, {\"hostType\": \"docker\",\"hostName\": \"<DOCKER_HOSTNAME>\",\"username\": \"${ID}\",\"password\": \"${PASSWORD}\"}, {\"hostType\": \"npm\",\"baseUrl\": \"<NPM_URL>",\"token\": \"\$\{env.NPM_TOKEN\}\"\"}]"

In target repo (abc repository), I have renovate.json which contains

"ignoreNpmrcFile": true,

and one .npmrc like this

_auth = ${NPM_AUTH}
registry=https://<NPM_URL>
always-auth=true

It gets stuck here.

17:28:34  DEBUG: Dependency lookup failure: unauthorized (repository=abc)
17:28:34         "pkgUrl": "<url>",
17:28:34         "authInfoType": "Basic",
17:28:34         "authInfoToken": "un*****ed",
17:28:34         "err": {
17:28:34           "name": "HTTPError",

17:28:34           "body": {
17:28:34             "errors": [
17:28:34               {"status": 401, "message": "Failed to decode basic authentication token"}
17:28:34             ]
17:28:34           },
17:28:34           "message": "Response code 401 (Unauthorized)",
17:28:34           "stack": "HTTPError: Response code 401 (Unauthorized)\n    at EventEmitter.<anonymous> (/home/jenkins/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/Node_12.16.3/lib/node_modules/renovate/node_modules/got/source/as-promise.js:74:19)\n    at runMicrotasks (<anonymous>)\n    at processTicksAndRejections (internal/process/task_queues.js:97:5)"

In the Jenkins console logs, I had echo-ed the token and I can see NPM_TOKEN as *****.

This is from Jenkins console.

17:35:36  DEBUG: CLI config
17:35:36         "config": {
17:35:36           "logLevel": "debug",
17:35:36           "hostRules": [
17:35:36             "[{\"hostType\": \"maven\"",
17:35:36             "\"endpoint\": \"URL"",
17:35:36             "\"username\": \"USER\"",
17:35:36             "\"password\": \"****\"}",
17:35:36             "{\"hostType\": \"docker\"",
17:35:36             "\"hostName\": \"HOSTNAME"",
17:35:36             "\"username\": \"USER"",
17:35:36             "\"password\": \"****\"}",
17:35:36             "{\"hostType\": \"npm\"",
17:35:36             "\"baseUrl\": \"URL",
17:35:36             "\"token\": \"****\"\"}]"
17:35:36           ]
17:35:36         }
17:35:36  DEBUG: Env config
17:35:36         "config": {"hostRules": [], "token": "***********"}
17:35:36  DEBUG: Combined config
17:35:36         "config": {
17:35:36           "endpoint": "G-URL",
17:35:36           "repositories": ["ABC"],
17:35:36           "hostRules": [
17:35:36             "[{\"hostType\": \"maven\"",
17:35:36             "\"endpoint\": \"URL",
17:35:36             "\"username\": \"USER",
17:35:36             "\"password\": \"****\"}",
17:35:36             "{\"hostType\": \"docker\"",
17:35:36             "\"hostName\": \"HOSTNAME",
17:35:36             "\"username\": \"USER",
17:35:36             "\"password\": \"****\"}",
17:35:36             "{\"hostType\": \"npm\"",
17:35:36             "\"baseUrl\": \"URL",
17:35:36             "\"token\": \"****\"\"}]"
17:35:36           ],
17:35:36           "token": "***********",
17:35:36           "logLevel": "debug"
17:35:36         }

Am unable to proceed after this. Can you make this work somehow? Thanks!

@nimmoadam
Copy link
Author

@rarkins @viceice Thanks mate! It worked. I did more analysis of the logs and finally having the npmrc reference in config.js worked.

Just one question, Is it possible to disable external dependency checks, and leave only internal checks, not sure if this is possible though.?

@rarkins
Copy link
Collaborator

rarkins commented Jul 9, 2020

What do you mean by external / internal here?

@nimmoadam
Copy link
Author

Internal dependency = the one hosted inside the premises. External - for ex: Central Maven or the public repo.

@rarkins
Copy link
Collaborator

rarkins commented Jul 9, 2020

Renovate doesn't have the ability to know what's internal or external. In most cases your configuration of registryUrls or a .npmrc file to point to internal registries will mean the default registries are disabled. Meanwhile I'm working on a feature to let you disable hosts by domain name or host name manually: renovatebot/renovate#6715

@stale
Copy link

stale bot commented Jul 12, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed soon if no further activity occurs.

@stale stale bot closed this as completed Jul 18, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants