gowalk-cicd 1.0.0

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.
Files changed (84) hide show
  1. package/CLAUDE.md +94 -0
  2. package/README.md +417 -0
  3. package/action/.daemux-version +1 -0
  4. package/action/MIGRATION.md +232 -0
  5. package/action/action.yml +973 -0
  6. package/action/prompts/generate_dependent_fields.prompt.yml +78 -0
  7. package/action/prompts/generate_descriptions.prompt.yml +59 -0
  8. package/action/scripts/app_context_scanner.py +239 -0
  9. package/action/scripts/asc_build_history.py +284 -0
  10. package/action/scripts/asc_common.py +246 -0
  11. package/action/scripts/asc_metadata_applier.py +368 -0
  12. package/action/scripts/asc_metadata_detector.py +250 -0
  13. package/action/scripts/asc_version_create.py +365 -0
  14. package/action/scripts/asc_version_fetch.py +274 -0
  15. package/action/scripts/asc_version_reuse.py +177 -0
  16. package/action/scripts/auto_detect.py +391 -0
  17. package/action/scripts/autoupdate_check.sh +118 -0
  18. package/action/scripts/cert_factory.py +190 -0
  19. package/action/scripts/cfg_io.py +27 -0
  20. package/action/scripts/cfg_resolve.py +147 -0
  21. package/action/scripts/commit_bot_changes.sh +82 -0
  22. package/action/scripts/creds_store.py +328 -0
  23. package/action/scripts/keychain.py +103 -0
  24. package/action/scripts/lookup_app_id.py +51 -0
  25. package/action/scripts/manage_marketing_version.py +337 -0
  26. package/action/scripts/metadata_constants.py +102 -0
  27. package/action/scripts/mmv_decide_create.py +181 -0
  28. package/action/scripts/mmv_floor_check.py +265 -0
  29. package/action/scripts/next_build_number.py +195 -0
  30. package/action/scripts/pbxproj_editor.py +220 -0
  31. package/action/scripts/prepare_signing.py +223 -0
  32. package/action/scripts/profile_io.py +64 -0
  33. package/action/scripts/profile_manager.py +307 -0
  34. package/action/scripts/read_config.py +315 -0
  35. package/action/scripts/resolve_marketing_version.py +173 -0
  36. package/action/scripts/set_app_store_whats_new.py +317 -0
  37. package/action/scripts/team_resolver.py +130 -0
  38. package/action/scripts/test_app_context_scanner.py +167 -0
  39. package/action/scripts/test_asc_build_history.py +221 -0
  40. package/action/scripts/test_asc_builds_prerelease.py +219 -0
  41. package/action/scripts/test_asc_common_timeouts.py +121 -0
  42. package/action/scripts/test_asc_metadata_applier.py +850 -0
  43. package/action/scripts/test_asc_metadata_detector.py +445 -0
  44. package/action/scripts/test_auto_detect.py +432 -0
  45. package/action/scripts/test_cfg_resolve_credentials.py +48 -0
  46. package/action/scripts/test_compute_next_version.py +95 -0
  47. package/action/scripts/test_compute_next_version_patch_backcompat.py +41 -0
  48. package/action/scripts/test_compute_next_version_strictness.py +67 -0
  49. package/action/scripts/test_fetch_versions.py +163 -0
  50. package/action/scripts/test_ground_truth_floor.py +104 -0
  51. package/action/scripts/test_manage_marketing_version.py +134 -0
  52. package/action/scripts/test_manage_marketing_version_autoroll.py +149 -0
  53. package/action/scripts/test_manage_marketing_version_floor.py +170 -0
  54. package/action/scripts/test_manage_marketing_version_match.py +187 -0
  55. package/action/scripts/test_mmv_409_classifier.py +231 -0
  56. package/action/scripts/test_mmv_autobump_persist_gate.py +131 -0
  57. package/action/scripts/test_mmv_decide_create.py +119 -0
  58. package/action/scripts/test_mmv_floor_check.py +158 -0
  59. package/action/scripts/test_mmv_floor_crosscheck.py +132 -0
  60. package/action/scripts/test_mmv_helpers.py +57 -0
  61. package/action/scripts/test_next_build_number.py +174 -0
  62. package/action/scripts/test_read_config_auto_detect.py +257 -0
  63. package/action/scripts/test_resolve_marketing_version.py +298 -0
  64. package/action/scripts/test_reuse_stale_editable.py +182 -0
  65. package/action/scripts/test_set_app_store_whats_new.py +71 -0
  66. package/action/scripts/test_team_fallback_wiring.py +157 -0
  67. package/action/scripts/test_team_resolver.py +249 -0
  68. package/action/scripts/tests_common.py +167 -0
  69. package/action/scripts/version_utils.py +373 -0
  70. package/android-action/.daemux-version +1 -0
  71. package/android-action/action.yml +92 -0
  72. package/android-action/scripts/android_config.py +130 -0
  73. package/android-action/scripts/bitrise_deploy.py +160 -0
  74. package/android-action/scripts/find_bundle.py +25 -0
  75. package/android-action/scripts/play_preflight.py +69 -0
  76. package/android-action/scripts/resolve_android.py +70 -0
  77. package/android-action/scripts/sign_bundle.py +70 -0
  78. package/android-action/scripts/test_android_config.py +97 -0
  79. package/android-action/scripts/test_bitrise_deploy.py +124 -0
  80. package/android-action/scripts/test_sign_bundle.py +82 -0
  81. package/bin/cli.mjs +63 -0
  82. package/package.json +57 -0
  83. package/src/install.mjs +208 -0
  84. package/templates/deploy.yml +150 -0
