Skip to content

[flutter tool] propagate analytics env to sub-tools#186780

Merged
auto-submit[bot] merged 11 commits into
flutter:masterfrom
pq:analytics_envProp
Jun 3, 2026
Merged

[flutter tool] propagate analytics env to sub-tools#186780
auto-submit[bot] merged 11 commits into
flutter:masterfrom
pq:analytics_envProp

Conversation

@pq

@pq pq commented May 20, 2026

Copy link
Copy Markdown
Contributor

Updates the Flutter CLI to propagate unified analytics environment variables down to all spawned subprocesses, achieving parity with dartdev(see: dart-lang/sdk@04c6612).

It automatically propagates:

  • DASH__SUPPRESS_ANALYTICS: Set to 'true' if analytics is disabled in the parent tool context (e.g. via config setting, bot detection, or FLUTTER_SUPPRESS_ANALYTICS), otherwise 'false'.
  • DASH__TOOL: Identifies the top-level tool calling the sub-tool, defaulting to 'flutter-tool'.

Architectural Rationale & Full Coverage

Rather than wrapping the environment map inside individual high-level wrappers (such as ProcessUtils), the propagation logic is centralized directly inside ErrorHandlingProcessManager (error_handling_io.dart), which is the single context-injected gate for process execution.

This centralized placement guarantees 100% coverage because:

  1. Every workflow in the codebase that executes processes via globals.processUtils delegates its calls directly to the context process manager.
  2. Any workflow that directly invokes process manager execution (e.g. calling globals.processManager.start(...) directly instead of processUtils) is also intercepted, securing full propagation coverage across the entire toolchain.

Fixes: #186696

Pre-launch Checklist

If you need help, consider asking for advice on the #hackers-new channel on Discord.

If this change needs to override an active code freeze, provide a comment explaining why. The code freeze workflow can be overridden by code reviewers. See pinned issues for any active code freezes with guidance.

Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the gemini-code-assist bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.

@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label May 20, 2026
@github-actions github-actions Bot added the tool Affects the "flutter" command-line tool. See also t: labels. label May 20, 2026
@github-actions github-actions Bot removed the CICD Run CI/CD label May 20, 2026

@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 implements environment variable propagation for unified analytics within ErrorHandlingProcessManager, ensuring that DASH__SUPPRESS_ANALYTICS and DASH__TOOL are passed to spawned processes. It also adds unit tests for this propagation and improves exception handling in shutdown hooks. Feedback suggests refactoring the environment propagation logic for better readability using Dart idioms and replacing LocalPlatform with FakePlatform in tests to ensure hermeticity.

Comment thread packages/flutter_tools/lib/src/base/error_handling_io.dart
Comment thread packages/flutter_tools/test/general.shard/base/process_test.dart Outdated
@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label May 20, 2026
@github-actions github-actions Bot removed the CICD Run CI/CD label May 20, 2026
@pq

pq commented May 20, 2026

Copy link
Copy Markdown
Contributor Author

Some context on the circular dependency exception handling (506dfce). I don't love it but the alternatives seem worse.

Here's a summary of what's up and the alternatives considered.

Circular Dependency Resolution & Alternatives Considered

