-
Notifications
You must be signed in to change notification settings - Fork 1.7k
System for making changes to package:macros without breaking the flutter engine roll #55870
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
Comments
Nit: not every change. Only changes to the APIs which are implemented by the analyzer, or breaking changes to APIs used by the analyzer. But yes, whenever a macros release requires a change in the analyzer, those packages have to be updated in lock step. The fact that one actually comes from the SDK means it has to happen as a part of the engine -> framework roll. |
How often do we have the situation where a change in the analyzer is required? |
One solution I proposed in the linked issue, is to allow version constraints for certain packages, instead of pinning them, in the framework. So for example |
It is difficult to predict, in the short term they will be more common, as we evolve the API. In the long term, we are looking into solutions to avoid the SDK vendored package entirely.
We could look into processes to ensure this, such as requiring an analyzer release to be prepared and landed together with any minor release of package:macros (analyzer depends on minor release versions because it implements the APIs, and that is the contract we have established). In theory we could also automate the publishing step, we have setups for that in GitHub repos already. I don't know what it would take to enable that for SDK packages. This hasn't been the pain point really though, it is the actual engine -> framework roll. There are already the required versions of things published and available. The issue is the framework pins to old versions which aren't compatible with the new SDK being rolled from the engine. |
I haven't really paid much attention to this in the past, but how do we ensure that the version of the analyzer that's pinned in flutter matches the version of the analyzer that's being used by the Dart SDK? Can we end up in a situation where |
I haven't seen the wiring in a while, but I'm 95% sure |
Then that begs the question of why there's a version of the analyzer package being rolled into flutter? What is it being used for? |
git grep shows the following:
The imports in (analysis.dart is separate; this is the code behind |
Thanks! I'm not seeing anything in that list that looks like it would cause problems for users if the two versions are out of date. The biggest risk I can see is if the pinned version of It still isn't clear why they aren't just depending on the version of the package in the SDK, but maybe because it would feel like a hack to add a dependency override? |
Flutter repo packages still do use pub so the solve will fail if version constraints are incompatible. So, assuming we version correctly this shouldn't be an issue.
If by "they" you mean the flutter/flutter repo, there is no version of |
We seem to have hit this issue again with the change https://dart-review.googlesource.com/c/sdk/+/370120 The engine to framework rolls have been failing for a day now, see flutter/flutter#150084 |
Does the More importantly, though, what process do we need to put in place to ensure that this doesn't happen again? |
Does the Dart SDK pin to an exact version of the analyzer package? Because if so, I think that is sufficient reason to simply unpin the analyzer in Flutter, as the whole reason for pinning in Flutter is to ensure everyone uses the same single version. |
The analyzer package is developed in the SDK ( Is there any way for Flutter to pin to the version in the vended in SDK? |
The only way I can imagine doing this is to use a |
This is a different kind of breakage, we did/do not need a new version of analyzer published. The issue was that the So, this recent blockage was not really the result of any process needing to be changed/improved, but instead the existing process (to publish package:macros after landing changes) was blocked on an unrelated issue so it couldn't be completed. |
Bug: #55870 Change-Id: Ic06f4c0a2cc5dc5f07f72335dd172f203b948cb1 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/371261 Reviewed-by: Brian Wilkerson <[email protected]> Commit-Queue: Konstantin Shcheglov <[email protected]>
dart-lang/language#3904 for discussion of whether we should switch back to internal-SDK-hosted for the macros dep until we are through with breaking changes. |
Hitting this again on the roll to Flutter: flutter/flutter#154731. |
A new analyzer version was published shortly after the macros package was landed into the SDK. |
The issue is that these changes break the autorollers, requiring the team to drop everything and do a manual roll as a P0. I think the overall approach here needs to be given some more thought so that we don't need to do these manual updates as a fire drill anymore. |
Which part of this is requiring a manual roll though? |
Oh, re-reading through the issue I see that the analyzer version is pinned, but you need different versions depending on which SDK you are on, so that pinning has to be updated as a part of the roll, which is presumably manual. |
Right. There are two separate rollers: one that updates packages, and one that updates the Dart SDK (via the engine roll). There is currently no team with bandwidth available to change how that behaves, for example by merging those two rollers into one that operates atomically. So when a Dart SDK roll requires package dependencies to be updated, the rolls fail, requiring manual work to do an atomic roll. |
Fwiw, another way to solve this would be with one giant mono repo instead of separate repos 🤷♂️. I don't have any other suggestions at this time other than not pinning analyzer in flutter/flutter. |
Another possibility is for the analyzer to do experiments with the experimental macros APIs on a branch, so that the version of the analyzer that is published on pub does not take on a dependency on macros. |
Or just not publish the macros package? I'm guessing that Edit; actually I guess that wouldn't work as long as Flutter has a dependency on macros, because the analyzer and CFE are constantly (?) changing. |
The macro support is built into the analysis server - which ships as a part of the SDK. So, this would mean all consumers having to build their own SDK to try it out, which isn't generally how we do experiments, and would essentially result in very few people using the experiment. Keeping that branch up to date would also be quite challenging. Using it in flutter would be incredibly challenging. |
If I understand correctly Jake couldn't we (Flutter) just not pin the macros package as it's effectively pinned to the rolled SDK anyway (hence this churn)? |
You need to not pin |
Allowing dependencies to roll forward without an explicit commit is not something that we can do, in general. There might be an exception for macros since it is an experiment that is tightly coupled with the Dart SDK, but not for analyzer. |
Why? What if we only allowed specific ranges - we could also fix this by having temporary range constraints like One alternative is to have a non-manual process for rolling a dependency as a part of the engine -> flutter roll but that sounds somewhat complicated. |
I also wonder whether we can have different rules for dev dependencies versus regular dependencies. These are afaik only dev dependencies. |
When dependencies are unpinned, the tree can turn red on an entirely unrelated commit because a new package version with some issue has been published to pub. This is not hypothetical, and it is difficult to determine that this is what has happened, and how to work around it. |
I agree this is not hypothetical, but it is rare (especially if you don't make things like deprecations turn the build red). Essentially all packages in the ecosystem operate using semver, other than flutter. There is a clear trade-off being made here, it has negative consequences for both upstream and downstream developers, for example:
|
@a-siva and I discussed this morning and I have one suggestion for a playbook for bumping the macros package, while it is still tied in 1-1 cadence with analyzer, and while all package versions are pinned in flutter/flutter: When a change is coming to the
(We have many alternative ideas, which all require bandwidth from the infra team. Sucha as: add fancy steps to the auto-roller; add fancy infra to the auto-roller to attach hotfixes to Dart SDK commits; stretch the version pinning to allow for precisely two minor version releases of analyzer (like |
That generally seems like a good plan. Step 1 is already something I have been doing. Step 2 seems like a good way to help make bumping the analyzer dependency less risky (fewer other packages getting bumped). And Step 3 would help lower the cost of investigating the failures. At least for now, that should minimize the pain compared to the current state. Longer term we do have plans to fix this, so that analyzer isn't locked to specific versions of package:_macros, but this is still O(months) from being complete. We may never need to do another change though before we have that in place. |
Closing as package:macros and package:json are discontinued |
See flutter/flutter#149093.
As I understand our system today: every change to the macros package requires a release. And every macros package release requires a specific, new companion analyzer package. And the analyzer package is pinned somewhere in flutter/flutter.
So any time the macros package, which is vendored with the Dart SDK, is changed, the flutter engine -> framework autoroll breaks. In order for it to not break, a new version of the analyzer package would need to be available on pub, and the flutter framework would need to be able to accept that new version.
CC @jakemac53 @scheglov @zanderso @a-siva
The text was updated successfully, but these errors were encountered: