registry-url ignored completely
Description: The registry-url set in the config is ignored and npm is used unconditionally
Action version: v4
Platform:
- [ ] Ubuntu
- [x] macOS
- [ ] Windows
Runner type:
- [x] Hosted
- [ ] Self-hosted
Tools version:
node version = v21.5.0
npm version = 10.2.4
see npm config list output in linked job for more
Repro steps:
https://github.com/getargv/getargv.js/blob/main/.github/workflows/npm.yml
Expected behavior: The package is pushed to GPR.
Actual behavior: https://github.com/getargv/getargv.js/actions/runs/7272407299/job/19814479275
Hello @CamJN Thank you for creating this issue, we will investigate it and come back to you as soon as we have some feedback.
Hello @CamJN, Thank you for creating the issue once again.
I've tried to reproduce the issue with respect to setup-node package, but it is working as expected. I am suspecting the below can be the root cause for the issue.
- Kindly confirm if .npmrc file is available in the root of your project.
- Please make sure github_token in the workflow file has valid permission with respect to repository and also please confirm, in case if you use token different from secrets.GITHUB_TOKEN.
- By default the package scope is set to the account that contains that workflow file. You have to use "scope" keyword to input if referring to other repositories. Please refer this Publish doc URL
Please feel free to share if any further clarifications needed.
Thanks!!
Thanks for getting back to me, sorry my issue isn't reproducing for you, I know that's annoying.
- I have no
.npmrcfile in my project at all, is one needed, is that documented anywhere? - The
github.tokenis granted the write packages scope permission right in the workflow, as you can see here. - I am trying to publish the package to the account that owns the workflow file, so the default scope is acceptable.
As you can see from the logs I linked to in my report, npm tries to publish to https://registry.npmjs.org/ when I set the registry-url to https://npm.pkg.github.com/, so checking permissions isn't likely to help, as it's not trying to publish to github packages at all.
Hello @CamJN, Thank you for an update!!
Thank you once again for letting us know, that .npmrc file is not available at project level.
Could you please try to run the npm.yml workflow by adding below code snippets at publish-gpr step before npm publish step in npm.yml file.
- run: |
echo registry=https://npm.pkg.github.com/ > .npmrc
echo always-auth=true >> .npmrc
echo _authToken=${{ secrets.GH_PAT }} >> .npmrc
Kindly refer the URL to refer the details about .npmrc file
Per that same page you linked to: https://github.com/actions/setup-node/blob/main/docs/advanced-usage.md#publish-to-npmjs-and-gpr-with-npm it should not be necessary to create an npmrc file, just run this action then publish. In fact the section on yarn2 (which I do not use but am simply quoting from) says that the setup-node action creates an npmrc file, but that doesn't seem to happen, I tried to cat the file and it doesn't seem to exist, perhaps I looked at the wrong path.
In my testing the auth line needs to be: echo //npm.pkg.github.com/:_authToken=${{ github.token }} >> .npmrc, the line you quoted gets this error:
npm ERR! code ERR_INVALID_AUTH
npm ERR! Invalid auth configuration found: `_authToken` must be renamed to `//npm.pkg.github.com/:_authToken` in project config
npm ERR! Please run `npm config fix` to repair your configuration.`
npm ERR! A complete log of this run can be found in: /Users/runner/.npm/_logs/2024-01-08T14_09_00_619Z-debug-0.log
Error: Process completed with exit code 1.
Hello @CamJN, Thank you for an update!!
I believe the below code snippet is causing an issue.
echo //npm.pkg.github.com/:_authToken=${{ github.token }} >> .npmrc
Try to add below code snippet instead of above.
echo _authToken=${{ secrets.GH_PAT }} >> .npmrc
Kindly try to rerun the workflow after making above change. Also, make sure the github.token is available and has the appropriate permissions needed for publishing to GitHub Packages.
I am sorry I wasn't clear.
echo _authToken=${{ secrets.GH_PAT }} >> .npmrc causes the issue, and echo //npm.pkg.github.com/:_authToken=${{ github.token }} >> .npmrc fixes it. So you may want to update the action to check the npm version and use the correct format when generating the .npmrc file.
Further, I have the workflow working at this point, though this action does seem to be broken, since I have to setup auth to the repo manually when this action is supposed to do so.
I've looked at the action's code and it prefers to put the .npmrc file in process.env['RUNNER_TEMP'] and then sets NPM_CONFIG_USERCONFIG to point npm at the file. However according to this issue, that env var will not be respected by npm when running the npm publish (or any other) script.
Hello @CamJN, Thank you for the information and confirmation that the workflow is working from your end.
Apologies for the delay in the response to provide the information about the current implementation of the setup-node.
The current implementation of setup-node is .npmrc file is created in the runner and set the the file location to NPM_CONFIG_USERCONFIG and should make sure that NPM token is properly configured (for automation primarily) and that it has been added as a repository secret in the repo's settings. please find the below code snippet that explains the functionality.
export function configAuthentication(registryUrl: string, alwaysAuth: string) { const npmrc: string = path.resolve( process.env['RUNNER_TEMP'] || process.cwd(), '.npmrc' ); if (!registryUrl.endsWith('/')) { registryUrl += '/'; }
writeRegistryToFile(registryUrl, npmrc, alwaysAuth); }
onst authString: string = registryUrl.replace(/(^\w+:|^)/, '') + ':_authToken=${NODE_AUTH_TOKEN}'; const registryString = ${scope}registry=${registryUrl}; const alwaysAuthString = always-auth=${alwaysAuth}; newContents += ${authString}${os.EOL}${registryString}${os.EOL}${alwaysAuthString}; fs.writeFileSync(fileLocation, newContents); core.exportVariable('NPM_CONFIG_USERCONFIG', fileLocation); // Export empty node_auth_token if didn't exist so npm doesn't complain about not being able to find it core.exportVariable( 'NODE_AUTH_TOKEN', process.env.NODE_AUTH_TOKEN || 'XXXXX-XXXXX-XXXXX-XXXXX' );
The below command will fix the issue as a workaround. run: | echo '//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}' > ${{ github.workspace }}/.npmrc cat .npmrc
If you're experiencing any further issues related to this one or any other (or if the information current implementation solve this one for you), please feel free to reach out to reopen the issue.
Once again, I apologize for the late response and thank you very much for your cooperation and updates :)
This quote:
and should make sure that NPM token is properly configured (for automation primarily) and that it has been added as a repository secret in the repo's settings.
is contradicted by this one:
The below command will fix the issue as a workaround
The action documents that it will setup auth for you, it does not. Thus there is a bug in the action. The bug is that it relies on the NPM_CONFIG_USERCONFIG env var to tell npm where the config file is, but npm ignores that env var when running scripts, including scripts documented as working with this action such as npm publish. So the action needs to be fixed. You can read more about why npm ignores this env var here. My suggestions are two-fold: 1) when the action runs check the npm version and generate an appropriately formatted auth string for the version of npm that is present (or use the node version that setup-node installed to guess, but checking would be more reliable); 2) save the npmrc file to either ~/.npmrc or ${{ github.workspace }}/.npmrc from in the action, so that it behaves as documented OR set the lowercase npm_config_userconfig env var which is respected by npm when running npm publish.
Hello @CamJN, Apologies for the delayed response. As mentioned in the docs example with a comment like # Setup .npmrc file to publish to GitHub Packages aligns with the current functionality of setup-node as it provides users with a correct and secure way to configure their workflows for publishing Node.js packages. Please find the setup instructions below to configure .npmrc file
- name: Configure .npmrc run: | echo ""@test-publish:registry=https://npm.pkg.github.com"" > ~/.npmrc echo ""//npm.pkg.github.com/:_authToken=${{ secrets.GIT_TOKEN }}"" >> ~/.npmrc
We have tried the same and able to publish the packages successfully.
The actions/setup-node action includes functionality to check the npm version and generate an appropriate authentication string. The below is the detailed explanation of the process: .npmrc File Creation: When the registry-url input is provided and NODE_AUTH_TOKEN is set, the action creates an .npmrc file in the project root. This file configures the npm scope and registry URL properly, ensuring secure and authenticated npm operations. Importance of .npmrc in Setup: Registry Configuration: The .npmrc file specifies the npm registry to use, such as GitHub Packages (registry=https://npm.pkg.github.com). Authentication: It includes authentication tokens (e.g., //npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}) to authenticate npm commands like npm publish.
Additionally, as per the npm/cli documentation, npm will consider the NPM_CONFIG_USERCONFIG environment variable for a custom user configuration file. The issue mentioned in your previous comment originates from npm/npm, which was archived on August 11, 2022, because the npm CLI codebase was moved to the npm/cli repository. Please feel to reach us in case of any further concerns / clarifications needed :)
The actions/setup-node action includes functionality to check the npm version and generate an appropriate authentication string.
No, it doesn't; here's the code: https://github.com/actions/setup-node/blob/main/src/authutil.ts#L47-L48 the same string is generated regardless of npm version. However it seems that it works now as expected: https://github.com/getargv/getargv.js/actions/runs/10323155075/job/28579915789 and since that code hasn't changed in 5 years, I'm going to assume that npm fixing its environment-variable-case problem was what fixed it.