During early tool startup, FlutterVersion runs a synchronous git log command during its own construction. Because process execution goes through ErrorHandlingProcessManager, looking up Analytics (which depends on FlutterVersion's properties) inside _propagateAnalyticsEnvironment creates a circular dependency cycle (FlutterVersion -> Process -> Analytics -> FlutterVersion).

We resolved this by catching ContextDependencyCycleException in _propagateAnalyticsEnvironment, allowing the process manager to safely skip environment propagation during early initialization phases while enabling it normally once context construction completes.

Alternatives Considered and Rejected:

  1. Bypassing the process manager for git startup ops (Option 1):
    • Why rejected: Directly calling Process.runSync from dart:io inside the version/git system breaks unit test mockability, as tests rely on intercepting all commands using FakeProcessManager to run hermetically without hitting real system binaries.
  2. Restricting propagation to specific executables (Option 2):
    • Why rejected: Restricting lookup to known Dart/Flutter binaries (like dart or pub) would fail to cover reentrant invocations where intermediary build systems (like gradle or xcodebuild) are spawned and in turn spawn child Dart/Flutter subtools.
  3. Dynamic Zone sentinel variables (Option 3):
    • Why rejected: Spawning custom Zones with sentinel tracking values simply to manage startup lifecycle added unnecessary complexity and boilerplate across version.dart, git.dart, and error_handling_io.dart.

@pq pq changed the title propagate analytics env to sub-tools [flutter tool] propagate analytics env to sub-tools May 20, 2026
@pq pq requested a review from bkonyi May 20, 2026 16:22
@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label May 20, 2026
@github-actions github-actions Bot removed the CICD Run CI/CD label May 20, 2026
Comment thread packages/flutter_tools/test/general.shard/base/process_test.dart Outdated
Comment thread packages/flutter_tools/lib/src/base/error_handling_io.dart Outdated
@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label Jun 1, 2026
@pq pq force-pushed the analytics_envProp branch from 0bec537 to a4aba20 Compare June 1, 2026 17:20
@github-actions github-actions Bot removed the CICD Run CI/CD label Jun 1, 2026
@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label Jun 1, 2026
Comment thread packages/flutter_tools/test/src/common.dart Outdated
@github-actions github-actions Bot removed the CICD Run CI/CD label Jun 1, 2026
@pq pq force-pushed the analytics_envProp branch from da74f8c to cdf9b58 Compare June 1, 2026 19:54
@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label Jun 1, 2026
@github-actions github-actions Bot removed the CICD Run CI/CD label Jun 1, 2026
@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label Jun 1, 2026

@bkonyi bkonyi 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.

LGTM!

Analytics? analytics;
try {
analytics = _analytics();
} on ContextDependencyCycleException {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Note that we need this still even with the lazy function.

I'll let Gemini try and explain. 🙃

Why we need both the Lazy Callback and the ContextDependencyCycleException catch

Both are required because they prevent two different circular dependency crashes at different stages of bootstrapping:

1. The Lazy Callback (Prevents Eager Top-Level Crash)

If we passed the Analytics object eagerly in context_runner.dart, the context manager would immediately try to resolve globals.analytics (which depends on FlutterVersion -> ProcessManager) before ProcessManager is registered in the context. This causes a reentrant lookup of ProcessManager during its own construction, throwing a ContextDependencyCycleException at the top-level bootstrapping layer and crashing the CLI immediately.

The lazy callback allows ProcessManager to construct and register in the context successfully.

2. The ContextDependencyCycleException catch (Prevents Lazy Evaluation Crash)

Even with the lazy callback, a cycle is still triggered later, when the callback is first evaluated:

  1. During startup, globals.flutterVersion begins construction.
  2. In its constructor, it runs a synchronous git log command to resolve metadata.
  3. ErrorHandlingProcessManager intercepts git log and evaluates the lazy _analytics() callback.
  4. _analytics() queries Analytics, which queries FlutterVersion.
  5. Since FlutterVersion is still in the middle of being constructed, the context throws a ContextDependencyCycleException.

Keeping the try-catch inside _propagateAnalyticsEnvironment allows us to catch this late-evaluation cycle gracefully, skip environment propagation for the early git command, and let FlutterVersion finish bootstrapping successfully.

@pq pq added the autosubmit Merge PR when tree becomes green via auto submit App label Jun 1, 2026
@pq

pq commented Jun 1, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the thoughtful review @bkonyi!

@auto-submit auto-submit Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Jun 1, 2026
@auto-submit

auto-submit Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

autosubmit label was removed for flutter/flutter/186780, because - The status or check suite Windows framework_tests_misc_leak_tracking has failed. Please fix the issues identified (or deflake) before re-applying this label.

@github-actions github-actions Bot removed the CICD Run CI/CD label Jun 1, 2026
@pq pq added the autosubmit Merge PR when tree becomes green via auto submit App label Jun 1, 2026
@auto-submit auto-submit Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Jun 2, 2026
@auto-submit

auto-submit Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

auto label is removed for flutter/flutter/186780, Failed to enqueue flutter/flutter/186780 with HTTP 400: Pull request Required status check "Merge Queue Guard" is expected..

@bkonyi bkonyi added autosubmit Merge PR when tree becomes green via auto submit App CICD Run CI/CD labels Jun 2, 2026
@auto-submit auto-submit Bot added this pull request to the merge queue Jun 2, 2026
Merged via the queue into flutter:master with commit 2d69fbc Jun 3, 2026
172 checks passed
@flutter-dashboard flutter-dashboard Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Jun 3, 2026
@pq pq deleted the analytics_envProp branch June 3, 2026 16:33
auto-submit Bot pushed a commit to flutter/packages that referenced this pull request Jun 3, 2026
…11832)

Manual roll requested by tarrinneal@google.com

flutter/flutter@701665b...2ba5420

2026-06-03 engine-flutter-autoroll@skia.org Roll Packages from 818b310 to b11504f (8 revisions) (flutter/flutter#187511)
2026-06-03 mdebbar@google.com Add new file patterns for team-web labeler (flutter/flutter#187397)
2026-06-03 engine-flutter-autoroll@skia.org Roll Skia from 279b17fe9fc1 to d625048c853a (12 revisions) (flutter/flutter#187483)
2026-06-03 chris@bracken.jp [SwiftPM] Fix prefer_initializing_formals lint (flutter/flutter#187502)
2026-06-03 engine-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from q27k7_um1GvVrySZS... to ap7MhLX4TdpWRrLS_... (flutter/flutter#187478)
2026-06-03 bkonyi@google.com [SwiftPM] Fix concurrent directory/file/symlink creation crashes (flutter/flutter#186953)
2026-06-03 flar@google.com [Impeller] Fix positioning of text shadow masks (flutter/flutter#187460)
2026-06-02 burak.karahan@mail.ru Remove Material imports from painting tests (flutter/flutter#186937)
2026-06-02 awolff@google.com Add android_hardware_smoke_test integration tests (flutter/flutter#187130)
2026-06-02 137456488+flutter-pub-roller-bot@users.noreply.github.com Roll pub packages (flutter/flutter#187471)
2026-06-02 pq@users.noreply.github.com [flutter tool] propagate analytics env to sub-tools (flutter/flutter#186780)
2026-06-02 30870216+gaaclarke@users.noreply.github.com Adds macro for fragment shaders to support flutter <= 3.44 (flutter/flutter#187316)
2026-06-02 116356835+AbdeMohlbi@users.noreply.github.com Small clean-up in different java files under `engine/src/flutter/shell/platform/android/io/flutter/embedding/engine/` (flutter/flutter#186631)
2026-06-02 1961493+harryterkelsen@users.noreply.github.com refactor(web): Unify ui.Path code for CanvasKit and Skwasm (flutter/flutter#187331)
2026-06-02 engine-flutter-autoroll@skia.org Roll Packages from f5d50ca to 818b310 (2 revisions) (flutter/flutter#187441)
2026-06-02 faheemabbas766@gmail.com Allow selecting multi-digit device options (flutter/flutter#186184)
2026-06-02 puneetkukreja98@gmail.com Improve error message for type mismatch in Navigator.pop and maybePop. (flutter/flutter#186571)
2026-06-02 sanaullah.383@hotmail.com Remove semantics_tester import from material_button_test.dart (flutter/flutter#184807)
2026-06-02 bkonyi@google.com [flutter_tools] Refactor hostPlatform to use Abi.current() (flutter/flutter#185369)
2026-06-02 mvincentong@gmail.com Clean up avoid_type_to_string suppressions (flutter/flutter#186869)
2026-06-02 202459002+Lukes-Lair@users.noreply.github.com Update Flutter documentation links in flutter_console.bat (flutter/flutter#187354)
2026-06-02 154381524+flutteractionsbot@users.noreply.github.com Revert "[Impeller] Allow attaching specific texture mip levels and slices" (flutter/flutter#187445)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-packages
Please CC stuartmorgan@google.com,tarrinneal@google.com on the revert to ensure that a human
is aware of the problem.

To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
creatorpiyush pushed a commit to creatorpiyush/packages that referenced this pull request Jun 10, 2026
…lutter#11832)

Manual roll requested by tarrinneal@google.com

flutter/flutter@701665b...2ba5420

2026-06-03 engine-flutter-autoroll@skia.org Roll Packages from 818b310 to b11504f (8 revisions) (flutter/flutter#187511)
2026-06-03 mdebbar@google.com Add new file patterns for team-web labeler (flutter/flutter#187397)
2026-06-03 engine-flutter-autoroll@skia.org Roll Skia from 279b17fe9fc1 to d625048c853a (12 revisions) (flutter/flutter#187483)
2026-06-03 chris@bracken.jp [SwiftPM] Fix prefer_initializing_formals lint (flutter/flutter#187502)
2026-06-03 engine-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from q27k7_um1GvVrySZS... to ap7MhLX4TdpWRrLS_... (flutter/flutter#187478)
2026-06-03 bkonyi@google.com [SwiftPM] Fix concurrent directory/file/symlink creation crashes (flutter/flutter#186953)
2026-06-03 flar@google.com [Impeller] Fix positioning of text shadow masks (flutter/flutter#187460)
2026-06-02 burak.karahan@mail.ru Remove Material imports from painting tests (flutter/flutter#186937)
2026-06-02 awolff@google.com Add android_hardware_smoke_test integration tests (flutter/flutter#187130)
2026-06-02 137456488+flutter-pub-roller-bot@users.noreply.github.com Roll pub packages (flutter/flutter#187471)
2026-06-02 pq@users.noreply.github.com [flutter tool] propagate analytics env to sub-tools (flutter/flutter#186780)
2026-06-02 30870216+gaaclarke@users.noreply.github.com Adds macro for fragment shaders to support flutter <= 3.44 (flutter/flutter#187316)
2026-06-02 116356835+AbdeMohlbi@users.noreply.github.com Small clean-up in different java files under `engine/src/flutter/shell/platform/android/io/flutter/embedding/engine/` (flutter/flutter#186631)
2026-06-02 1961493+harryterkelsen@users.noreply.github.com refactor(web): Unify ui.Path code for CanvasKit and Skwasm (flutter/flutter#187331)
2026-06-02 engine-flutter-autoroll@skia.org Roll Packages from f5d50ca to 818b310 (2 revisions) (flutter/flutter#187441)
2026-06-02 faheemabbas766@gmail.com Allow selecting multi-digit device options (flutter/flutter#186184)
2026-06-02 puneetkukreja98@gmail.com Improve error message for type mismatch in Navigator.pop and maybePop. (flutter/flutter#186571)
2026-06-02 sanaullah.383@hotmail.com Remove semantics_tester import from material_button_test.dart (flutter/flutter#184807)
2026-06-02 bkonyi@google.com [flutter_tools] Refactor hostPlatform to use Abi.current() (flutter/flutter#185369)
2026-06-02 mvincentong@gmail.com Clean up avoid_type_to_string suppressions (flutter/flutter#186869)
2026-06-02 202459002+Lukes-Lair@users.noreply.github.com Update Flutter documentation links in flutter_console.bat (flutter/flutter#187354)
2026-06-02 154381524+flutteractionsbot@users.noreply.github.com Revert "[Impeller] Allow attaching specific texture mip levels and slices" (flutter/flutter#187445)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-packages
Please CC stuartmorgan@google.com,tarrinneal@google.com on the revert to ensure that a human
is aware of the problem.

To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
via-guy pushed a commit to via-guy/flutter that referenced this pull request Jun 26, 2026
Updates the Flutter CLI to propagate unified analytics environment
variables down to all spawned subprocesses, achieving parity with
`dartdev`(see:
dart-lang/sdk@04c6612).

It automatically propagates:


* `DASH__SUPPRESS_ANALYTICS`: Set to `'true'` if analytics is disabled
in the parent tool context (e.g. via config setting, bot detection, or
`FLUTTER_SUPPRESS_ANALYTICS`), otherwise `'false'`.
* `DASH__TOOL`: Identifies the top-level tool calling the sub-tool,
defaulting to `'flutter-tool'`.
### Architectural Rationale & Full Coverage
Rather than wrapping the environment map inside individual high-level
wrappers (such as `ProcessUtils`), the propagation logic is centralized
directly inside **`ErrorHandlingProcessManager`**
(`error_handling_io.dart`), which is the single context-injected gate
for process execution.

This centralized placement guarantees **100% coverage** because:
1. Every workflow in the codebase that executes processes via
`globals.processUtils` delegates its calls directly to the context
process manager.
2. Any workflow that directly invokes process manager execution (e.g.
calling `globals.processManager.start(...)` directly instead of
`processUtils`) is also intercepted, securing full propagation coverage
across the entire toolchain.

Fixes: flutter#186696


## Pre-launch Checklist

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

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

If this change needs to override an active code freeze, provide a
comment explaining why. The code freeze workflow can be overridden by
code reviewers. See pinned issues for any active code freezes with
guidance.

**Note**: The Flutter team is currently trialing the use of [Gemini Code
Assist for
GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).
Comments from the `gemini-code-assist` bot should not be taken as
authoritative feedback from the Flutter team. If you find its comments
useful you can update your code accordingly, but if you are unsure or
disagree with the feedback, please feel free to wait for a Flutter team
member's review for guidance on which automated comments should be
addressed.

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[AI contribution guidelines]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#ai-contribution-guidelines
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CICD Run CI/CD tool Affects the "flutter" command-line tool. See also t: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[analytics] Update the Flutter CLI to set analytics ENV variables when invoking sub-tools #2408

2 participants