Sitelet https://github.com/flutter/flutter/pull/189918
Skip to content

Full migration for agp new dsl (should not land as is) - #189918

Draft
reidbaker wants to merge 13 commits into
flutter:masterfrom
reidbaker-agent:agp-gradle-api
Draft

reidbaker wants to merge 13 commits into
flutter:masterfrom
reidbaker-agent:agp-gradle-api

Conversation

@reidbaker

Copy link
Copy Markdown
Contributor

This was llm authored. I am opening the pull request to see what happens in the presubmit environment.

This contains breaking changes.

Pre-launch Checklist

  • I read the [Contributor Guide] and followed the process outlined there for submitting PRs.
  • I read the [AI contribution guidelines] and understand my responsibilities, or I am not using AI tools.
  • I read the [Tree Hygiene] wiki page, which explains my responsibilities.
  • I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement].
  • I signed the [CLA].
  • I listed at least one issue that this PR fixes in the description above.
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or this PR is [test-exempt].
  • I followed the [breaking change policy] and added [Data Driven Fixes] where supported.
  • All existing and new tests are passing.

@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label Jul 23, 2026
@github-actions github-actions Bot added platform-android Android applications specifically tool Affects the "flutter" command-line tool. See also t: labels. team-android Owned by Android platform team d: docs/ flutter/flutter/docs, for contributors labels Jul 23, 2026
@reidbaker
reidbaker requested a review from a team as a code owner July 23, 2026 14:34
@reidbaker
reidbaker requested review from mboetger and removed request for a team July 23, 2026 14:34
@reidbaker
reidbaker marked this pull request as draft July 23, 2026 14:34
@google-cla

google-cla Bot commented Jul 23, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request migrates the Flutter Gradle Plugin to the public Android Gradle Plugin (AGP) API surface, removing dependencies on AGP internals and legacy DSL/Variant APIs. It introduces dedicated lazy tasks for asset and APK copying, cleans up the android.newDsl=false opt-out from templates and existing projects via a new migration, and updates error handling to guide users through migrating legacy build scripts. Feedback on the changes suggests using dependsOn instead of finalizedBy to attach the APK copying task to the assemble task, preventing secondary failures from obscuring compilation errors on failed builds.

Comment on lines +453 to +456
val assembleTaskName = "assemble$capitalizeVariantName"
projectToAddTasksTo.tasks
.matching { it.name == assembleTaskName }
.configureEach { finalizedBy(copyFlutterApksTaskProvider) }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using finalizedBy to attach CopyFlutterApksTask to the assemble task can lead to confusing build failure outputs. In Gradle, finalizer tasks run even if the finalized task fails. If the build fails during compilation or packaging, the APK and its metadata won't be generated. When CopyFlutterApksTask runs as a finalizer, it will fail with a GradleException ('Flutter could not read the built APK metadata...'), which then obscures the actual compilation or packaging error at the end of the build log.

Suggest using dependsOn instead of finalizedBy. This ensures the copy task is only executed if the build successfully reaches the assembly stage, preventing misleading secondary failures.

Suggested change
val assembleTaskName = "assemble$capitalizeVariantName"
projectToAddTasksTo.tasks
.matching { it.name == assembleTaskName }
.configureEach { finalizedBy(copyFlutterApksTaskProvider) }
val assembleTaskName = "assemble$capitalizeVariantName"
projectToAddTasksTo.tasks
.matching { it.name == assembleTaskName }
.configureEach { dependsOn(copyFlutterApksTaskProvider) }

@reidbaker-agent
reidbaker-agent force-pushed the agp-gradle-api branch 4 times, most recently from a0ab835 to 4f20a40 Compare July 29, 2026 20:45
@reidbaker

Copy link
Copy Markdown
Contributor Author

Prompt used for updating this pr.

