Our app requires a private package to build which we publish to NPM. (With expo-cli this wasn’t an issue because the packages were resolved locally and each dev has their local machine configured with access.)
Configure your project in a way that relies on the NPM_TOKEN env variable to authenticate with private repositories.
Add NPM_TOKEN to your account or project’s secrets. See the secret environment variables docs to learn how to do this.
I’ve added the NPM_TOKEN as a secret on our project.
I’ve done what works for our GitLab CI machines, which is using yarn config set, running in the pre-install hook, but adding this to package.json under the scripts section:
"eas-build-pre-install": "yarn config set '//registry.yarnpkg.com/:_authToken' $NPM_TOKEN
I know the secret is being resolved correctly because under “Pre-install hook” when the build runs, I see
$ yarn config set '//registry.yarnpkg.com/:_authToken' $NPM_TOKEN
success Set "//registry.yarnpkg.com/:_authToken" to "<correct token here>".
I’ve also tried:
Echoing the right string to .yarnrc
Using npm config set instead of yarn config set
Trying the --use-yarnrc flag on yarn config
But no matter what I try, when the “Install dependencies” step of the build runs, it gives me
[stderr] error An unexpected error occurred: "https://registry.yarnpkg.com/@growers/<our package>/-/<package-version>.tgz: Request failed \"404 Not Found\"".
The URL it’s using is the URL specified in yarn.lock. I don’t understand why it’s not working.
Has anyone gotten EAS Build working to fetch a private package from NPM?
The URL it’s using is the URL specified in yarn.lock. I don’t understand why it’s not working.
i’m not personally familiar with using private npm packages with yarn, is this unexpected behavior for you? this is what yarn v1 does and it doesn’t provide a way to override it. because of this, we have some instructions for how to use our npm cache with yarn v1 that you may find useful if the url in the yarn lockfile is the issue
Yes, it is unexpected. This configuration works on our dev machines and our Gitlab CI builders. Why should it not work on EAS machines?
So we have to rewrite our yarn.lock file because your builders can’t proxy the request out to the package repository? I understand bandwidth costs money, but we’re on the paid plan. Let us pay what it takes to just fetch the package, as specified, from the repo.
that is not what i am saying at all. i am saying that if you want yarn to use the proxy, you have to set this up manually because of how yarn v1 will just use the url in the lockfile and that can’t be overridden. so the solution to make it use the proxy, if you want it to, is to substitute the url in the lockfile. my suggestion, without knowing much about this specific problem, is that perhaps if the url used for fetching your package is unexpected that this may be a related problem.
it is not clear to me why this is not working in the context of our builders when the same thing would work on your local machine. are you possibly using a different version of yarn?
my suggestion, without knowing much about this specific problem, is that perhaps if the url used for fetching your package is unexpected that this may be a related problem.
I added a step to the pre-install hook to try doing a curl -I on the URL to make sure it is accessible from the build machine, and it is. Which makes it seem like for whatever reason the yarn config set value set in the pre-install step is being ignored. Link to build: Build Details — 67e69bd5-836c-45a0-96ac-92ffe7ad52d8 — growers-rally — Expo
so maybe you are using yarn v2 locally and on gitlab
Yarn v1 all around. According to the second line of the “Install Dependencies” step, it’s using the same yarn version I’m using locally: 1.22.10. I added it to eas.json and ran again, same result.
you could try also doing yarn config set always-auth true
i have seen this mentioned in issues on the yarn repository where developers have encountered the same problem as you
i tried setting this up myself and i found out that in my experience the read-only token type suggested by npm actually didn’t work for reading private packages.
i tested this by creating .npmrc within my project directory, setting NPM_TOKEN, and then signing out of npm. i then deleted node_modules and ran yarn. got a 404 error. swapped the NPM_TOKEN with an “automation” token and it worked. you could possibly try the same thing on your end.
add NPM_TOKEN secret created with “automation” privileges (read-only did not work for me)
create .npmrc in your project directory (or do it in the pre-install script) and set the npm registry (see this commit)
i think we should improve our documentation on this, i’ll take care of that. i do wonder if maybe npm has introduced a regression recently around read-only tokens and private packages, however.
Not that it really matters now, but just to clarify : @growersbenb said “The URL it’s using is the URL specified in yarn.lock.” and @notbrent was asking whether that was unexpected. Given the rest of the conversation I do not think it was unexpected.
I have validated that the token I’m supplying to the EAS Build allows access to this package, both on my local machine and in the pre-install hook via curl -I. The token is valid.
Is it possible that the start of the install step is overwriting .yarnrc, or that the .yarnrc.ymldescribed here conflicts with my .yarnrc settings and the two are not being merged? Is there a way for yarn config list to be run at the beginning of the install step so we can inspect what the settings are just before yarn install runs?
Edit: just tested this config locally. On my machine, running yarn 1.22.10, if there is both ~/.yarnrc and ~/.yarnrc.yml, the .yml file is ignored and only ~/.yarnrc appears to be being read.