Mohammed Tarig Nour e98205f8ae
flutter_tools: correct iOS signing log for manual code signing (CODE_SIGN_STYLE=Manual) (#177852)
## Summary

When running `flutter build ipa` with a project that uses manual code
signing (`CODE_SIGN_STYLE=Manual`) for Release/Profile, the tool
currently prints:

```
Automatically signing iOS for device deployment using specified development team in Xcode project: x
```

This is misleading in two ways:

1. The project is not using automatic signing for Release/Profile, it's
explicitly using manual signing with a provisioning profile.
2. The build in this mode is typically for App Store/TestFlight
distribution, not just device deployment.

Users who rely on manual signing (for example, Push Notifications + Sign
in with Apple entitlements) often hit an `xcodebuild -exportArchive`
failure later (`"Runner.app" requires a provisioning profile ...`) and
assume Flutter overrode their signing, because of this log line. This
confusion has been reported in the context of `flutter build ipa` where
archive succeeds but export fails, and Flutter's messaging doesn't match
the actual signing setup.

**Related issues:**
- #106612 - Support `flutter build ipa` with manual signing and
provisioning profiles
- #113977 - Flutter build IPA with --export-options-plist not working

## What this change does

* Before logging "Automatically signing iOS ...", we now check the
active build configuration's `CODE_SIGN_STYLE`.
* If the style is `Manual`, we suppress the automatic-signing message
(since manual signing is not automatic).
* If the style is `Automatic` or not set, we keep the original behavior.
* No functional behavior of signing or export is changed.

## Before

```
Automatically signing iOS for device deployment using specified development team in Xcode project: x
```

(This message appears even when `CODE_SIGN_STYLE=Manual`)

## After

```
(No message when CODE_SIGN_STYLE=Manual, since signing is not automatic)
```

(The message only appears when `CODE_SIGN_STYLE=Automatic` or not set)

## Tests

* Added test in
`packages/flutter_tools/test/general.shard/ios/code_signing_test.dart`
to assert we don't emit the automatic-signing message when
`CODE_SIGN_STYLE=Manual`.
* All existing tests pass (40/40 tests in code_signing_test.dart).

## Why this helps

* Reduces confusion around manual signing / App Store export flows.
* Matches expectations from users who configure provisioning profiles
manually and expect Flutter to respect that configuration.
* Prevents users from thinking Flutter is overriding their manual
signing setup based on misleading log output.

## Breaking Changes

None. This change only affects log output and does not modify any
signing behavior, export behavior, or CLI interface.

## Verification

Reviewers can verify this fix by:
1. Creating a test iOS project with `CODE_SIGN_STYLE=Manual` and
`DEVELOPMENT_TEAM` set in Xcode project settings
2. Running `flutter build ipa --release --verbose`
3. Confirming the log does NOT show "Automatically signing iOS..."
4. Verifying the app still builds/signs correctly

The included unit test covers this scenario automatically.

---

Supersedes #177851 (that PR accidentally included unrelated commits from
my fork history). This version only includes the intended change and
tests.

---------

Co-authored-by: Navaron Bracke <brackenavaron@gmail.com>
2025-11-13 18:43:47 +00:00
..

Flutter Tools

This section of the Flutter repository contains the command line developer tools for building Flutter applications.

Working on Flutter Tools

Be sure to follow the instructions on CONTRIBUTING.md to set up your development environment. Further, familiarize yourself with the style guide, which we follow.

Setting up

First, ensure that the Dart SDK and other necessary artifacts are available by invoking the Flutter Tools wrapper script. In this directory run:

$ flutter --version

Running the Tool

To run Flutter Tools from source, in this directory run:

$ dart bin/flutter_tools.dart

followed by command-line arguments, as usual.

As a convenience for folks developing the flutter tool itself, you can also use the bin/flutter-dev script:

# Assuming flutter/bin is on your PATH
$ flutter-dev

Note: flutter-dev is identical to flutter, except it does not use a cached on-disk snapshot. In other words, it will be significantly slower but you will not need to forget (remember?) to delete the cached snapshot.

Running the analyzer

To run the analyzer on Flutter Tools, in this directory run:

$ flutter analyze

Writing tests

As with other parts of the Flutter repository, all changes in behavior must be tested. Tests live under the test/ subdirectory.

  • Hermetic unit tests of tool internals go under test/general.shard and must run in significantly less than two seconds.

  • Tests of tool commands go under test/commands.shard. Hermetic tests go under its hermetic/ subdirectory. Non-hermetic tests go under its permeable sub-directory. Avoid adding tests here and prefer writing either a unit test or a full integration test.

  • Integration tests (e.g. tests that run the tool in a subprocess) go under test/integration.shard.

  • Slow web-related tests go in the test/web.shard directory.

In general, the tests for the code in a file called file.dart should go in a file called file_test.dart in the subdirectory that matches the behavior of the test.

The dart_test.yaml file configures the timeout for these tests to be 15 minutes. The test.dart script that is used in CI overrides this to two seconds for the test/general.shard directory, to catch behaviour that is unexpectedly slow.

Please avoid setting any other timeouts.

Using local engine builds in integration tests

The integration tests can be configured to use a specific local engine variant by setting the FLUTTER_LOCAL_ENGINE and FLUTTER_LOCAL_ENGINE_HOST environment variables to the name of the local engines (e.g. android_debug_unopt and host_debug_unopt). If the local engine build requires a source path, this can be provided by setting the FLUTTER_LOCAL_ENGINE_SRC_PATH environment variable. This second variable is not necessary if the flutter and engine checkouts are in adjacent directories.

export FLUTTER_LOCAL_ENGINE=android_debug_unopt
export FLUTTER_LOCAL_ENGINE_HOST=host_debug_unopt
flutter test test/integration.shard/some_test_case

Running the tests

To run all of the unit tests:

$ flutter test test/general.shard

The tests in test/integration.shard are slower to run than the tests in test/general.shard. Depending on your development computer, you might want to limit concurrency. Generally it is easier to run these on CI, or to manually verify the behavior you are changing instead of running the test.

The integration tests also require the FLUTTER_ROOT environment variable to be set. The full invocation to run everything might therefore look something like:

$ export FLUTTER_ROOT=~/path/to/flutter-sdk
$ flutter test --concurrency 1

This may take some time (on the order of an hour). The unit tests alone take much less time (on the order of a minute).

You can run the tests in a specific file, e.g.:

$ flutter test test/general.shard/utils_test.dart

Forcing snapshot regeneration

To force the Flutter Tools snapshot to be regenerated, delete the following files:

$ rm ../../bin/cache/flutter_tools.stamp ../../bin/cache/flutter_tools.snapshot