We have failing presubmit CI checks on our PR https://github.com/flutter/flutter/pull/189918. This pull request is part of a stacked PR chain:
1. https://github.com/reidbaker-agent/flutter/pull/1 (branch: agp-api-doc)
2. https://github.com/reidbaker-agent/flutter/pull/2 (branch: agp-internal-utils)
3. https://github.com/reidbaker-agent/flutter/pull/3 (branch: agp-buildmode-deps)
4. https://github.com/reidbaker-agent/flutter/pull/4 (branch: agp-plugin-buildtypes)
5. https://github.com/reidbaker-agent/flutter/pull/5 (branch: agp-ndk-fallback)
6. https://github.com/reidbaker-agent/flutter/pull/6 (branch: agp-assets-onvariants)
7. https://github.com/reidbaker-agent/flutter/pull/7 (branch: agp-apk-copy-versioncode)
8. https://github.com/reidbaker-agent/flutter/pull/8 (branch: agp-add-to-app)
9. https://github.com/reidbaker-agent/flutter/pull/9 (branch: agp-aar-script)
10. https://github.com/reidbaker-agent/flutter/pull/10 (branch: agp-newdsl-flip)
11. https://github.com/reidbaker-agent/flutter/pull/11 (branch: agp-gradle-api)

Please handle the presubmit failures using the following systematic workflow:
### 1. Investigate & Inventory CI Failures
- Query the CI build logs or reproduce the failures locally to identify every failing presubmit job.
- Determine the underlying technical root cause for each failure.
### 2. Resolve & Verify Locally
- Implement minimal, targeted fixes for each root cause in your local workspace.
- Prove that your fixes resolve the failures by running local verification commands, static analyzers, linters, formatters, and relevant test suites.
- All modified files must pass static analysis and formatting checks with zero errors before proceeding.
### 3. Determine Target PR Assignments (Preserve Stack Bisectability)
- **Do NOT place all presubmit fixes into a catch-all commit on the final PR.**
- Trace git commit history and diffs across the PR stack to identify the exact PR that introduced the regression or added the feature being modified.
- Assign each fix to its originating PR so that every intermediate branch in the stack remains independently CI-green and git-bisectable.
### 4. Document Findings & PR Stack Mapping Table
- Update our existing analysis artifact at:
  `/Users/reidbaker/.gemini/jetski/brain/ba5a826f-1cd3-4096-a1b6-08626d40983f/presubmit_failures_analysis_and_fixes.md`
- Ensure the document accurately reflects:
  1. **Inventory of Failing Presubmits**: Job names, categories, and root causes.
  2. **Implemented Fixes & Proofs**: Code changes made and exact terminal commands/outputs proving local pass status.
  3. **Target PR Assignment Matrix**: Mapping each fix to its target PR in the stack with a technical rationale explaining why placing it earlier would break compilation and placing it later would break bisectability.
### 5. Adversarial Review & Intent Verification
- Run an adversarial review (or spin up a subagent with an Expert/Reviewer persona) on your Target PR Assignment Matrix to challenge your rationale and confirm no fix was assigned to the wrong branch.
- If you rebase or amend the branches in the stack, invoke a subagent for each updated branch to inspect the commit diff and verify that the original architectural and functional intent of the PR remained 100% unchanged.
Once your local verifications and adversarial reviews are complete, summarize your findings and let me know you are ready for my review before any rebase or push.

@github-actions github-actions Bot added a: tests "flutter test", flutter_test, or one of our tests framework flutter/packages/flutter repository. See also f: labels. d: examples Sample code and demos f: integration_test The flutter/packages/integration_test plugin team-web Owned by Web platform team labels Jul 30, 2026
…page draft)

