I have a project level .npmrc
with private npm registry url
registry=https://blabla.pkgs.visualstudio.com/_packaging/BlaBla/npm/registry/
always-auth=true
and my Azure pipeline has this stage for npm install
using their built in task
- task: Npm@1
displayName: "NPM Install"
inputs:
command: custom
workingDir: ./project/ #this is the project folder, has package.json, npmrc files
customCommand: install
verbose: true
Now this works fine and packages are installed. I think the authentication token is stored in some global .npmrc file
Due to compliance issues I cannot store the URL hardcoded in the .npmrc
since it is committed and scanned and complained by code analysis tools.
I tried to somehow set it like an environment variable
Approach 1
I edited my project level npmrc
registry=$REGISTRY
always-auth=true
and wrote a bash stage before the install
- bash: |
export NPM_CONFIG_REGISTRY=https://blabla.pkgs.visualstudio.com/_packaging/BlaBla/npm/registry/
echo $NPM_CONFIG_REGISTRY #hardcoded in pipeline for testing
displayName: "Set NPM Registry"
workingDir: $(Build.SourcesDirectory)/project/
This didn't work in the pipeline and gave npm ERR! code ERR_INVALID_URL
. When I tried this locally also it seems that it adds the registry URL globally because when I tested with npm config get registry
it printed the URL I just set both in the project folder level (has project level npmrc) and outside the project folder.
I also tested while the url was hardcoded and npm config get registry
printed the correct URL in the project folder and outside it printed https://registry.npmjs.org/
. But locally the npm install
worked but probably for the wrong reasons since it also gave this
npm WARN invalid config registry="$REGISTRY" set in C:\BlaBla\project\.npmrc
npm WARN invalid config Must be full url with "http://"
So in conclusion I think the project level registry URL was never set even locally but I don't know why the Azure pipeline didn't even come this close. My guess is the NPM task runs in a different terminal/session so it doesn't have an idea of the env variable I just set
Approach 2
Instead of setting an env I edited my install custom command
customCommand: install --registry https://blabla.pkgs.visualstudio.com/_packaging/BlaBla/npm/registry/
now also the I got the same npm WARN
but instead of the invalid URL errors this time I got
npm ERR! code E401
npm ERR! Unable to authenticate, your authentication token seems to be invalid.
What can I try next to resolve this?
Resources used: https://stackoverflow.com/a/55441931/13583510
How to set the registry URL in a project-level .npmrc file from an environment variable in an Azure Pipeline
Your guess is correct. When you use export command in bash to set the environment variable, it can only work on current session. And NPM task is working on different session. So it can not read the correct environemnt.
To meet your requirement, you can directly define the Pipeline Variable with the feed url and set the format: ${REGISTRY}
to use environment variable in npmrc file.
Here is an example:
.npmrc file:
registry=${REGISTRY}
always-auth=true
Pipeline Sample:
variables:
REGISTRY: 'https://blabla.pkgs.visualstudio.com/_packaging/BlaBla/npm/registry'
steps:
.... Other steps
- task: Npm@1
displayName: "NPM Install"
inputs:
command: custom
workingDir: ./project/ #this is the project folder, has package.json, npmrc files
customCommand: install
verbose: true
Result: We can see valid NPM registry url in NPM task.
On the other hand, I would like to share another easier method to use private feed. If your pipeline and feed are in the same organization, you can directly set the customRegistry
and customFeed
in NPM task.
For example:
- task: Npm@1
displayName: "NPM Install"
inputs:
command: 'custom'
workingDir: './project/'
customCommand: 'install'
customRegistry: 'useFeed'
customFeed: 'Your Feed Name'
In this case, you don't need to set any additional configurations in project .npmrc file.
Update:
When we use Pipeline Environment variable in NPM task to replace the registry value in .npmrc file, it may not automatically set the credentials for the registry and cause 401 error.
If you run into this issue, you can consider using sed command to replace the registry url before the npm task.
Here is an example:
.npmrc file:
registry=InputREGISTRY
always-auth=true
Pipeline sample:
variables:
REGISTRY: https://blabla.pkgs.visualstudio.com/_packaging/BlaBla/npm/registry/
steps:
- bash: sed -i 's,registry=InputREGISTRY,registry=$(REGISTRY),g' $(Build.SourcesDirectory)/project/.npmrc
- task: Npm@1
displayName: "NPM Install"
inputs:
command: custom
workingDir: ./project/
customCommand: install
verbose: true