-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(turborepo): Rationalize the install and execution process. #5695
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
8 Ignored Deployments
|
@nathanhammond is attempting to deploy a commit to the Vercel Team on Vercel. A member of the Team first needs to authorize it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewer's Guide!
// If we do not find the correct platform binary, should we attempt to install it? | ||
const SHOULD_INSTALL = true; | ||
|
||
// If we do not find the correct platform binary, should we trust calling an emulated variant? | ||
const SHOULD_ATTEMPT_EMULATED = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left these in as configuration variables; but we can actually hardcode the decisions here.
child_process.execSync( | ||
`npm install --loglevel=error --prefer-offline --no-audit --progress=false`, | ||
{ cwd: turboPath, stdio: "pipe", env } | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Previously this had to carefully track which package and version, clean up after itself, and more.
Now we just rely on npm
to do the right thing when looking at the package.json
for turbo
, clean up in the event of failure, etc.
// This provides logging messages as it progresses towards calculating the binary path. | ||
function getBinaryPath() { | ||
// First we see if the user has configured a particular binary path. | ||
const TURBO_BINARY_PATH = process.env.TURBO_BINARY_PATH; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We still need to allow the user to specify a particular binary path.
const correctBinary = availablePlatforms.includes(platform) && availableArchs.includes(resolvedArch) ? `turbo-${platform}-${resolvedArch}/bin/turbo${ext}` : null; | ||
if (correctBinary !== null) { | ||
try { | ||
return require.resolve(`${correctBinary}`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By rule we should be able to require.resolve()
the platform-specific package from within the turbo
directory, so we do that. (1:1 with the existing behavior.)
installUsingNPM(); | ||
const resolvedPath = require.resolve(`${correctBinary}`); | ||
console.warn('Installation has succeeded.'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't succeed unless we can resolve it, so this gets split across lines.
|
||
console.error(); | ||
console.error('To resolve this issue for your repository, run:'); | ||
console.error(`npm install turbo${version} --package-lock-only${environment} && npm install`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@chris-olszewski This is the magic command that fixes things without rm -rf
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😮
break; | ||
} catch (e) {} | ||
|
||
let next = path.join(current, '..', '..', 'package-lock.json'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No-dependencies find-up
.
@@ -9,15 +9,12 @@ | |||
"main": "./bin/turbo", | |||
"scripts": { | |||
"postversion": "node bump-version.js", | |||
"postinstall": "node install.js" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a couple of notes on errors / warnings, otherwise LGTM.
Are there any concerns about running this when the repo is using package managers besides npm?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is so much more straight forward!
I think we can get away with not building out this level of support for package-lock.json
version 1. The last version of npm that used this version by default was 6 and node 16 (EOL 9/11) was the last one to ship with npm 6.
|
||
console.error(); | ||
console.error('To resolve this issue for your repository, run:'); | ||
console.error(`npm install turbo${version} --package-lock-only${environment} && npm install`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😮
Ah, right, the package name should match, even if the architecture doesn't.
Ok, sgtm
…On Wed, Aug 9, 2023, 6:51 PM Nathan Hammond ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In packages/turbo/bin/turbo
<#5695 (comment)>:
> + if (SHOULD_INSTALL && correctBinary !== null) {
+ console.warn('Turborepo did not find the correct binary for your platform.');
+ console.warn('We will attempt to install it now.');
+
+ try {
+ installUsingNPM();
+ const resolvedPath = require.resolve(`${correctBinary}`);
+ console.warn('Installation has succeeded.');
+ return resolvedPath;
+ } catch (e) {
+ console.warn('Installation has failed.');
+ }
+ }
+
+ // 3. Both Windows and macOS ARM boxes can run x64 binaries. Attempt to run under emulation.
+ const alternateBinary = (arch === "arm64" && ['darwin', 'windows'].includes(platform)) ? `turbo-${platform}-64/bin/turbo${ext}` : null;
I believe this is still worth warning on. Even if you are running under
emulation you don't by default get the differently-named binary. So getting
the correctly-named binary is still important.
Phrased differently: if you run an install on windows arm, you should get
the windows arm binary. If you don't have the windows arm binary it is
indicative of an error in configuration (probably the npm issue) every time.
Also, to get this warning at all you have to fail the install saving throw
where we would drop the correct binary on your box.
I'm going to keep this as is.
—
Reply to this email directly, view it on GitHub
<#5695 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AADGD7ODNAKRC3T3WWA7HWTXUQ5DZANCNFSM6AAAAAA3JVMNAY>
.
You are receiving this because your review was requested.Message ID:
***@***.***>
|
Nope! There are two things happening here that do
Writing to this destination (no matter how it is implemented underneath the hood with linking) results in safe behavior—even if it pollutes the cache, even if that cache is later restored from a random cache, even if that cache comes from a different platform, even if the base project is a different package manager. It works because it leverages The material difference is that, in a misconfigured repository, if we restore from a polluted cache, on the same platform (worst-case scenario), the correct binary will be found inside the
This does not directly invoke or mutate |
Previously we had a lot of complexity in our install scripts inherited from
esbuild
. This change removes all of the incidental complexity in favor of relying upon default ecosystem behaviors in most cases.Instead of attempting correction of configuration at both installation and invocation, it handles everything at invocation. Early returns ensure that we perform the exact same amount of work as we did in the previous variation.
It can now also detect and provide instructions on how to repair a broken
package-lock.json
caused by npm/cli#4828. (Note: if the "just try installing" saving throw works, we won't provide this information to the user. I elected this ordering for startup time reasons.)As an added bonus,
turbo
no longer has apostinstall
script which is more end-user-friendly.Material changes:
preferUnplugged
support. This works with all stable releases ofyarn
(berry). This is a change for users on canary versions >2.0.0-rc.0 && <=2.0.0-rc.30 from September 2019 – March 2020—but we already don't support in other portions of our codebase so this only changes where the error is thrown from.npm install
download failure it does not attempt to directly download a tarball. If a user misconfigured their setup and we didn't succeed atnpm install
to bail them out? It's okay for you to get an error with lots of details on how to fix your configuration.