Phase P0 of the Flutter Gradle Plugin migration to the AGP public API
surface (flutter#180137, flutter#166550): the contributor
migration record (replacement map, decision records, phase map,
revert-window table) and the draft of the user-facing breaking-change
page to be published to docs.flutter.dev before the newDsl flip reaches
beta.

Revert-safe: always.
…k/ndk reads to the public DSL

Phase P1 of the AGP public-API migration (flutter#180137,
flutter#166550):

- VersionFetcher no longer calls the internal
  com.android.build.gradle.internal.utils.getKotlinAndroidPluginVersion.
  getKGPVersion now relies on the existing public fallback chain
  (kotlin_version property -> KotlinAndroidPluginWrapper.pluginVersion ->
  reflection) and documents that null is the expected result when KGP is
  absent (e.g. under AGP built-in Kotlin). DependencyVersionChecker
  already treats null as "KGP not required".
- AgpCommonExtensionWrapper gains compileSdkPreview.
- getCompileSdkFromProject now reads compileSdk/compileSdkPreview from
  the new DSL via the wrapper and returns a structured CompileSdkVersion
  instead of parsing the legacy "android-NN" string. The PluginHandler
  compileSdk mismatch warning uses CompileSdkVersion.isHigherThan, which
  defines the preview semantics the old string comparison got wrong
  (resolves the PluginHandler TODO): preview > numeric, distinct preview
  codenames incomparable (no warning), numeric compared numerically.
  Warning message text is unchanged.
- getConfiguredNdkVersion reads through the wrapper instead of the
  legacy BaseExtension fallback.
- Deletes the setAgpKotlinVersionToNull test helper (existed only to
  stub the internal AGP call) and updates unit tests accordingly; adds
  tests for both preview-vs-numeric directions and the codename reset
  case.

Verification note: the FGP unit test suite could not be executed in this
sandbox (the network policy blocks dl.google.com, so AGP artifacts do
not resolve); run 'gradle test' in packages/flutter_tools/gradle in CI.

Revert-safe until P2 lands.
…gh the new DSL

Phase P2 of the AGP public-API migration (flutter#180137,
flutter#166550):

- buildModeFor gains a (buildTypeName, isDebuggable) core overload and a
  new-DSL BuildType overload. Application and dynamic-feature build
  types use their public isDebuggable flag; library build types have no
  public debuggable signal at DSL scope, so the conventional "debug"
  name is used for them. The legacy com.android.builder.model.BuildType
  overload remains for the variant-scope call sites that migrate in
  later phases.
- addFlutterDependencies (engine/embedding deps) now takes a new-DSL
  BuildType, and FlutterPlugin registers it via the wrapper's buildTypes
  container instead of the legacy BaseExtension.
- PluginHandler's three dependency-wiring loops (per-build-type Api
  wiring, embedding deps, plugin-to-plugin deps) iterate the wrapper
  container. The build-type copy block still uses the legacy container
  and internal.dsl.BuildType; that is phase P3.
- build.gradle.kts accepts -PagpVersion= so CI can compile and test the
  plugin against the AGP 9 line in addition to the default (the public
  DSL is not binary-compatible between AGP 8 and 9 everywhere), and a
  new validateNoCommonExtensionInBytecode task fails the build if any
  compiled main class references CommonExtension (the known-broken
  type that AgpCommonExtensionWrapper exists to avoid).
- android_run_flutter_gradle_plugin_tests_test.dart gains a second test
  running the suite with -PagpVersion=<templateAndroidGradlePluginVersion>.
- PluginHandlerTest no longer depends on exhausted-iterator mock
  behavior; the wrapper container returns a fresh iterator per call.

Verification note: FGP unit tests could not be executed in this sandbox
(network policy blocks dl.google.com); run 'gradle test' and
'gradle -PagpVersion=9.1.0 test' in packages/flutter_tools/gradle in CI.

Revert-safe until P3 lands.
Phase P3 of the AGP public-API migration (flutter#180137,
flutter#166550):

- PluginHandler no longer imports com.android.build.gradle.internal.dsl.BuildType.
  The build-type copy block that shared live legacy BuildType instances
  (addAll) for app-type plugin projects and hand-copied two properties
  for library plugin projects is replaced by a single initWith-based
  copy on the new-DSL containers: missing build types are created on
  the plugin project with initWith(appBuildType) (which carries
  matchingFallbacks), and isDebuggable is additionally copied when both
  sides are application build types. Library build types cannot receive
  app-specific properties through the public DSL - this is a documented
  behavior change of the migration (BuildConfig.DEBUG / JNI
  debuggability of plugins built for custom debuggable build types).
- Production sources are now free of com.android.build.gradle.internal
  imports; InternalAgpApiImportTest locks that in (test sources may
  still use internals until the gradle-api dependency swap).
- PluginHandlerTest: the two mock-only copy tests (which never invoked
  configurePlugins) are replaced with tests that run configurePlugins
  and assert the initWith copy for both a library plugin project and an
  app plugin project, including the custom-debuggable-build-type ->
  debug engine artifact mapping.
- The planned pre-spike (afterEvaluate DSL mutation under newDsl=true)
  could not run in this sandbox; recorded in the migration doc with the
  finalizeDsl fallback. android_plugin_example_app_build and a custom
  build-type scratch build must confirm in CI.

Verification note: FGP unit tests could not be executed in this sandbox
(network policy blocks dl.google.com); run 'gradle test' (both AGP
axes) in packages/flutter_tools/gradle in CI.

Revert-safe until P4 lands.
…public DSL

Phase P4 of the AGP public-API migration (flutter#180137,
flutter#166550):

- AgpCommonExtensionWrapper gains externalNativeBuild, and both the
  already-configuring-a-native-build check in forceNdkDownload and the
  synthetic-cmake fallback now read/write cmake.path,
  cmake.buildStagingDirectory and the per-build-type
  externalNativeBuild.cmake.arguments through the public DSL (property
  assignment with File values instead of the legacy Any-taking
  CmakeOptions methods; arguments via the public MutableList).
- getLegacyAndroidExtension and the BaseExtension import are deleted
  from FlutterPluginUtils; nothing in production sources references
  BaseExtension anymore.
- forceNdkDownload tests move their mocks from BaseExtension/
  internal CmakeOptions to the wrapper path (findByName("android") +
  public Cmake), assert cmake arguments by list content, and drop the
  defaultConfig-untouched assertions that only existed to guard the
  legacy extension. The two tests that asserted the old
  ApplicationExtension-vs-BaseExtension ndkVersion preference are
  deleted: getConfiguredNdkVersion has had a single source since P1.
  Also restores the findByType(ApplicationExtension) mocks (needed by
  isFlutterAppProject) that P1's test edit dropped in three tests.
- FlutterPluginUtilsTest no longer imports internal.dsl.CmakeOptions or
  internal.dsl.DefaultConfig.

Verification note: FGP unit tests could not be executed in this sandbox
(network policy blocks dl.google.com); run 'gradle test' (both AGP
axes) in packages/flutter_tools/gradle in CI, plus an NDK-absent
scratch build exercising the synthetic-cmake fallback.

Revert-safe until P5 lands.
… projects

Phase P5, commit 1 of 2 (P5a), of the AGP public-API migration
(flutter#180137, flutter#166550):

- For application projects, compileFlutterBuild<Variant> (FlutterTask)
  is now registered inside the consolidated androidComponents.onVariants
  block as a lazy TaskProvider, configured entirely from the public
  variant API: minSdk from Variant.minSdk.apiLevel, flavor from
  Variant.flavorName, and the Flutter build mode from
  buildModeFor(variant.buildType, variant.debuggable) so custom
  debuggable build types keep mapping to debug engine artifacts.
  Registration is gated by shouldConfigureFlutterTask on the computed
  assemble task name (new name-based overload), mirroring the legacy
  callback's gating.
- addFlutterDeps is split: addFlutterDepsForApp (per-ABI versionCode,
  legacy assets copy into the merged-assets dir, processResources hook)
  looks the compile task up by name instead of registering it;
  addFlutterDepsForModule keeps the full legacy path for add-to-app
  module projects until that path migrates. The always-null
  packageAssets/isUsedAsSubproject dead code and the duplicated
  processResources hook in the application variant callback are
  removed.

No behavior change intended for what gets built; the assets delivery
mechanism changes in the next commit (P5b).

Verification note: FGP unit tests could not run in this sandbox (network
policy blocks dl.google.com); run 'gradle test' (both AGP axes) in CI.

Revert-safe (with P5b) until P6 lands.
…app path

Phase P5, commit 2 of 2 (P5b), of the AGP public-API migration
(flutter#180137, flutter#166550):

- New CopyFlutterAssetsTask stages flutter_assets/** from the Flutter
  build output into its own output directory (modeled on
  CopyFlutterJniLibsTask, including the overlapping-outputs rationale),
  applying the user read+write file permissions the old Copy task set.
- For application projects, copyFlutterAssets<Variant> is registered in
  the consolidated onVariants block as a lazy TaskProvider and wired via
  variant.sources.assets.addGeneratedSourceDirectory. AGP now merges
  Flutter's assets like any other assets source; collisions with user
  assets resolve by source-set priority instead of the old post-merge
  overwrite (documented behavior change). A missing assets source set
  fails loudly instead of silently building an APK without Flutter
  assets.
- The legacy app-path assets copy (into mergeAssets.outputDir), its
  processResources/cleanMergeAssets task-graph surgery, and the manual
  compress<V>Assets dependsOn wiring are deleted for app projects; AGP
  owns those edges now. The application variant callback is reduced to
  the per-ABI versionCode override and the flutter-apk copy, both of
  which migrate in the next phase. The add-to-app module path is
  unchanged (still the full legacy copy) until it migrates.
- copyFlutterAssets<Variant> changes type from org.gradle.api.tasks.Copy
  to CopyFlutterAssetsTask and is now registered lazily (documented
  breaking change for build scripts that referenced it by type).
- Tests: new CopyFlutterAssetsTaskTest executes the task against real
  files (staging layout, permission bits, non-asset exclusion, stale
  output cleanup). The FlutterPluginTest filePermissions test built on
  capturing the legacy Copy registration is superseded by it.

Verification (CI): gradle unit tests both AGP axes; integration
builddir/obfuscate/jni/print_build_variants/deferred_components_assets;
add-to-app source smoke + flutter build aar; asset-staleness rebuild
check; config-cache per baseline.

Revert-safe until P6 lands.
Phase P6 of the AGP public-API migration (flutter#180137,
flutter#166550). The application path no longer uses the legacy
variant API at all:

- New CopyFlutterApksTask copies the variant's SingleArtifact.APK
  directory contents (via BuiltArtifactsLoader) into
  build/outputs/flutter-apk under the unchanged names
  app[-abi][-flavor]-<build-mode>.apk. It is attached as a finalizer of
  assemble<Variant> (matched by name, with a projectsEvaluated
  assertion that fails loudly if the assemble task was never created,
  instead of silently leaving flutter run/build without APKs). The task
  declares individual predictable @OutputFiles - computed from target
  platforms, flavor, and build mode - rather than the shared
  flutter-apk directory, so it is UP-TO-DATE-capable without
  overlapping outputs between variants; it replaces the old
  assemble.doLast copy.
- Per-ABI versionCode for --split-per-abi builds is now a read-then-set
  on VariantOutput.versionCode inside onVariants (the output is seeded
  with AGP's merged value, which covers flavor-defined versionCodes),
  replacing versionCodeOverride on the legacy ApkVariantOutput. When
  the built APK's versionCode differs from what Flutter configured
  (e.g. an afterEvaluate mutation), CopyFlutterApksTask logs a warning
  pointing at androidComponents.onVariants.
  Note on onVariants FIFO callback ordering: Because FGP is applied at
  line 25 of build.gradle.kts, FGP's callback executes before app-level
  onVariants callbacks at line 70. Any custom app-level block reading
  output.versionCode.get() will observe the ABI-offset value. For
  standard apps, no change is needed; monotonic ABI ordering and Play
  Store uniqueness are preserved even if an app transforms versionCode.
- The entire legacy applicationVariants.configureEach block and its
  helpers are deleted; AbstractAppExtension remains only in the
  add-to-app module path, which migrates next.

Verification (CI): split-per-abi + apkanalyzer per-ABI versionCode
assertions including the flavor-defined-versionCode case; flavor
filename check; flutter run / hot restart / attach; Windows-runner
smoke for the copy tasks; android_e2e_api_test; gradle unit tests on
both AGP axes.

Revert-safe until P7 lands (mutually tolerant with P7 until P10).
…ct cross-wiring

Phase P7 of the AGP public-API migration (flutter#180137,
flutter#166550), the last Kotlin consumer of the legacy variant
API:

- Add-to-app module (library) projects now use the same consolidated
  onVariants block as application projects: the Flutter compile task
  and CopyFlutterAssetsTask are registered lazily per library variant,
  and flutter_assets are wired through
  variant.sources.assets.addGeneratedSourceDirectory. The host
  application consumes them through AGP's normal library packaging and
  variant matching, with build modes resolved from the public
  Component.debuggable flag (so a custom debuggable host build type
  such as 'staging' still maps to the debug engine artifacts via the
  module's matched variant). Module variants skip the CLI task-name
  gating: which module variant a host build consumes is AGP's variant
  matching decision, and a module has at most three variants to
  configure lazily.
- The host-project lookup, the appProject.afterEvaluate
  libraryVariants.all x applicationVariants.all cross-product, the
  explicit merge<HostVariant>Assets.dependsOn edge, and the
  addFlutterDepsForModule legacy fork from P5 are deleted.
- flutter.hostAppProjectName is now a no-op: it only fed the host
  lookup. A warning explains that it has no effect and will be removed
  in a future Flutter release.
- The legacy com.android.builder.model.BuildType buildModeFor overload
  lost its last caller and is deleted along with its duplicate tests
  (the P2 name/debuggable and DSL overload tests cover the semantics).
  FlutterPlugin.kt and FlutterPluginUtils.kt no longer import any
  legacy (non com.android.build.api) AGP types.

Verification (CI): build_android_host_app_with_module_source,
module_host_with_custom_build, module_custom_host_app_name scenarios;
module-root flutter build apk; add-to-app newDsl=true test; gradle unit
tests on both AGP axes.

Revert-safe until P10 lands (mutually tolerant with P6).
Phase P8 of the AGP public-API migration (flutter#180137,
flutter#166550):

- The library-project check no longer probes for the legacy
  android.libraryVariants property (absent under the new DSL); it
  checks for the com.android.library plugin. Error message unchanged.
- The plugin-to-module assembleAar task wiring enumerates published
  variants through the public software components (which the script
  already used for task creation) instead of libraryVariants.
- The singleVariant dedup guard no longer reads the internal
  publishing.singleVariants collection. Flutter now marks projects it
  configured with an ext property and declares each variant's
  publishing in a try-catch: when the project's own build file already
  declared publishing for a variant, the user's declaration wins and a
  warning explains the situation and the fix. (Previously any
  user-declared variant silently disabled Flutter's publishing setup
  for ALL variants, which broke partially-declared projects at
  publication time with no explanation.)

Verification (CI): flutter build aar with and without flavors for
module and plugin projects; AAR-host add-to-app flow; a scratch module
with a partial user singleVariant declaration; newDsl=true aar flow.

Revert-safe even after P10, but not after P9.
…it away

Phase P9 of the AGP public-API migration (flutter#180137,
flutter#166550) - the breaking-change PR. The Flutter Gradle
Plugin is public-API-only since P7/P8, so projects no longer need
android.newDsl=false:

- The app and module gradle.properties templates no longer ship the
  newDsl opt-out (android.builtInKotlin=false stays; it belongs to the
  separate built-in Kotlin migration).
- DisableNewDslMigration is replaced by RemoveNewDslOptOutMigration,
  which removes exactly the line pairs Flutter wrote: one of the two
  known marker comments ('added by the Flutter template' / 'added
  automatically by Flutter migrator') immediately followed by
  android.newDsl=false. The removal is anchored on the android.newDsl
  property line, so the adjacent builtInKotlin marker/flag lines are
  never touched; hand-added opt-outs and developer-edited values are
  respected; the file the old migrator created with only the flag is
  emptied. A visible status message names the change and links the
  breaking-change page.
- New legacyVariantApiUsageErrorHandler matches the Gradle failures
  users hit when their build scripts use the removed legacy variant API
  (unknown property/method applicationVariants, libraryVariants,
  testVariants, variantFilter) and prints problem, cause, fix
  (androidComponents.onVariants), the breaking-change page URL, and the
  android.newDsl=false escape hatch with its AGP 10 expiry.
  useNewAgpDslErrorHandler is retired: its signature was the FGP's own
  legacy DSL access failing under newDsl, which can no longer happen.
- kNewDslBreakingChangeDocsUrl pins the docs.flutter.dev page location;
  the in-repo website-page draft records that the page must be
  published at that exact path before this reaches beta.
- The migration doc records the stable-channel release-management step
  (guard or accept the add-migrator flip-flop during the overlap
  window).
- Updated test_result_embedder.gradle.kts in
  dev/integration_tests/android_hardware_smoke_test to resolve adbExecutable
  via ApplicationAndroidComponentsExtension (sdkComponents.adb) with fallback
  to BaseExtension, preventing Extension of type 'BaseExtension' does not exist
  when RemoveNewDslOptOutMigration enables newDsl=true.

Verified here: android_project_migration_test.dart (42/42) and
gradle_errors_test.dart (56/56) pass with the repo Dart SDK; dart
analyze clean on the changed files. CI preconditions before this ships:
full newDsl=true matrix green (R6), website page live, top-25 pub.dev
plugin scratch-app sweep under -Pandroid.newDsl=true, and
GradleHandledError eventLabel hit-rate monitoring during the beta soak
as the stable go/no-go signal.

Cleanly revertible in isolation.
Phase P10, the final phase of the AGP public-API migration
(flutter#180137, flutter#166550):

- build.gradle.kts swaps both AGP dependencies from the full
  com.android.tools.build:gradle artifact to
  com.android.tools.build:gradle-api. Compilation is now the proof that
  the plugin uses zero AGP internals (AGP 10 removes access to them
  entirely), on top of the InternalAgpApiImportTest source check and
  the validateNoCommonExtensionInBytecode bytecode check, which stay as
  fast-feedback guards.
- FlutterPluginTest is rewritten on public-API mocks only: the
  AbstractAppExtension multi-interface mock, BaseExtension,
  CommonExtension, internal.dsl.DefaultConfig, and the legacy
  sourceSets/AndroidSourceDirectorySet mocks are gone. No test source
  references a full-artifact-only or internal type anymore.
- The --android-skip-build-dependency-validation help text now warns
  that skipping validation cannot make unsupported AGP versions work:
  builds below the supported minimum fail in Gradle regardless.
- The android tooling README gains the AGP-bump checklist step to run
  the FGP test suite against the new version's public API artifact
  (-PagpVersion axis) and links the migration doc.

Verification (CI): full matrix per the migration doc (gradle unit tests
on both AGP axes - now both against gradle-api; scratch-app matrix;
add-to-app source/AAR flows; config-cache baseline). Dart analyzer
clean on the changed tool file.

Cleanly revertible in isolation.
@reidbaker-agent

Copy link
Copy Markdown
Contributor

Stack Audit Summary & Re-Authoring Guidance

Following the review on Phase 6 (flutter/flutter#192488), an architectural and correctness audit was conducted across the remaining downstream pull requests in the stack (Phases 7 through 11).

Detailed findings, evidence, and re-authoring instructions have been posted directly to each downstream PR on the fork:

  1. Phase 7 (reidbaker-agent/flutter#7):

    • Dual source of truth for APK filenames: Declared @OutputFiles and actual copy filenames can drift, causing untracked output copies and broken Gradle up-to-date checks.
    • False-positive versionCode warning: Warns on legitimate customer androidComponents.onVariants configurations because FGP's callback runs first.
    • Formula change documentation: Documents the shifted versionCode calculation order for split-per-ABI builds.
  2. Phase 8 (reidbaker-agent/flutter#8):

    • Eliminate string-based task lookup: CopyFlutterJniLibsTask still queried the compile task by name and used tasks.matching, despite compileTaskProvider being in scope within the same onVariants block.
    • Decouple variant configuration: Replaces mid-block return@onVariants with structured helpers.
    • Isolated Projects safety: Replaces rootProject.hasProperty check with providers.gradleProperty.
  3. Phase 9 (reidbaker-agent/flutter#9):

    • Lazy wiring in aar_init_script.gradle: Fixes eager .get() configuration-time task realization and guards against task lookup exceptions when publishing.multipleVariants is used.
    • Internal namespace compliance: Prefixes project extension properties with flutter.internal..
  4. Phase 10 (reidbaker-agent/flutter#10):

    • CRITICAL / High Severity: Deferred component templates (build.gradle.tmpl and deferred_components_test) still access applicationVariants. Flipping android.newDsl=true causes an immediate build failure. Must be migrated to modern AGP variant APIs.
    • Configuration cache hygiene: Resolves execution-time project.extensions lookups in smoke test scripts.
  5. Phase 11 (reidbaker-agent/flutter#11):

    • CRITICAL / High Severity: The migration removing android.builtInKotlin=false does not check for the presence of org.jetbrains.kotlin.android, which causes immediate build failures on AGP 9.
    • Bisectability preservation: Squashes unit test fixes back into their originating commits instead of bundling them into catch-all presubmit fix commits.
    • AGENTS.md Rule 1 compliance: Re-evaluates contributor bytecode validation tasks attached to check in customer-evaluated build.gradle.kts.

Re-Authoring Next Steps

When updating the stacked PR chain, branches should be re-authored / rebased against a recent cut of upstream flutter/flutter master + the updated Phase 6 (flutter/flutter#192488).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

a: tests "flutter test", flutter_test, or one of our tests CICD Run CI/CD d: docs/ flutter/flutter/docs, for contributors d: examples Sample code and demos f: integration_test The flutter/packages/integration_test plugin framework flutter/packages/flutter repository. See also f: labels. platform-android Android applications specifically team-android Owned by Android platform team team-web Owned by Web platform team tool Affects the "flutter" command-line tool. See also t: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants