-
Notifications
You must be signed in to change notification settings - Fork 4.6k
Speed up npm ci by caching node_modules
#45932
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
Merged
Merged
Changes from 1 commit
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
f4ec7b3
Try custom setup-node composite action for aggressive caching
kevin940726 239050c
Add comment about GHA bug
kevin940726 2eff8c8
Try without rebuild and ignore-scripts
kevin940726 38bca97
Include npm version to the cache key
kevin940726 4014266
Try reverting the change of graceful-fs
kevin940726 65efe55
Update step name
kevin940726 1c9ca27
Code review
kevin940726 e437750
Add some comments
kevin940726 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Add comment about GHA bug
- Loading branch information
commit 239050c676e5de4925b7fe00f01219596946f409
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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 normally not needed because most of the packages don't have
postinstallscripts. However, somereact-nativerelated packages do need them so we make this an opt-in.This is not future-proof as we might include a package that needs
postinstallin the future. We can runnpx can-i-ignore-scriptsto manually inspect these cases.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.
can we not run
npm ciabove instead ofnpm ci --ignore-scripts?also I wonder how much of the impact on performance is related to
--ignore-scripts- I might measure it and find out.this seems more of a danger on this change: is there a way we can make it more obvious to someone when their PRs are failing multiple test suites that the reason is that they need to supply
should-rebuild: true?I'm not sure how I would expect someone to start from the failure and work back up to this setting.
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.
Yeah, as I said above, it's not entirely "safe", but I think it's good enough for most cases. We will invalidate the cache whenever OS/Node/
package-lock.jsonchanges so it's more or less like what we have during local development.Probably not much, because
npm ciis only run when there isn't a cache hit. Most runs in our measurements have cache hit.However,
npm rebuilddoes contribute to some running time. We use it here to trigger any underlyingpostinstallscript in the dependencies that gets ignored by-ignore-scripts. Tested withcan-i-ignore-scripts, most dependencies that have thepostinstallscripts arereact-native-related (and local development related), hence I think it makes sense to make it an opt-in when we're building for react-native.We can try to just use
npm ciwithout the--ignore-scriptsand always runnpm rebuildthough. I think that's unnecessary in most cases and probably will add up 20 to 30 seconds of runtime but it's technically "safer". Cachingnode_moduleswon't behave exactly like runningnpm cievery time and I think that's okay.I'd expect it to be pretty visible as it would probably fail the CI and we can look into that. I think it'll only happen when there's a new dependency with
postinstallget added though, which should be pretty uncommon.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.
where did you measure this? and what was the ratio for
pull_requestevents in PRs?it's usually faster to do the wrong thing 😉
I'm really nervous about introducing a very subtle behavior that could break things if you don't already happen to know it exists and remember that you need to apply a workaround when it's appropriate.
I agree here, but how is it that you would propose someone moves from "my PR failed and I don't know why" to finding this flag?
Uh oh!
There was an error while loading. Please reload this page.
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.
Not that I have investigated why yet, but if I did the test right it doesn't seem to make much difference beyond a couple seconds. There is not enough of an effect with the data collected so far to conclude that there is any measurable impact. I could have done something wrong, or the flag might not be having the impact we expect it to.
Granted, for the unit tests and end-to-end tests there's still that issue of having the multi-modal distribution which could be throwing off the statistics. I haven't investigated the impact that has on the results.
My test branch is #46318
Unit Tests workflow
Performance tests workflow
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 directly looked into the details of each run and see if there's a cache hit. I only looked into this PR's runs as this is where we're measuring.
It depends on what you think is "wrong". I'm just saying that upon my research this is the trade-off that I'm willing to take. It's obviously subjective and it's totally "right" to think otherwise.
I think we should be able to find this out in a code review. Just like how people work in different OSes than in CI, things are gonna be different and weird things happen in CI. We can also write some guide or log about this if necessary. I agree we should minimize the breaking changes whenever possible but I believe this is something that rarely breaks. However, if the added time of removing
--ignore-scriptsis so little that it doesn't matter then I'll immediately stand on the other side of the fence 😝 .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 removed
--ignore-scriptsandnpm rebuildin 1949d5f. Seems like it's still working nicely!I updated the postinstall step to also run the
postinstallscripts in the packages folder too. This technically doesn't match the behavior ofnpm cientirely though as it only runs in thepackagesfolder but not recursively for all dependencies.If the
postinstallscripts only update thenode_modulesfolder (which is what most dependencies are doing) then it should be safely cached. However, inreact-native-editor, thei18n-cachefiles are generated both innode_modulesand in thepackages/folder because of linking. During the tests, thei18n-cachefiles are read from thepackagesfolder for some reason, hence we need to re-run thepostinstallscript to populate it again. I think this can be seen as an edge case, and possibly there are other ways to solve it too (for example reading fromnode_modulesas a fallback).