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.
- package/CLAUDE.md +94 -0
- package/README.md +417 -0
- package/action/.daemux-version +1 -0
- package/action/MIGRATION.md +232 -0
- package/action/action.yml +973 -0
- package/action/prompts/generate_dependent_fields.prompt.yml +78 -0
- package/action/prompts/generate_descriptions.prompt.yml +59 -0
- package/action/scripts/app_context_scanner.py +239 -0
- package/action/scripts/asc_build_history.py +284 -0
- package/action/scripts/asc_common.py +246 -0
- package/action/scripts/asc_metadata_applier.py +368 -0
- package/action/scripts/asc_metadata_detector.py +250 -0
- package/action/scripts/asc_version_create.py +365 -0
- package/action/scripts/asc_version_fetch.py +274 -0
- package/action/scripts/asc_version_reuse.py +177 -0
- package/action/scripts/auto_detect.py +391 -0
- package/action/scripts/autoupdate_check.sh +118 -0
- package/action/scripts/cert_factory.py +190 -0
- package/action/scripts/cfg_io.py +27 -0
- package/action/scripts/cfg_resolve.py +147 -0
- package/action/scripts/commit_bot_changes.sh +82 -0
- package/action/scripts/creds_store.py +328 -0
- package/action/scripts/keychain.py +103 -0
- package/action/scripts/lookup_app_id.py +51 -0
- package/action/scripts/manage_marketing_version.py +337 -0
- package/action/scripts/metadata_constants.py +102 -0
- package/action/scripts/mmv_decide_create.py +181 -0
- package/action/scripts/mmv_floor_check.py +265 -0
- package/action/scripts/next_build_number.py +195 -0
- package/action/scripts/pbxproj_editor.py +220 -0
- package/action/scripts/prepare_signing.py +223 -0
- package/action/scripts/profile_io.py +64 -0
- package/action/scripts/profile_manager.py +307 -0
- package/action/scripts/read_config.py +315 -0
- package/action/scripts/resolve_marketing_version.py +173 -0
- package/action/scripts/set_app_store_whats_new.py +317 -0
- package/action/scripts/team_resolver.py +130 -0
- package/action/scripts/test_app_context_scanner.py +167 -0
- package/action/scripts/test_asc_build_history.py +221 -0
- package/action/scripts/test_asc_builds_prerelease.py +219 -0
- package/action/scripts/test_asc_common_timeouts.py +121 -0
- package/action/scripts/test_asc_metadata_applier.py +850 -0
- package/action/scripts/test_asc_metadata_detector.py +445 -0
- package/action/scripts/test_auto_detect.py +432 -0
- package/action/scripts/test_cfg_resolve_credentials.py +48 -0
- package/action/scripts/test_compute_next_version.py +95 -0
- package/action/scripts/test_compute_next_version_patch_backcompat.py +41 -0
- package/action/scripts/test_compute_next_version_strictness.py +67 -0
- package/action/scripts/test_fetch_versions.py +163 -0
- package/action/scripts/test_ground_truth_floor.py +104 -0
- package/action/scripts/test_manage_marketing_version.py +134 -0
- package/action/scripts/test_manage_marketing_version_autoroll.py +149 -0
- package/action/scripts/test_manage_marketing_version_floor.py +170 -0
- package/action/scripts/test_manage_marketing_version_match.py +187 -0
- package/action/scripts/test_mmv_409_classifier.py +231 -0
- package/action/scripts/test_mmv_autobump_persist_gate.py +131 -0
- package/action/scripts/test_mmv_decide_create.py +119 -0
- package/action/scripts/test_mmv_floor_check.py +158 -0
- package/action/scripts/test_mmv_floor_crosscheck.py +132 -0
- package/action/scripts/test_mmv_helpers.py +57 -0
- package/action/scripts/test_next_build_number.py +174 -0
- package/action/scripts/test_read_config_auto_detect.py +257 -0
- package/action/scripts/test_resolve_marketing_version.py +298 -0
- package/action/scripts/test_reuse_stale_editable.py +182 -0
- package/action/scripts/test_set_app_store_whats_new.py +71 -0
- package/action/scripts/test_team_fallback_wiring.py +157 -0
- package/action/scripts/test_team_resolver.py +249 -0
- package/action/scripts/tests_common.py +167 -0
- package/action/scripts/version_utils.py +373 -0
- package/android-action/.daemux-version +1 -0
- package/android-action/action.yml +92 -0
- package/android-action/scripts/android_config.py +130 -0
- package/android-action/scripts/bitrise_deploy.py +160 -0
- package/android-action/scripts/find_bundle.py +25 -0
- package/android-action/scripts/play_preflight.py +69 -0
- package/android-action/scripts/resolve_android.py +70 -0
- package/android-action/scripts/sign_bundle.py +70 -0
- package/android-action/scripts/test_android_config.py +97 -0
- package/android-action/scripts/test_bitrise_deploy.py +124 -0
- package/android-action/scripts/test_sign_bundle.py +82 -0
- package/bin/cli.mjs +63 -0
- package/package.json +57 -0
- package/src/install.mjs +208 -0
- 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.
|