@@ -0,0 +1,232 @@
1
+ # Migration: project-owned MARKETING_VERSION
2
+
3
+ ## Symptom
4
+
5
+ CI runs of the `ios-native-testflight` composite action used to bump the
6
+ marketing version on every TestFlight upload, even when the consumer
7
+ project's `MARKETING_VERSION` build setting (or `Info.plist`'s
8
+ `CFBundleShortVersionString`) had not changed. Across consecutive runs
9
+ the marketing version would drift upward in App Store Connect:
10
+
11
+ ```
12
+ project.yml MARKETING_VERSION: "1.0.0"
13
+ CI run #16 -> TestFlight 1.0.7 (16)
14
+ CI run #17 -> TestFlight 1.0.8 (17)
15
+ CI run #18 -> TestFlight 1.0.9 (18)
16
+ CI run #19 -> TestFlight 1.1.0 (19)
17
+ CI run #20 -> TestFlight 1.1.1 (20)
18
+ ```
19
+
20
+ The bumped value never round-tripped to the consumer repo (zero
21
+ "bump version" commits in the project's git log) — each run started
22
+ from `MARKETING_VERSION: "1.0.0"` again. This was confusing for users
23
+ ("why does my TestFlight build claim to be 1.1.1 when my project says
24
+ 1.0.0?") and produced unintended user-visible version numbers.
25
+
26
+ ## Cause
27
+
28
+ The previous version of `manage_marketing_version.py` computed
29
+ `next = combined_floor + patch` on every CI run, treating App Store
30
+ Connect prerelease history as the source of truth. Because the project
31
+ itself never told CI which marketing version the user wanted to ship,
32
+ the script had to guess — and it guessed by walking forward from the
33
+ floor it discovered server-side. With every successful upload, the
34
+ floor moved up; the guess walked further forward; the project-side
35
+ value stayed at 1.0.0 indefinitely.
36
+
37
+ ## Fix
38
+
39
+ The action now treats the project's `MARKETING_VERSION` build setting
40
+ (or `Info.plist`'s `CFBundleShortVersionString`) as the **single source
41
+ of truth**. CI never bumps it. CI only bumps the build number (still
42
+ handled automatically via `next_build_number.py`).
43
+
44
+ When CI starts a release run it now:
45
+
46
+ 1. Resolves `MARKETING_VERSION` from the project via
47
+ `xcodebuild -showBuildSettings`, falling back to PlistBuddy on
48
+ `CFBundleShortVersionString` when the build setting is absent.
49
+ 2. Refuses the build if the resolved value is missing or non-semver
50
+ (must match `^\d+\.\d+(\.\d+)?$`). The error message names the
51
+ build-setting sources you can edit.
52
+ 3. Compares the resolved value to the App Store Connect floor (max
53
+ of `appStoreVersions`, `preReleaseVersions`, and
54
+ `builds->preReleaseVersion`):
55
+ - **REUSE path**: target ≥ floor is allowed. Equality with the
56
+ floor is the steady-state TestFlight case where the editable
57
+ row at the target IS the floor source — uploading another
58
+ build at the same marketing version with a higher build
59
+ number is the whole point.
60
+ - **CREATE path**: target > floor is required (strict). A new
61
+ row at-or-below the floor would collide with already-shipped
62
+ or in-flight versions.
63
+ 4. Finds-or-creates the App Store Connect row at exactly that
64
+ versionString:
65
+ - If an editable row already exists at the target → REUSE it.
66
+ - If a non-editable row exists at the target (shipped, in
67
+ review, etc.) → refuse with a clear error.
68
+ - If no row exists at the target → POST a new one, OR PATCH-
69
+ rename a leftover lower-version editable to the target (see
70
+ "Stale-editable rename" below).
71
+
72
+ ## Stale-editable rename
73
+
74
+ When the developer bumps `MARKETING_VERSION` (e.g., 1.0.0 → 1.1.0)
75
+ and there's a leftover editable App Store version at the OLD value
76
+ (1.0.0 `PREPARE_FOR_SUBMISSION`, never finalized), the action will
77
+ PATCH-rename that editable to the new target. This is the correct
78
+ behaviour: the developer has explicitly chosen a new marketing
79
+ version, so promoting the leftover draft to match their intent
80
+ avoids ASC's "single editable per app" 409 collision.
81
+
82
+ The rename is **only** applied when the existing editable's
83
+ versionString is **strictly less than** the target. If the existing
84
+ editable is at a versionString **>= the target** (e.g., editable at
85
+ 1.2.0, target=1.1.0), the action refuses with `SystemExit(2)`.
86
+ PATCH-renaming a higher-version editable would silently downgrade
87
+ an in-progress draft, which is never what the developer wants.
88
+
89
+ ## How to migrate
90
+
91
+ Pick the section that matches your project layout.
92
+
93
+ ### xcodegen (project.yml)
94
+
95
+ If your repo uses `project.yml` and (re)generates `.xcodeproj` in CI:
96
+
97
+ ```yaml
98
+ # project.yml
99
+ name: MyApp
100
+ options:
101
+ bundleIdPrefix: com.example
102
+ settings:
103
+ base:
104
+ MARKETING_VERSION: "1.1.2" # <-- bump this when you want a release
105
+ CURRENT_PROJECT_VERSION: "1" # CI overrides this anyway
106
+ ```
107
+
108
+ When you decide to ship a new release, edit `MARKETING_VERSION`,
109
+ commit, push, and let CI take over. CI never edits this file.
110
+
111
+ ### Traditional .xcodeproj (committed Xcode project)
112
+
113
+ Two options. Pick whichever matches how your project is structured:
114
+
115
+ **Option A — `MARKETING_VERSION` build setting in xcconfig or pbxproj:**
116
+
117
+ In Xcode: `Project > Build Settings`, search for `Marketing Version`,
118
+ edit the value. Or edit your `.xcconfig` directly:
119
+
120
+ ```text
121
+ // Config/Release.xcconfig
122
+ MARKETING_VERSION = 1.1.2
123
+ ```
124
+
125
+ **Option B — `CFBundleShortVersionString` literal in `Info.plist`:**
126
+
127
+ If your project uses literal values in `Info.plist` instead of
128
+ `$(MARKETING_VERSION)` substitution, edit the plist:
129
+
130
+ ```xml
131
+ <key>CFBundleShortVersionString</key>
132
+ <string>1.1.2</string>
133
+ ```
134
+
135
+ The action looks at `MARKETING_VERSION` first. If that build setting
136
+ is empty or unset, it falls back to reading
137
+ `CFBundleShortVersionString` from the resolved `Info.plist`.
138
+
139
+ ## Recovery for projects already drifted by old CI
140
+
141
+ If your `MARKETING_VERSION` in the repo is *behind* the App Store
142
+ Connect floor (because earlier CI runs server-side-bumped past it),
143
+ the new action will exit 2 with a message like:
144
+
145
+ ```
146
+ ::error::MARKETING_VERSION 1.0.0 in your project's build settings
147
+ (typically project.yml [xcodegen], the .xcodeproj's MARKETING_VERSION
148
+ xcconfig, or Info.plist's CFBundleShortVersionString) must be strictly
149
+ greater than the App Store Connect floor 1.1.1. Bump it (e.g. to
150
+ 1.1.2), commit, and rerun. ...
151
+ ```
152
+
153
+ Recovery (verbatim, from `gowalk-public/vpn-swift-tempalte`):
154
+
155
+ 1. Edit `project.yml`: change `MARKETING_VERSION: "1.0.0"` to
156
+ `MARKETING_VERSION: "1.1.2"` (or whatever the suggested bump is).
157
+ 2. (Optional) Run `xcodegen generate` if the repo commits
158
+ `.xcodeproj`; otherwise CI's xcodegen step handles it.
159
+ 3. `git add project.yml && git commit -m "Bump MARKETING_VERSION to 1.1.2"`
160
+ 4. `git push origin main`
161
+ 5. The next CI run will produce TestFlight `1.1.2 (22)` (or whatever
162
+ your auto-incremented build number happens to be).
163
+
164
+ For traditional `.xcodeproj` projects, replace step 1 with editing the
165
+ appropriate `.xcconfig` or `Info.plist` (see "How to migrate" above)
166
+ and step 2 with no-op (Xcode reads the build setting directly).
167
+
168
+ ## Failure modes
169
+
170
+ CI surfaces `SystemExit(2)` errors for the following anomalies. Each
171
+ error message points to this document and names the build-setting
172
+ sources you can edit.
173
+
174
+ ### 1. Floor too high
175
+
176
+ ```
177
+ ::error::MARKETING_VERSION 1.0.0 ... must be strictly greater than the
178
+ App Store Connect floor 1.1.1. ...
179
+ Sources contributing to floor: appStoreVersions=..., preReleaseVersions=...,
180
+ buildsViaPreRelease=...
181
+ ```
182
+
183
+ **Cause**: an earlier upload (often by a different developer or a
184
+ previous CI run from before this fix) pushed a version higher than
185
+ your project's value into App Store Connect.
186
+
187
+ **Resolution**: bump `MARKETING_VERSION` in your project to a value
188
+ strictly greater than the floor named in the per-source breakdown,
189
+ commit, and push.
190
+
191
+ ### 2. Higher editable exists
192
+
193
+ ```
194
+ ::error::Cannot CREATE MARKETING_VERSION 1.1.0: an editable App Store
195
+ version exists at 1.2.0 (id=..., state=PREPARE_FOR_SUBMISSION).
196
+ Renaming a higher or equal-version editable would downgrade an
197
+ in-progress draft. ...
198
+ ```
199
+
200
+ **Cause**: a future-train draft already exists in App Store Connect
201
+ at a higher version than your project's `MARKETING_VERSION`. CI
202
+ refuses to PATCH-rename it down to your target.
203
+
204
+ **Resolution**: either bump `MARKETING_VERSION` in your project to
205
+ ≥ the editable's version (matching the existing draft), OR manually
206
+ delete or rename the existing draft in App Store Connect.
207
+
208
+ ### 3. Duplicate versionString already shipped
209
+
210
+ ```
211
+ ::error::MARKETING_VERSION 1.0.0 already exists in App Store Connect
212
+ in state READY_FOR_SALE (id=...). REUSE/CREATE both require a fresh
213
+ marketing version. ...
214
+ ```
215
+
216
+ **Cause**: the project's `MARKETING_VERSION` matches a row that is
217
+ already shipped (or in review, awaiting release, etc.) — not an
218
+ editable draft.
219
+
220
+ **Resolution**: bump `MARKETING_VERSION` past the shipped version.
221
+ The version slot is taken; you must ship a fresh marketing version.
222
+
223
+ ## Quick checklist
224
+
225
+ - [ ] `project.yml` (or `.xcconfig` / `Info.plist`) carries the
226
+ desired marketing version.
227
+ - [ ] If CI exits with "floor too high", bump above the floor.
228
+ - [ ] If CI exits with "higher editable exists", either bump to
229
+ match the existing draft, or delete the draft in ASC.
230
+ - [ ] If CI exits with "already exists in state X", bump past the
231
+ shipped version.
232
+ - [ ] Commit and push. CI takes it from there.