ann-flavor-cocoapods 0.4.6 → 0.4.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0753376f0ddae76a1894acb795e3e1cac3f6a975a79b799e0cccc79c9db2760b
4
- data.tar.gz: cc9c6297e39a2702dc119975168fc92926eb2db5bdfc9c23ff44eb9076b8b568
3
+ metadata.gz: 0d456b989981f0e9a376250a86ef9938ae916032e121b89fd4117232303d0ece
4
+ data.tar.gz: f02019d7919198b23a805c0104912e106537dd9b136bd15c9d3c4f0f498dd109
5
5
  SHA512:
6
- metadata.gz: 2b56c73fc8ced1dbd22e58e2780aded019fc5cf87e76ed6df5fac6ec6ab4650f4391e3707543147095df39b1342fa892a9c6699604cad1ce75daec906b7a37cb
7
- data.tar.gz: 2c1dcff237aded83a87e68fe1b1d4869bd901d61c5703749307df2dd02ba91105fefdc62363fcc5d7b2dbb095bb09d491d5410b64456eced522e82a2255b9322
6
+ metadata.gz: fd843dc2cea6f16e286dc7a33c24bc88eb6993f44d0816e40f7eeac307075ef86766538ed29d51a1b922e01bedef9ee29403e3157d9eb923c76e22a475befdee
7
+ data.tar.gz: 1a193d4841e2968798c94e09704175cf45be1643a15a03038dbba4643eca7486a2fd5d071e431b5cdb836665a82a086fe8e7cccc6f4d5011cb75184a3572724d
@@ -0,0 +1,617 @@
1
+ # Changelog
2
+
3
+ ## 0.4.7
4
+
5
+ ### Added
6
+ - **`merge_info_plist`/`merge_entitlements` gain a genuine third merge
7
+ layer** — `ios/ann/Info/merged/plugin-contributions.plist`/
8
+ `ios/ann/Entitlements/merged/plugin-contributions.entitlements`, read as
9
+ a plain file with no knowledge of Flutter plugins or
10
+ `.flutter-plugins-dependencies` on this plugin's part — sitting between
11
+ the base (`Runner/Info.plist`/`Runner.entitlements`) and the flavor delta
12
+ in precedence. Companion fix to `ann-flavor-flutter` 1.7.1: that release
13
+ stops pre-merging plugin-contributed content into the per-flavor delta
14
+ file (which had silently changed that file's meaning) and writes it to
15
+ this new file instead, under the same `merged/` directory this plugin
16
+ already owns and already `.gitignore`s — this plugin now merges it as
17
+ its own layer so the final merged output is unchanged.
18
+ - `merge_entitlements`'s "nothing to sign with" check now also considers
19
+ `plugin-contributions.entitlements` — a plugin-only contribution (no
20
+ stock `Runner.entitlements`, no flavor delta) now correctly produces
21
+ signed output instead of leaving `CODE_SIGN_ENTITLEMENTS` unset.
22
+
23
+ ## 0.4.6
24
+
25
+ ### Changed
26
+ - **Info.plist and entitlements merging moved from a build-time
27
+ `PBXShellScriptBuildPhase` to plain Ruby code that runs during
28
+ CocoaPods' `post_integrate` hook (pod-install time).** 0.4.1-0.4.5
29
+ each narrowed the conditions under which the "Cycle inside Runner"
30
+ failure occurred, but deep research (Apple Developer Forums,
31
+ CocoaPods/CocoaPods#11133, several flutter/flutter issues, and the
32
+ `swift-build` source) confirmed the real cause: *any*
33
+ `PBXShellScriptBuildPhase` with declared `output_paths` feeding
34
+ `INFOPLIST_FILE`/`CODE_SIGN_ENTITLEMENTS` becomes a graph node XCBuild
35
+ must order relative to a shared `ModuleVerifierTaskProducer` gate that
36
+ framework-embed phases (CocoaPods and SPM alike) are also gated
37
+ behind — no `build_phases` position or `input_paths` declaration could
38
+ avoid it. The values these phases merged (flavor name, files already on
39
+ disk) are fully known at `pod install` time, so there is no need for a
40
+ build-time script phase at all — the same pattern CocoaPods' own
41
+ `Pods-Runner-Info.plist` already uses.
42
+ - `[ann-flavor] Merge Info.plist` and `[ann-flavor] Merge Entitlements`
43
+ build phases are no longer injected, at all, for any project (new or
44
+ upgrading from 0.4.1-0.4.5's phases, which are removed).
45
+ - Merged output is now written directly to
46
+ `ios/ann/Info/merged/<flavor>-<buildType>.plist` and
47
+ `ios/ann/Entitlements/merged/<flavor>-<buildType>.entitlements` — one
48
+ file per flavor **and build type** (previously one merged file per
49
+ flavor, always built from the `release`-level cascade regardless of
50
+ build type — see the matching `ann-flavor-flutter` 1.6.0 changelog
51
+ entry for the generator-side half of this fix).
52
+ - `INFOPLIST_FILE`/`CODE_SIGN_ENTITLEMENTS` build settings now point
53
+ directly at these per-build-type merged files under `$(SRCROOT)`,
54
+ instead of a `$(DERIVED_FILE_DIR)/...-merged...` path produced by a
55
+ script phase.
56
+
57
+ ### Fixed
58
+ - A stale merged entitlements file is now deleted when a flavor/build-type
59
+ combination that previously had entitlements to sign no longer does
60
+ (previously only the build setting was cleared; the stale file was left
61
+ on disk).
62
+
63
+ ## 0.4.5
64
+
65
+ ### Fixed
66
+ - **0.4.4 stopped the cycle for a *fresh* install, but any project already
67
+ on 0.4.1-0.4.3 kept hitting it after upgrading.** 0.4.4 stopped *setting*
68
+ `input_paths` on `[ann-flavor] Merge Entitlements`/`Merge Info.plist`, but
69
+ never explicitly *cleared* it. `existing = target.build_phases.find { ... }`
70
+ reuses the same Xcodeproj object across runs, and `pod install` never
71
+ touches an attribute it doesn't assign — so a project that had already run
72
+ 0.4.1-0.4.3 (which did set `input_paths` on that same, reused object) kept
73
+ the stale value forever, silently reintroducing the exact "Cycle inside
74
+ Runner" failure 0.4.4 was meant to remove. Confirmed live against `ledger`:
75
+ the cycle came back, now involving whichever framework happened to be on
76
+ the other side of the shared `ModuleVerifierTaskProducer` gate (in this
77
+ case an SPM-resolved `AppLovinAdapter.xcframework`, following the
78
+ consumer's separate SPM plugin migration — same underlying mechanism, not
79
+ a new bug). Fixed by explicitly setting `phase.input_paths = []` on both
80
+ phases, so a stale value is genuinely wiped on the next `pod install`, not
81
+ just left unset going forward.
82
+
83
+ ## 0.4.4
84
+
85
+ ### Fixed
86
+ - **"Cycle inside Runner" could still occur even after 0.4.1-0.4.3.**
87
+ Confirmed live (again, against `ledger`) that declaring `input_paths` on
88
+ `[CP] Check Pods Manifest.lock`'s own output (introduced in 0.4.1 as the
89
+ original fix, kept through 0.4.2/0.4.3 as "belt-and-suspenders") was
90
+ actually the *cause* of the cycle, not a fix for it: `[ann-flavor] Merge
91
+ Entitlements`/`[ann-flavor] Merge Info.plist`'s output feeds
92
+ `ProcessProductPackaging` (signing), which Xcode's new build system gates
93
+ behind a chain of task producers (`ModuleVerifierTaskProducer` et al) —
94
+ and `Check Pods Manifest.lock`'s own output is *itself* gated behind that
95
+ same chain. Declaring it as an input routed these phases through that
96
+ chain from the other direction, closing a genuine cycle with the Firebase
97
+ framework-copy phases (also gated behind it) regardless of
98
+ `build_phases` position. Fixed by removing the `input_paths` declaration
99
+ entirely — `output_paths` plus running after the Pods/framework-copy
100
+ phases (the 0.4.2 position fix, kept) is sufficient on its own; this
101
+ phase never actually needed Check Pods Manifest.lock's result as an
102
+ input. Xcode's own error message ("moving Check Pods Manifest.lock so it
103
+ runs before the phase that depends on its outputs") was describing a
104
+ self-inflicted dependency, not a real requirement.
105
+
106
+ ## 0.4.3
107
+
108
+ ### Fixed
109
+ - **0.4.2's fix produced a silently-corrupt `project.pbxproj`.** Moving
110
+ `[ann-flavor] Merge Entitlements`/`[ann-flavor] Merge Info.plist` from
111
+ `build_phases.unshift` to `build_phases.push` (to fix "Cycle inside
112
+ Runner") used the wrong method: `Xcodeproj::Project::ObjectList`
113
+ (`build_phases`'s real class) overrides `<<`/`insert`/`unshift`/`delete`
114
+ to register an added object in the project's global objects table, but
115
+ does **not** override `push` — plain `Array#push` silently bypasses that
116
+ registration. The phase ended up referenced in `buildPhases` with no
117
+ matching object anywhere else in `project.pbxproj`, which Xcode then
118
+ failed to build with `Build input file cannot be found:
119
+ '.../Entitlements-merged.entitlements'. Did you forget to declare this
120
+ file as an output of a script phase...?` — confirmed live against
121
+ `ledger`. Fixed by using `<<` instead of `push` in both phases' injection
122
+ code. Added regression coverage asserting the phase is genuinely present
123
+ in `project.objects`, not just the `build_phases` array — the exact
124
+ distinction `push` silently violated.
125
+
126
+ ## 0.4.2
127
+
128
+ ### Fixed
129
+ - **0.4.1's fix for "Cycle inside Runner" was incomplete — the cycle could
130
+ still occur.** Declaring `input_paths` on `[CP] Check Pods Manifest.lock`'s
131
+ own output (0.4.1) correctly ordered `[ann-flavor] Merge Entitlements`/
132
+ `[ann-flavor] Merge Info.plist` after that one phase, but both were still
133
+ `unshift`ed to the very *front* of `build_phases`. Confirmed live (again,
134
+ against `ledger`) that the real cycle ran through a longer chain: these
135
+ phases' outputs feed `ProcessProductPackaging` (entitlements/Info.plist
136
+ signing), which is gated behind a chain of Xcode task producers that the
137
+ Firebase framework-copy phases are *also* gated behind — being first in
138
+ `build_phases` put both on the same shared gate from opposite directions,
139
+ a genuine cycle no single `input_paths` declaration could resolve.
140
+ `CODE_SIGN_ENTITLEMENTS`/`INFOPLIST_FILE` are only consumed at packaging/
141
+ signing time, which is late in the build — neither phase has any real
142
+ reason to run before `Sources`/`Frameworks`/`Resources`/`Embed Frameworks`
143
+ at all. Fixed by appending both phases at the **end** of `build_phases`
144
+ instead of unshifting them to the front (`input_paths` from 0.4.1 kept as
145
+ belt-and-suspenders). Also now unconditionally repositions the phase to
146
+ the end even when it already exists from a prior install — a project that
147
+ picked up the incomplete 0.4.1 fix needs this to actually move it on the
148
+ next `pod install`, not just leave it in place.
149
+
150
+ ## 0.4.1
151
+
152
+ ### Fixed
153
+ - **`pod install`/Xcode build failed with "Cycle inside Runner; building
154
+ could produce unreliable results"** against a real project with real
155
+ CocoaPods frameworks (confirmed live: Firebase). The `[ann-flavor] Merge
156
+ Entitlements` and `[ann-flavor] Merge Info.plist` build phases (0.3.0/
157
+ 0.4.0) declared `output_paths` but no `input_paths`, so nothing told
158
+ Xcode's new build system these phases must run after CocoaPods' own
159
+ `[CP] Check Pods Manifest.lock` phase — `build_phases.unshift` only
160
+ controls list order, which CocoaPods' own installer reorders after this
161
+ Podfile hook runs anyway. Fixed by declaring `input_paths =
162
+ ['$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt']` on both
163
+ phases, matching Check Pods Manifest.lock's own declared output — Xcode
164
+ now has an explicit dependency to resolve the ordering, rather than a
165
+ cycle its scheduler was resolving incorrectly.
166
+
167
+ ## 0.4.0
168
+
169
+ ### Added
170
+ - **New `[ann-flavor] Merge Entitlements` build phase composes the final
171
+ `.entitlements` file Xcode signs with at build time**, not sync time: copies
172
+ `ios/Runner/Runner.entitlements` (the generic/base layer, developer-owned —
173
+ if present; unlike `Runner/Info.plist`, most projects have no stock
174
+ entitlements file at all, so a missing base file here starts from an empty
175
+ plist rather than failing), then merges in every key from the current
176
+ flavor's `ann/Entitlements/<flavor>.entitlements` delta (see
177
+ `ann_flutter_flavor` 1.3.0 — that file now holds only the flavor's
178
+ `entitlements:` cascade, not a full copy of `Runner.entitlements`), with the
179
+ flavor's value winning on any key both define. Uses `PlistBuddy`, mirroring
180
+ `[ann-flavor] Merge Info.plist` (0.3.0) exactly — entitlements files and
181
+ Info.plist are both plain Apple XML property lists, so the same
182
+ type-preserving merge logic applies unchanged. Injected only when at least
183
+ one flavor actually needs entitlements (its own cascade, or a stock
184
+ `Runner.entitlements`); removed automatically once nothing needs it anymore.
185
+
186
+ ### Changed
187
+ - **`CODE_SIGN_ENTITLEMENTS` now points at
188
+ `$(DERIVED_FILE_DIR)/Entitlements-merged.entitlements`** (the Merge
189
+ Entitlements phase's output above) instead of directly at
190
+ `ann/Entitlements/<flavor>.entitlements`, whenever anything needs signing —
191
+ extends the same `INFOPLIST_FILE` rewiring from 0.3.0 to entitlements. See
192
+ [plan 039](../../docs/03-planning/features/039-entitlements-build-time-merge.md)
193
+ and the [Entitlements](../../docs/04-userguide/ios/overview.md#entitlements)
194
+ section of the iOS userguide for the full design.
195
+
196
+ ## 0.3.0
197
+
198
+ ### Added
199
+ - **New `[ann-flavor] Merge Info.plist` build phase composes the final
200
+ Info.plist Xcode builds against at build time**, not sync time: copies
201
+ `ios/Runner/Info.plist` (the generic/base layer, developer-owned, always
202
+ present) to `$(DERIVED_FILE_DIR)/Info-merged.plist`, then merges in every
203
+ key from the current flavor's `ios/ann/Info/Info-<flavor>.plist` delta (see
204
+ `ann_flutter_flavor` 1.2.0 — that file now holds only the flavor's
205
+ `info_plist:` cascade, not a full copy of `Runner/Info.plist`), with the
206
+ flavor's value winning on any key both define. Uses `PlistBuddy`
207
+ (`/usr/libexec/PlistBuddy`), not `python3`/`ruby` — ships as part of Xcode
208
+ itself, so this phase adds no dependency on any scripting runtime beyond
209
+ what Xcode already requires. Every plist value type (string, bool, integer,
210
+ real, array, nested dict — e.g. `SKAdNetworkItems`) round-trips correctly
211
+ through the merge, not just strings. Prints a one-line notice to the Xcode
212
+ build log for any key the flavor delta actually overrides, to make an
213
+ unintentional override easy to spot. Found-and-updated in place on a
214
+ re-run, same UUID-stability guarantee as the Firebase-copy and Print Build
215
+ Info phases.
216
+
217
+ ### Changed
218
+ - **`INFOPLIST_FILE` now points at `$(DERIVED_FILE_DIR)/Info-merged.plist`**
219
+ (the Merge Info.plist phase's output above) instead of directly at
220
+ `ios/ann/Info/Info-<flavor>.plist`. Enables `Runner/Info.plist` to remain a
221
+ live, always-consulted base layer instead of a one-time sync-time template
222
+ — the change this whole release exists to support. See
223
+ [plan 038](../../docs/03-planning/features/038-info-plist-build-time-merge.md)
224
+ and the [`Info.plist`
225
+ keys](../../docs/04-userguide/ios/overview.md#infoplist-keys) section of the
226
+ iOS userguide for the full design and migration notes.
227
+
228
+ ## 0.2.0
229
+
230
+ ### Added
231
+ - **Wires the new `entitlements:` schema field (see `ann_flutter_flavor`
232
+ 1.1.0) into the Xcode build.** When `ios/ann/Entitlements/<flavor>.entitlements`
233
+ exists on disk for a flavor, `configure_build_configuration` sets
234
+ `CODE_SIGN_ENTITLEMENTS` to it — the same find-or-create-by-name pattern
235
+ already used for `INFOPLIST_FILE`. `entitlements:` is opt-in (unlike
236
+ `info_plist`/the icon catalog, which every flavor always has): a flavor with
237
+ no generated entitlements file gets no `CODE_SIGN_ENTITLEMENTS` set at all,
238
+ and a stale value from a flavor's `entitlements:` being removed from
239
+ `annspec.yaml` is explicitly cleared on the next `pod install` rather than
240
+ left as a dangling, build-breaking reference to a file that no longer
241
+ exists. `CODE_SIGN_ENTITLEMENTS` is also added to `PROJECT_LEVEL_EXCLUDED_KEYS`
242
+ (same shadowing risk as `INFOPLIST_FILE`/`PRODUCT_BUNDLE_IDENTIFIER`).
243
+
244
+ ## 0.1.39
245
+
246
+ ### Fixed
247
+ - **Real bug: the Firebase copy phase and `[ann-flavor] Print Build Info` phase
248
+ were both delete-and-recreated on every single `pod install`, each getting a
249
+ fresh UUID even when their content never changed.** `reject!`/manual removal
250
+ only dropped the old phase from `target.build_phases` (an `ObjectList`) —
251
+ the object itself stayed registered in the project's global objects table
252
+ (`objects_by_uuid`) forever, since only `ObjectList#delete` (not plain
253
+ `Array#reject!`) reference-counts and fully unregisters an object. This
254
+ permanently grew `project.pbxproj` by one orphaned, unreferenced build-phase
255
+ object per phase per `pod install` — confirmed via a real object-count diff
256
+ across two consecutive runs with zero actual configuration change. Both
257
+ phases are now found-or-updated in place (reusing the existing object's
258
+ UUID when found) instead of unconditionally removed and recreated; the
259
+ find-and-delete step itself now uses `ObjectList#delete` so any already-
260
+ orphaned phase from a prior gem version is still cleaned up correctly.
261
+ - `project.pbxproj` is also no longer rewritten on a `pod install` with no
262
+ real change: `save_if_changed` (already used for `.xcscheme` files) renders
263
+ what `Xcodeproj::Project#save` would write and compares against disk first,
264
+ skipping the write entirely when identical.
265
+
266
+ ### Changed
267
+ - `[ann-flavor] Print Build Info`'s output uses plain ASCII markers (`==`,
268
+ `-`) instead of emoji. Cosmetic only, but fixes a real Nanaimo (Xcodeproj's
269
+ pbxproj serializer) nondeterminism: the same emoji byte sequence could be
270
+ written as raw UTF-8 or as a `\u{...}` escape depending on the string
271
+ object's history, defeating the new byte-comparison skip-write check above
272
+ even when the underlying config was genuinely unchanged.
273
+
274
+ ## 0.1.38
275
+
276
+ ### Fixed
277
+ - **Real bug: every `pod install` (and every Studio Upgrade run) appended a
278
+ fresh, duplicate `BuildActionEntry` to each flavor's `.xcscheme`, forever.**
279
+ Xcodeproj's `configure_with_targets` always appends a new build/test/launch
280
+ target entry rather than checking whether an equivalent one already
281
+ exists, and `configure_scheme` called it unconditionally on every run.
282
+ Confirmed against a real project: 16 duplicate `BuildActionEntry` blocks,
283
+ all pointing at the same `Runner` target, after repeated runs with no
284
+ actual configuration change in between. `configure_scheme` now skips
285
+ calling `configure_with_targets` when the scheme's build action already
286
+ has an entry for the target, and — more generally — skips writing the
287
+ `.xcscheme` file at all when the fully rebuilt scheme content is
288
+ byte-identical to what's already on disk, so a `pod install` with no real
289
+ change produces no file write and no git diff at all, not just no visible
290
+ duplication.
291
+
292
+ ## 0.1.37
293
+
294
+ ### Fixed
295
+ - **`MARKETING_VERSION` was never set on any per-flavor build configuration** —
296
+ confirmed against a real project that `flutter create`'s own stock
297
+ Debug/Release configs never set it either. `CURRENT_PROJECT_VERSION =
298
+ "$(FLUTTER_BUILD_NUMBER)"` is present on the stock template and gets copied
299
+ forward as a starting point for each per-flavor config, but there was never
300
+ an equivalent `MARKETING_VERSION` to copy along with it. This left
301
+ `$MARKETING_VERSION` (and therefore `CFBundleShortVersionString`, the
302
+ version shown in App Store Connect, and `[ann-flavor] Print Build Info`'s
303
+ own Version Name line) resolving empty. Now explicitly sets
304
+ `MARKETING_VERSION = "$(FLUTTER_BUILD_NAME)"` on every per-flavor
305
+ configuration, mirroring the existing `CURRENT_PROJECT_VERSION` bridge.
306
+
307
+ ## 0.1.36
308
+
309
+ ### Added
310
+ - **The Firebase plist copy step now also logs to `ios/build_info.log`**
311
+ (appended, since `[ann-flavor] Print Build Info` — which runs first —
312
+ overwrites that file earlier in the same build), recording exactly which
313
+ source plist was copied to which destination, or the specific error if the
314
+ expected source file wasn't found. Makes it possible to confirm which
315
+ flavor's Firebase config actually landed in the build without needing
316
+ Xcode's own build log or `flutter run -v`.
317
+
318
+ ## 0.1.35
319
+
320
+ ### Fixed
321
+ - **Real bug, present since Firebase plist wiring was first added: the copied
322
+ `GoogleService-Info.plist` was never actually packaged into the built
323
+ `.app`.** The pre-build script correctly copies the right flavor's plist to
324
+ `Runner/GoogleService-Info.plist` on disk, but nothing ever added that file
325
+ as a Copy Bundle Resources member — Xcode had no reason to bundle a file it
326
+ didn't know to include, even though it existed correctly in the source tree
327
+ the whole time. This is very likely the actual root cause behind
328
+ `[core/no-app] No Firebase App '[DEFAULT]' has been created` crashes on iOS
329
+ that this session mistakenly (though not wrongly, given evidence at the
330
+ time) attributed only to the plist-deletion race fixed in 0.1.33 — that fix
331
+ was real and necessary, but incomplete. Now finds-or-creates a file
332
+ reference for `Runner/GoogleService-Info.plist` and adds it to the target's
333
+ Resources build phase, mirroring the pattern `find_or_create_icon_catalog`
334
+ already uses for `Assets.xcassets`. Verified directly against a real
335
+ project's `Runner.xcodeproj` — confirmed the file is now a genuine Copy
336
+ Bundle Resources member after `pod install`.
337
+
338
+ ## 0.1.34
339
+
340
+ ### Added
341
+ - **`[ann-flavor] Print Build Info` now also writes to `ios/build_info.log`**
342
+ (relative to the project root, overwritten fresh on every build), not just
343
+ `echo`ed into the Xcode build log. `flutter run` doesn't stream Xcode
344
+ script-phase output to the terminal by default (only `flutter run -v`
345
+ does), so this makes build/flavor info visible without that flag — e.g.
346
+ `tail -f ios/build_info.log` in a separate terminal while `flutter run` is
347
+ going. Add `ios/build_info.log` to `.gitignore` — it's a generated,
348
+ build-time file, not meant to be checked in.
349
+
350
+ ## 0.1.33
351
+
352
+ ### Fixed
353
+ - **Real bug, present since 0.1.18: the app could crash at launch with "No
354
+ Firebase App '[DEFAULT]' has been created" after a working build, with no
355
+ code change in between.** The Firebase plist wiring used a pre-build shell
356
+ script (copies the correct flavor's `GoogleService-Info.plist` into
357
+ `Runner/`) paired with a post-build script that deleted it again. 0.1.18
358
+ declared the pre-build script's `output_paths` to fix a *different* error
359
+ ("Build input file cannot be found"), but that combination is unsafe: once
360
+ Xcode's incremental build system considers the declared output already
361
+ satisfied, it can skip re-running the pre-build copy on a later build —
362
+ while the post-build phase had already deleted that same file at the end of
363
+ the previous build, permanently leaving `Runner/GoogleService-Info.plist`
364
+ (and therefore the shipped `.app`) without a Firebase config. Removed the
365
+ post-build deletion entirely; `ios/Runner/GoogleService-Info.plist` is
366
+ already gitignored, so leaving the last-built flavor's copy on disk between
367
+ builds is safe — the pre-build phase always overwrites it fresh before the
368
+ next real build regardless.
369
+
370
+ ### Changed
371
+ - **`[ann-flavor] Print Build Info` now prints the flavor key on its own
372
+ labeled line** (`Flavor: ledger_in`), instead of only appearing embedded
373
+ inside `Build Type` (`$CONFIGURATION`, e.g. `Debug-ledger_in`).
374
+
375
+ ## 0.1.32
376
+
377
+ ### Fixed
378
+ - Corrected the `RunnerTests` `SWIFT_VERSION` fix from 0.1.30/0.1.31: asserting
379
+ `SWIFT_VERSION` on a target's *existing* configurations wasn't sufficient.
380
+ `PBXNativeTarget#resolved_build_setting` (the API CocoaPods' own analysis uses)
381
+ resolves a target against every configuration name that exists anywhere in the
382
+ project, not just the target's own list — a name the target has no configuration for
383
+ resolves to `nil` rather than being skipped. `Runner` gets `Debug-<flavor>`/
384
+ `Release-<flavor>` configurations; `RunnerTests` didn't, so it resolved `SWIFT_VERSION`
385
+ to `nil` for every flavor name while `Runner` resolved to a real value — still failing
386
+ `pod install` even when `RunnerTests`'s own stock configurations were fully consistent
387
+ with each other. `configure_build_settings` now also mirrors every project-level
388
+ configuration name onto every native target it processes.
389
+ - Added `PodfileHelper.preflight_swift_version` (exposed as
390
+ `bundle exec ann-ios-flavorize preflight --project <dir>`), callable standalone with no
391
+ CocoaPods `installer` object needed. The fix above only runs from `pod install`'s
392
+ `post_integrate` hook, which — per CocoaPods' own `Pod::Installer#install!` call order
393
+ — only fires *after* the dependency-resolution/analysis phase that's rejecting the
394
+ project for inconsistent `SWIFT_VERSION`. A project that has never had a successful
395
+ `pod install` therefore failed before the `post_integrate` fix ever got a chance to
396
+ run. `preflight_swift_version` opens `.xcodeproj` directly and applies the same fix,
397
+ so it can run from a separate process (`ann_flutter_flavor sync`) *before*
398
+ `pod install` is ever invoked — unblocking a project's very first install too.
399
+
400
+ ## 0.1.31
401
+
402
+ ### Added
403
+ - `configure_build_settings` now fails `pod install` loudly for a flavor whose
404
+ `.appiconset` directory hasn't been generated yet, instead of silently shipping a build
405
+ with no app icon. `ASSETCATALOG_COMPILER_APPICON_NAME` is set unconditionally by `sync`
406
+ before "Generate App Icons" has necessarily run for a given flavor — without this check,
407
+ `pod install` succeeded silently and Xcode just couldn't find the named appiconset at
408
+ build time. The error names the missing flavor and the exact expected path.
409
+
410
+ ## 0.1.30
411
+
412
+ ### Fixed
413
+ - `configure_build_settings` now asserts `SWIFT_VERSION` (when `sdk.swift_version` is set)
414
+ on every native target's existing build configurations, not just the `:application`
415
+ target — fixes a `pod install` failure ("There may only be up to 1 unique SWIFT_VERSION
416
+ per target") caused by `RunnerTests` drifting out of sync with `Runner`'s per-flavor
417
+ configs, since this plugin never touched non-application targets before. No new
418
+ per-flavor configurations are created on non-application targets.
419
+ - `find_or_create_icon_catalog` now explicitly sets the `ann` group's `path` (`'ann'`) when
420
+ creating it. Previously the group was created with only a `name`, so its
421
+ `Assets.xcassets` file reference resolved to `ios/Assets.xcassets` instead of
422
+ `ios/ann/Assets.xcassets` — one directory up from where `ios_icon_generator.dart`
423
+ actually writes the generated per-flavor `.appiconset` content. Xcode couldn't find the
424
+ icon catalog at build time even though the generated files were correctly on disk.
425
+
426
+ ## 0.1.29
427
+
428
+ ### Fixed
429
+ - `AnnFlavorCore::AnnSpec#flavor_exists_on?(platform_key, flavor_key)` added to the shared core (`ann-flavor-core-ruby`, vendored into this gem at publish time). Core-only in this release — `PodfileHelper` does not call this method yet; no functional change to Podfile/xcconfig generation. Included here purely because this gem vendors the shared core's source and versions travel together.
430
+
431
+ ## 0.1.28
432
+
433
+ ### Fixed
434
+ - **`configure_build_settings`'s generated `XCBuildConfiguration`s were silently non-functional at real `xcodebuild` time**, despite passing every prior test (all of which only inspected the in-memory `Xcodeproj::Project` object model, never shelled out to real `xcodebuild`) — found via plan 035 STEP-2.11's real-project verification. Three distinct bugs, all now fixed:
435
+ - The `baseConfigurationReference`/`INFOPLIST_FILE` paths were constructed with a redundant `ios/` prefix (`"ios/ann/xcconfig/..."`), doubling to a nonexistent `ios/ios/ann/...` when resolved relative to `SRCROOT` (the `.xcodeproj`'s own containing directory) — the most severe of the three, since it meant every per-flavor xcconfig's `#include` chain silently never applied at all, and `xcodebuild -showBuildSettings` misleadingly echoed back the unresolved literal path string, making it look correct until checked against what the xcconfig actually set.
436
+ - New per-flavor configurations were registered only on the target's own `XCConfigurationList`, never the *project*-level one — `xcodebuild -configuration <name>` (and `-list`) only recognizes configuration names that exist at the project level; a target-only name is silently ignored, with `xcodebuild` falling back to the project's `defaultConfigurationName` instead.
437
+ - The "copy an existing configuration's settings as a starting point" convenience (both when creating the new target-level config and the new project-level one) copied Flutter's own stock `PRODUCT_BUNDLE_IDENTIFIER` placeholder along with it — a literal key in a configuration's own `buildSettings` dict always wins over a value pulled in via `baseConfigurationReference`, so this silently shadowed the correct per-flavor bundle ID no matter what the xcconfig itself said.
438
+ - 3 new regression tests, all verified end-to-end against a real, fresh `flutter create` project + real `pod install` + real `xcodebuild -showBuildSettings`, not just the existing in-memory object-model assertions (which had themselves been unknowingly asserting the buggy doubled-path output as correct).
439
+
440
+ ## 0.1.27
441
+
442
+ ### Fixed
443
+ - Dependency note above corrected: `ann-flavor-flutter` 1.0.8+ requirement is now satisfied — `flutter_package` reached 1.0.10+ generating `ios/ann/xcconfig/` and `ios/ann/Info/` in this same release cycle (plan 035 Phase 2 STEP-2.2). `configure_build_settings`'s generated build configurations now point at files that actually exist on disk from a fresh `sync` + `pod install`, not just a forward-compatible no-op.
444
+ - Verified end-to-end against `test-apps/sample_app`'s real `configure_build_settings_spec.rb` suite (11 tests against real `Xcodeproj::Project` objects, not mocks) — build-configuration creation, `INFOPLIST_FILE`/`ASSETCATALOG_COMPILER_APPICON_NAME` wiring, idempotency, the shared icon catalog reference, scheme creation and merge-preservation, and the Print Build Info phase all confirmed passing (plan 035 Phase 2 STEP-2.8).
445
+
446
+ ## 0.1.26
447
+
448
+ ### Added
449
+ - **Programmatic `project.pbxproj` build-configuration, scheme, and asset-catalog generator** (`PodfileHelper.configure_build_settings`, called automatically by `annai_ios_podfile_setup`): closes a previously-silent, undocumented manual Xcode step. For every iOS flavor x build type, `pod install` now creates/updates the `Debug-<flavor>`/`Release-<flavor>` `XCBuildConfiguration` (pointed at the generated `ios/ann/xcconfig/<Flavor><BuildType>.xcconfig`, `INFOPLIST_FILE` set to `ios/ann/Info/Info-<flavor>.plist`, `ASSETCATALOG_COMPILER_APPICON_NAME` set to `<Flavor>AppIcon`), the shared `ios/ann/Assets.xcassets` catalog reference, and a merge-if-exists `.xcscheme` per flavor (only the `buildConfiguration=` references are touched — manually added scheme content like environment variables and launch arguments is preserved). This also means a bare Dart-CLI + `pod install` workflow (no Studio/IDE plugin required) now produces a fully working multi-flavor Xcode project on its own. Everything is idempotent by construction (find-or-create by name), so re-running never duplicates configurations and always refreshes stale values. See [plan 035](https://github.com/anntech-dev/ann-flavor-tooling/blob/main/docs/03-planning/features/035-ios-flavor-architecture-redesign.md).
450
+ - **`[ann-flavor] Print Build Info` pre-build phase** — iOS parity with Android's `PreBuildProcessingTask`: prints resolved Build Type, App Name, App ID, Version Name, and Version Code before any compilation step, gated by `debug.print_build_and_flavor_info` (default on, same flag Android already uses).
451
+
452
+ **Requires `ann-flavor-flutter` 1.0.8+ generating `ios/ann/xcconfig/` and `ios/ann/Info/` files** (Phase 2 of plan 035, not yet released as of this version) for the referenced xcconfig/Info.plist paths to actually exist on disk — until then, the build configurations point at files that don't exist yet, which is expected and does not error at `pod install` time (only surfaces at actual Xcode build time). **Update (0.1.27):** this requirement is now satisfied — see below.
453
+
454
+ ## 0.1.25
455
+
456
+ ### Added
457
+ - `info_plist` schema field added to the shared core (`ann-flavor-core-ruby`, vendored into this plugin) — a new iOS-only field for raw `Info.plist` overrides, valid at `default`/`flavor`/`build_type` levels, as either an inline map or a file-path reference. Core-only in this release — `PodfileHelper` does not yet read or act on this field; `Info.plist` generation/patching remains unchanged. Included here purely because this plugin vendors the shared core and versions travel together.
458
+
459
+ ## 0.1.24
460
+
461
+ ### Added
462
+ - **iOS-only (non-Flutter) project support for `project_id`-mode Firebase**: the plugin now detects project layout once, at `pod install` time, by checking for `pubspec.yaml` at the project root. Flutter projects (pubspec.yaml present) keep resolving generated Firebase config files from `lib/generated/firebase/`, unchanged. Plain Xcode projects with no Flutter wrapper (pubspec.yaml absent) now resolve them from `ios/generated/firebase/` instead of incorrectly assuming a `lib/` directory that doesn't exist. `config_file` mode (an explicit path in `annspec.yaml`) is unaffected by this change on either layout. `ann-ios-flavorize setup` now prints which layout it detected (`Detected: Flutter project` / `Detected: iOS-only project`) and its error messages no longer assume a Flutter project when `annspec.yaml` or `ios/Podfile` is missing.
463
+
464
+ ## 0.1.23
465
+
466
+ ### Fixed
467
+ - Upgrading past 0.1.22 did not actually fix the `../../` path bug for any project that had already run `pod install` against an earlier version — `inject_build_phases`'s idempotency check only tested whether a phase carrying our marker text already existed, never whether its content matched the currently-installed gem. Once injected, a stale build phase was permanently baked into `project.pbxproj` and silently skipped on every later `pod install`, regardless of gem upgrades. The check now removes any existing `[ann-flavor] Copy Firebase plist` / `[ann-flavor] Remove Firebase plist` phases by name before re-adding fresh ones on every `post_integrate` run, so the injected script always matches the installed gem version. **Projects with a stale phase already baked in from a prior version must run `pod install` once with 0.1.23 to self-heal** — no manual `project.pbxproj` editing needed.
468
+
469
+ ## 0.1.22
470
+
471
+ ### Fixed
472
+ - 0.1.21 fixed which target the Firebase plist copy build phase runs in but left an off-by-one in the source path it computes — `"${SRCROOT}/../../#{plist_path}"` looked two directories above `$SRCROOT` (`<project_root>/ios`), landing one level *above* the Flutter project root, so the script failed with `Firebase plist not found` even though the file existed exactly where expected. `plist_path` is relative to the Flutter project root, and for the real `Runner` target `$SRCROOT` is `<project_root>/ios` — one level below it — so only a single `..` is needed. Fixed.
473
+
474
+ ## 0.1.21
475
+
476
+ ### Fixed
477
+ - The Firebase-config-file build phase injected by `PodfileHelper.configure_firebase` never actually ran against the app build, causing `Build input file cannot be found: '.../Runner/GoogleService-Info.plist'` — it was injected into `installer.pods_project`'s `Pods-Runner` target, CocoaPods' own generated aggregate target for building pod dependencies, never the real app project. Now injected into the real user project (`aggregate_target.user_project`, not `pods_project`) and the actual app target (identified by product type via `symbol_type == :application`, not a hardcoded name), with the project explicitly saved afterward. **Requires calling `configure_firebase` from your Podfile's `post_integrate` hook instead of `post_install`** — `post_install` fires before CocoaPods has integrated/saved the user project, so build phases added there are silently lost regardless of which project they're added to. ([#61](https://github.com/anntech-dev/ann-flavor-tooling/issues/61))
478
+
479
+ ## 0.1.20
480
+
481
+ ### Fixed
482
+ - `pod install` failed for every consumer with `cannot load such file -- ann_flavor_core` — the 0.1.19 core-delegation change added a hard `require 'ann_flavor_core'` in `PodfileHelper`, but `ann_flavor_core` is intentionally never published to RubyGems (ADR-008). The published gem now vendors `ann_flavor_core`'s source and resolves it automatically; local monorepo development is unaffected. ([#58](https://github.com/anntech-dev/ann-flavor-tooling/issues/58))
483
+
484
+ ## 0.1.19
485
+
486
+ ### Changed
487
+ - `PodfileHelper` now delegates `annspec.yaml` parsing and iOS bundle-ID/Firebase resolution to the shared `ann-flavor-core-ruby` gem ([ADR-008](../../docs/02-decisions/008-core-delegation-mandate.md)).
488
+
489
+ ### Fixed
490
+ - `configure_firebase` now resolves Firebase config files for `profile` builds in addition to `debug`/`release` — previously `profile`-build-type Firebase overrides in `annspec.yaml` were silently skipped.
491
+
492
+ ### Removed
493
+ - `PodfileHelper.bundle_id(flavor_key, ...)` (the build-type-agnostic bundle ID accessor, confirmed unused by any caller). Use `PodfileHelper.bundle_id_for_build_type(flavor_key, build_type, ...)` instead.
494
+
495
+ ## 0.1.18
496
+
497
+ ### Fixed
498
+ - **Build phase output declaration**: pre-build script phase now declares `$(SRCROOT)/Runner/GoogleService-Info.plist` as an `output_paths` entry. This tells Xcode's build system that the script produces the file, suppressing the "Build input file cannot be found" error that fired when the plist was listed in Copy Bundle Resources but did not yet exist on disk. Post-build cleanup phase declares the same path as `input_paths` to preserve the ordering dependency.
499
+
500
+ ## 0.1.17
501
+
502
+ ### Fixed
503
+ - **Issue #46**: Firebase plist build phase script now uses `${SRCROOT}/../../` instead of `${SRCROOT}/../` to correctly resolve paths relative to the project root. `${SRCROOT}` in the `Pods-Runner` target resolves to `ios/Pods`, so one extra `../` is required to reach the Flutter project root where `lib/generated/firebase/` lives.
504
+
505
+ ---
506
+
507
+ ## 0.1.16
508
+
509
+ ### Fixed
510
+ - Restored `project_root:` keyword arg on `configure_firebase`, `bundle_id`, and `bundle_id_for_build_type` for testability; defaults to auto-discovery via `find_spec_file` when not provided.
511
+
512
+ ---
513
+
514
+ ## 0.1.15
515
+
516
+ ### Fixed
517
+ - `annspec.yaml` is now discovered by walking up from `Dir.pwd` until the file is found, so the gem works standalone for iOS-only projects and as a Flutter plugin regardless of which directory `pod install` runs from. No hardcoded paths.
518
+
519
+ ---
520
+
521
+ ## 0.1.14
522
+
523
+ ### Fixed
524
+ - Added top-level `annai_ios_podfile_setup(installer)` method so Podfiles can call it directly in a `post_install` hook. Previously only `AnnFlavorCocoapods::PodfileHelper.configure_firebase` was exposed, causing `undefined method 'annai_ios_podfile_setup'`.
525
+
526
+ ---
527
+
528
+ ## 0.1.13
529
+
530
+ ### Fixed
531
+ - Added `lib/ann-flavor-cocoapods.rb` alias so CocoaPods can resolve `plugin 'ann-flavor-cocoapods'` under Ruby 3.4, where hyphenated gem names cannot be loaded via `require` directly.
532
+
533
+ ---
534
+
535
+ ## 0.1.12
536
+
537
+ ### Changed
538
+ - Version bump — no functional changes.
539
+
540
+ ---
541
+
542
+ ## 0.1.11
543
+
544
+ ### Fixed
545
+ - Added `lib/annai-flutter-flavor.rb` and `lib/ann-flavor-cocoapods.rb` aliases so legacy `require 'annai-flutter-flavor'` in Podfiles works under Ruby 3.4.
546
+
547
+ ---
548
+
549
+ ## 0.1.9
550
+
551
+ ### Added
552
+ - **DEF-019** (`target` field): Core-ruby now carries `target` on `FirebaseConfig` and cascades
553
+ it via `resolve_firebase` / `merge_firebase_config`. Version bump triggered by ADR-006 core-to-plugin rule.
554
+
555
+ ---
556
+
557
+ ## 0.1.8
558
+
559
+ ### Added
560
+ - **DEF-017**: `ann-ios-flavorize setup` CLI command for iOS-only (non-Flutter)
561
+ projects. Checks `annspec.yaml` exists, patches `ios/Podfile` with
562
+ `plugin 'ann-ios-flavorize'`, and prints next-step guidance. Idempotent —
563
+ safe to run multiple times. Install via `gem 'ann-flavor-cocoapods'` in your
564
+ Gemfile, then run `bundle exec ann-ios-flavorize setup`.
565
+
566
+ ### Fixed
567
+ - **DEF-014**: `configure_firebase` now injects build phases in `project_id` mode
568
+ (no `config_file` set). The plist source is derived from
569
+ `lib/generated/firebase/GoogleService-Info-{flavor}-{buildType}.plist`.
570
+ Previously no build phases were injected, causing the Crashlytics dSYM upload
571
+ run script to fail with a missing plist error.
572
+
573
+ ---
574
+
575
+ ## 0.1.7
576
+
577
+ **Backwards-compatibility shims removed** — the deprecated `firebase.file` fallback
578
+ and `firebase_token_file` are no longer accepted. Specs must use `config_file` and
579
+ `service_account` directly.
580
+
581
+ **`service_account` support** — the `service_account` field is read from the spec
582
+ and exported as `GOOGLE_APPLICATION_CREDENTIALS` when invoking Firebase CLI commands.
583
+
584
+ ## 0.1.6
585
+
586
+ **`enabled: false` support** — when `annspec.yaml` sets `enabled: false`, the
587
+ CocoaPods plugin skips all configuration silently.
588
+
589
+ **Improved error messages** — field validation errors now include the exact YAML path
590
+ and a fix hint.
591
+
592
+ ## 0.1.5
593
+
594
+ **Breaking: `annai_app:` root key renamed to `app:`** — `annspec.yaml` files using
595
+ the old `annai_app:` root key must be updated.
596
+
597
+ ## 0.1.4
598
+
599
+ **Firebase `config_file` support** — the podfile helper now reads the `config_file`
600
+ field. The old `file` field is accepted with a deprecation warning; support will be
601
+ removed in a future version.
602
+
603
+ **Firebase `path` / `firebase_app_id` / `build_target` removed** — replaced by
604
+ `config_file` and `project_id`.
605
+
606
+ ## 0.1.3
607
+
608
+ **Schema restructure** — credentials and sdk fields reorganised to match the updated
609
+ `annspec.yaml` structure.
610
+
611
+ ## 0.1.2
612
+
613
+ Documentation and sync-workflow updates. No user-facing behaviour changes.
614
+
615
+ ## 0.1.1
616
+
617
+ Initial release.