| # Flutter postmortem: AndroidX Plugin Migration | |
| Status: draft | |
| Owners: @mklim, @amirh, @dnfield, @hixie | |
| ## Summary | |
| Description: The flutter/plugins repo was updated with a breaking change to | |
| resolve | |
| [flutter/flutter#23995](https://github.com/flutter/flutter/issues/23995). The | |
| change migrated and deprecated Android dependencies in the plugins' | |
| `build.gradle` files and required any apps using the plugins to also have Gradle | |
| files that were either migrated or compatible with the AndroidX. Gradle errors | |
| in hard-to-debug ways on Flutter apps broken by the change, without surfacing a | |
| clear explanation or migration path to affected users. In addition this was a | |
| known breaking change but originally incorrectly incremented the minor semantic | |
| version number in 6/32 of the affected packages. | |
| Component: `flutter/plugins` | |
| Date/time: 2019-01-24 13:24 -0800 | |
| Duration: 4 days for the semantic versioning problem. 2 weeks for the confusing | |
| Gradle error. | |
| User impact: Users pinned to the major version of firebase_analytics, | |
| firebase_database, firebase_messaging, firebase_storage, google_sign_in, and | |
| url_launcher were broken by pub despite deliberately trying to avoid any | |
| breaking changes. All other first party plugin users that try to use the latest | |
| major version are affected by the confusing Gradle error. | |
| ## Timeline (all times in PST/PDT) | |
| ### 2019-01-24 | |
| * 13:24 - First breaking change with incorrect versioning merged, | |
| [flutter/plugins#1103](https://github.com/flutter/plugins/pull/1103). | |
| * 14:20 - [flutter/plugins#1103](https://github.com/flutter/plugins/pull/1103) | |
| uploaded to pub. **<START OF OUTAGE>** | |
| ### 2019-01-25 | |
| * 09:44 - [flutter/plugins#1115](https://github.com/flutter/plugins/pull/1115), | |
| the final commit with breaking changes and incorrect semver, is merged to | |
| master. | |
| * 10:55 - Final batch of incorrectly versioned plugins is published to pub. | |
| * 13:53 - @hixie files | |
| [flutter/flutter#27106](https://github.com/flutter/flutter/issues/27106) for | |
| the obscure Gradle error following a fresh run of `flutter create` on the | |
| `stable` channel. Links the error to the AndroidX migration and tags @mklim, | |
| @amirh, and @dnfield. | |
| * 14:03 - @mklim confirms the root cause of the error as an incompatibility | |
| between the app and plugin's Gradle files. *(The semantic versioning issue is | |
| not known at this point.)* | |
| * 14:45 - @dnfield, @mklim, and @amirh discuss mitigating the user unfriendly | |
| `flutter create` error on `stable` offline. Decide to republish the AndroidX | |
| migration with a constraint so that users are on a version of flutter that | |
| produces AndroidX-compatible Gradle files. [pub](http://pub.dartlang.org) | |
| maintainers are contacted to remove the broken packages. | |
| ### 2019-01-26 | |
| * 00:30 - Email back and forth begins with pub maintainers. | |
| * 08:07 - | |
| [flutter/flutter#27128](https://github.com/flutter/flutter/issues/27128) filed | |
| about upgrading a >= 1.0.0 plugin's minor version number. | |
| * 12:33 - @mklim briefly explains the problem in | |
| [flutter/flutter#27128](https://github.com/flutter/flutter/issues/27128) and | |
| recommends to downgrade plugin versions since a revert for `flutter stable` is | |
| incoming. However his comment doesn't have details on all of the plugins to | |
| downgrade and what versions to downgrade them to. User discussion continues on | |
| this bug over the next 48 hours. | |
| * 14:00 - Discussion with pub maintainers concludes. The affected packages can't | |
| be replaced because pub has safeguards against removing a "stable" package | |
| version. Decided to replace the packages with a patch+1 revert, and then a | |
| patch+2 migration with the minimum Flutter SDK constraint. | |
| ### 2019-01-28 | |
| * 09:00 - *Semantic versioning issue discovered.* Offline discussion scheduled | |
| with @mklim, @amirh, @kevmoo, @hixie, and @dnfield to re-assess a fix. | |
| * 11:00 - @mklim, @amirh, @kevmoo, @hixie, and @dnfield re-review the issue with | |
| the semantic versioning issue also in mind. Decide that the minimum Flutter | |
| constraint is useless to address the problem since it really has to do with | |
| the app's `build.gradle`, which could have been generated by any Flutter | |
| version including the current one and which also could have been manually | |
| edited. Decide that the semver problem should be fixed by patching the 6 | |
| affected plugins with a revert and then incrementing them with a major bump | |
| and the migration. | |
| * 11:45 - @mklim updates | |
| [flutter/flutter#27128](https://github.com/flutter/flutter/issues/27128) with | |
| a detailed description of the bug, root cause, way to fix via migration or | |
| downgrade, and plan to fix the semantic versioning for the affected plugins. | |
| * 14:28 - [flutter/plugins#1127](https://github.com/flutter/plugins/pull/1127) | |
| (the patch revert) is merged to master. | |
| * 15:05 - [flutter/plugins#1128](https://github.com/flutter/plugins/pull/1128) | |
| (the correct forward roll) is merged to master. | |
| * 15:08 - @dnfield alerts users following the AndroidX migration | |
| ([flutter/flutter#23995](https://github.com/flutter/flutter/issues/23995)) of | |
| the semantic version issues and that there's going to be a major version bump. | |
| * 15:46 - The last affected package is updated on pub with both the patch revert | |
| and the forward roll with correct semver bump. **<END OF SEMVER | |
| OUTAGE>** | |
| * 15:58 - @mklim updates | |
| [flutter/flutter#27128](https://github.com/flutter/flutter/issues/27128) and | |
| [flutter/flutter#23995](https://github.com/flutter/flutter/issues/23995) with | |
| info on the 6 packages that have had their semantic versions updated. | |
| * 17:09 - @mklim updates | |
| [flutter/flutter#27106](https://github.com/flutter/flutter/issues/27106) with | |
| more details on the bug and the fixed semantic versioning problem. | |
| ### 2019-01-30 | |
| * 10:27 - @mklim updates the Flutter website via | |
| [flutter/website#2310](https://github.com/flutter/website/pull/2310) to | |
| explain how to import a Flutter app into the Android Studio IDE for automatic | |
| migration. | |
| * 11:28 - @mklim opens | |
| [flutter/plugins#1138](https://github.com/flutter/plugins/pull/1138) so that | |
| the plugins warn about the AndroidX migration when Gradle fails to compile. | |
| ### 2019-02-05 | |
| * 13:41- @mklim opens | |
| [flutter/flutter#27566](https://github.com/flutter/flutter/pull/27566) to | |
| detect gradle error messages and link to a Flutter AndroidX migration guide on | |
| the Flutter website in Flutter itself. | |
| * 17:35 - @mklim opens | |
| [flutter/website#2349](https://github.com/flutter/website/pull/2349) to add a | |
| migration guide to AndroidX for Flutter apps and plugins. | |
| ### 2019-02-07 | |
| * 13:23 - [flutter/website#2349](https://github.com/flutter/website/pull/2349) | |
| is merged. | |
| * 17:30 - [flutter/plugins#1138](https://github.com/flutter/plugins/pull/1138) | |
| and [flutter/flutter#27566](https://github.com/flutter/flutter/pull/27566) are | |
| merged. Plugins are uploaded with the change. **<END OF GRADLE ERROR | |
| OUTAGE>** | |
| ## Impact | |
| ### Some first party plugin users were broken in a minor version upgrade | |
| It looks like the only issue filed for this directly has been | |
| [flutter/flutter#27128](https://github.com/flutter/flutter/issues/27128). | |
| ### All first party plugin users were broken in a confusing way | |
| An explanation and migration path exists in the CHANGELOG.md of each plugin, but | |
| this information is hard to find and the actual Gradle error is not helpful. | |
| Several bugs on GitHub have been filed from affected users. | |
| * [flutter/flutter#27106](https://github.com/flutter/flutter/issues/27106) | |
| * [flutter/flutter#27226](https://github.com/flutter/flutter/issues/27226) | |
| * [flutter/flutter#27146](https://github.com/flutter/flutter/issues/27146) | |
| * [flutter/flutter#27156](https://github.com/flutter/flutter/issues/27156) | |
| ## Root causes | |
| [flutter/plugins#1103](https://github.com/flutter/plugins/pull/1103), | |
| [flutter/plugins#1115](https://github.com/flutter/plugins/pull/1115) migrated | |
| the plugins to support AndroidX instead of the original Android support | |
| libraries. See #23995 for more details, but in short the original support | |
| libraries are deprecated and not recommended for Android app development | |
| anymore. | |
| This was a known breaking change and the changelog links to the official | |
| [migration steps](https://developer.android.com/jetpack/androidx/migrate). BUT | |
| plugins that were greater than or equal to `1.0.0` weren't updated according to | |
| [pubspec's semantic versioning | |
| philosophy](https://www.dartlang.org/tools/pub/versioning#semantic-versions). On | |
| pub for packages < `1.0.0` the versioning is `0.major.minor+patch`, and for >= | |
| 1.0.0 it's `major.minor.patch`. The AndroidX PRs universally incremented the | |
| middle number, so any plugin that was already at or above `1.0.0` is being | |
| incorrectly treated as non-breaking by pub. This caused the semantic versioning | |
| issue. | |
| In addition the breaking change was only surfaced in the CHANGELOG.md of each | |
| plugin, but resulted in breaking Gradle errors at runtime. These Gradle errors | |
| did not provide any obvious ways to debug the incompatibility. | |
| ## Lessons learned | |
| ### What worked | |
| * The plugins were migrated to AndroidX! | |
| ### Where we got lucky | |
| * @hixie diagnosed the problem with standard `flutter create` templates | |
| relatively quickly and cc'ed the relevant devs. | |
| ### What didn't work | |
| * We understood that the AndroidX migration was breaking, but underestimated the | |
| scale of the breakage. We didn't realize that it applied to all untouched | |
| `build.gradle` files produced by released versions of `flutter create`. Also | |
| failed to verify that the Gradle errors mentioned AndroidX or were otherwise | |
| easily understandable. | |
| * The `flutter/plugins` CI failed to verify that the new plugins could be used | |
| with the template from `flutter create` on stable. | |
| * No manual sanity checks were recommended and insufficient ones were performed | |
| before publishing the packages to pub. There could have been manual checks to | |
| catch the `flutter create` and semantic versioning issues. | |
| * The packages were pushed Thursday/Friday (24-25) and remained broken over the | |
| weekend until a fix was decided communally when everyone was in the office | |
| Monday morning (28). | |
| * The breaking change and suggested migration were only surfaced in the | |
| CHANGELOG of the plugins, not in the actual Gradle compile error. The | |
| changelogs are not very findable and the Gradle error is confusing. | |
| * There was no way to mark the incorrect semver packages as broken in pub, so we | |
| needed to push a breaking revert along with a forward migration. | |
| ## Action items | |
| ### Prevention | |
| * [flutter/flutter#27110](https://github.com/flutter/flutter/issues/27110) - | |
| Test the plugins from a blank, stable `flutter create` template on the plugins | |
| CI | |
| ### Detection | |
| * [flutter/flutter#27258](https://github.com/flutter/flutter/issues/27258) - The | |
| plugins releasing process should be improved to help detect regressions. | |
| ### Mitigation | |
| * [flutter/flutter#14818](https://github.com/flutter/flutter/issues/14818) - | |
| Translate Gradle errors into actionable steps for our users when possible. | |
| * [dart-lang/pub#2038](https://github.com/dart-lang/pub/issues/2038) - Show a | |
| migration prompt and ask for confirmation on updating a breaking change in | |
| pub. | |
| * [dart-lang/pub-dartlang-dart#378](https://github.com/dart-lang/pub-dartlang-dart/issues/378) - Tag | |
| specific pub releases as broken. | |
| ### Process | |
| * [flutter/flutter#27258](https://github.com/flutter/flutter/issues/) - Have a | |
| better/more formalized releasing process for flutter/plugins. | |
| ### Fixes | |
| * [flutter/plugins#1127](https://github.com/flutter/plugins/pull/1127) | |
| * [flutter/plugins#1128](https://github.com/flutter/plugins/pull/1128) | |
| * [flutter/website#2310](https://github.com/flutter/website/pull/2310) | |
| * [flutter/plugins#1138](https://github.com/flutter/plugins/pull/1138) | |
| * [flutter/flutter#27566](https://github.com/flutter/flutter/pull/27566) | |
| * [flutter/website#2349](https://github.com/flutter/website/pull/2349) |