[Feature] Provide a way to pass in registry credentials to `yarn npm login`
- [x] I'd be willing to implement this feature
- [ ] This feature can already be implemented through a plugin
Describe the user story
I'm trying to configure Berry with authentication to JFrog, so that I can run yarn install in a GitHub Action workflow. Currently, to do that, I'm executing the following bash script:
#!/usr/bin/env bash
cat << EOF > ~/.yarnrc.yml
npmScopes:
myScope:
npmPublishRegistry: "https://myrepo.jfrog.io/myrepo/api/npm/npm"
npmRegistryServer: "https://myrepo.jfrog.io/myrepo/api/npm/npm"
EOF
{ echo $ARTIFACTORY_USERNAME; sleep 2; echo $ARTIFACTORY_API_KEY; } | yarn npm login --scope myScope
However, this script is not very reliable. From time to time, the login fails with an authentication error. Using sleep is very brittle, it seems.
Describe the solution you'd like
Providing a way of passing in the credentials would make the use of yarn in CI environments much easier. Something along the lines of:
yarn npm login \
--scope myScope \
--username $ARTIFACTORY_USERNAME \
--password $ARTIFACTORY_API_KEY
Describe the drawbacks of your solution
I cannot see any drawbacks to the proposed interface.
Describe alternatives you've considered
Alternatives could be:
- reading credentials from the environment,
- reading credentials from
~/.yarnrc.yml.
Additional context
Add any other context or screenshots about the feature request here.
Isn't https://yarnpkg.com/configuration/yarnrc#npmScopes.npmAuthIdent or https://yarnpkg.com/configuration/yarnrc#npmScopes.npmAuthToken good enough?
reading credentials from the environment,
As documented at the top here https://yarnpkg.com/configuration/yarnrc all (simple) configs can be env variables
Adding these to the setup script:
npmAuthIdent: "$ARTIFACTORY_USERNAME:$ARTIFACTORY_API_KEY"
# or
npmAuthToken: "$ARTIFACTORY_API_KEY"
produces:
➤ YN0041: │ @myScope/my-package@npm:1.0.8::__archiveUrl=https%3A%2F%2Fmyrepo.jfrog.io%2Fmyrepo%2Fapi%2Fnpm%2Fnpm%2F%40myScope%2Fmy-package%2F-%2F%40myScope%2Fmy-package-1.0.8.tgz: Invalid authentication (as an unknown user)
Did you place them under the scope? Also if you read the notice at the top here https://yarnpkg.com/configuration/yarnrc you can see that your syntax is incorrect
Try:
npmAuthToken: "${ARTIFACTORY_API_KEY}"
Yes. The script currently looks like this but it still results in the same invalid authentication issue:
cat << EOF > ~/.yarnrc.yml
npmScopes:
myScope:
npmAuthToken: "${ARTIFACTORY_API_KEY}"
npmPublishRegistry: "https://myrepo.jfrog.io/myrepo/api/npm/npm"
npmRegistryServer: "https://myrepo.jfrog.io/myrepo/api/npm/npm"
EOF
Could you try with npmAuthIdent: "${ARTIFACTORY_USERNAME}:${ARTIFACTORY_API_KEY}"?
It also fails.
@merceyz bump
Pretty sure this is a duplicate of https://github.com/yarnpkg/berry/issues/1039
For reference, the following works for GitHub Packages: https://github.com/Siteimprove/alfa/blob/c448d93e030b0f6b55433dec5bc667d874befd87/.github/workflows/release.yml#L15-L18
Can yarn v2 not read npmAuthIdent from an env var? Doesn't seem to work for me.
Ah, it's actually YARN_NPM_AUTHIDENT when translated to an environment variable.
It is sometimes sort of possible to script this by using a shell hack like (echo "$USER"; sleep 2; echo "$PASS") | yarn npm login (and yes, the sleep is significant, ignoring it may lead to your username being interpreted as user<NEWLINE>password and have the command waiting for a password).
While passing credentials as an env var seems fine and dandy for regular automation, and the shell hack works in most cases, there's one situation when neither is an option - I've been trying to write a Sherlock reproduction case for #4341, but it seems the stars are all misaligned when running under Sherlock and the shell hack just won't work (the command just hangs, seemingly ignoring stdin), and since the bug I'm trying to reproduce has to do with yarn npm login, passing the env var defeats the purpose.
- One option would be having
yarn npm loginrecognize if stdin is not a TTY and adapted to just do two readlines to get username/password. (Passing secrets via command line/env vars is generally considered bad, isn't it?) - Alternatively,
scripts/actions/sherlock-prepare.jscould include some kind of helper function to invoke (an equivalent of)yarn npm loginwith script-provided credentials so you could do something likeawait yarnNpmLogin(username, password)for repro
yes, passing secrets via arguments or env vars is bad. Honestly I think just accepting them from a pipe would be good, or being able to pass filenames --user-file --password-file, you might ask why to separate them, that's what the docker secrets spec would do.
The workaround no longer seems to work in Node 18.6. I'm getting the following error:
node: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.28' not found (required by node)
./script/setup-jfrog-authn: line 10: echo: write error: Broken pipe
Line 10 is
{ echo $ARTIFACTORY_USERNAME; sleep 2; echo $ARTIFACTORY_API_KEY; } | yarn npm login --scope myScope
UPDATE: nvm, the above was caused by a faulty installation of Node.