gowalk-cicd 1.0.167 → 1.0.169
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/README.md +125 -220
- package/action/action.yml +59 -362
- package/action/scripts/auto_detect.py +39 -60
- package/action/scripts/commit_bot_changes.sh +3 -26
- package/action/scripts/creds_store.py +10 -91
- package/action/scripts/mobile_artifact_files.py +14 -3
- package/action/scripts/mobile_artifact_inventory.cjs +32 -19
- package/action/scripts/mobile_inputs.cjs +6 -4
- package/action/scripts/native_cache.py +5 -1
- package/action/scripts/native_pods.py +44 -15
- package/action/scripts/native_pods_diagnostics.py +18 -3
- package/action/scripts/native_pods_process.py +5 -0
- package/action/scripts/prepare_crashlytics_build.py +22 -5
- package/action/scripts/prepare_signing.py +4 -6
- package/action/scripts/profile_manager.py +74 -165
- package/action/scripts/resolve_info_plist.py +7 -2
- package/action/scripts/resolve_marketing_version.py +9 -1
- package/action/scripts/set_app_store_whats_new.py +3 -4
- package/action/scripts/version_utils.py +17 -7
- package/android-action/action.yml +6 -8
- package/android-action/flutter-setup/action.yml +46 -7
- package/android-action/scripts/android_build_diagnostics.py +53 -27
- package/android-action/scripts/crashlytics_symbols.py +4 -0
- package/android-action/scripts/sign_bundle.py +10 -7
- package/backend-action/action.yml +41 -46
- package/backend-action/configure_vhost.py +39 -21
- package/backend-action/edge_vhost.py +7 -7
- package/backend-action/ensure_certificate.sh +66 -186
- package/backend-action/remote_deploy.sh +55 -23
- package/bin/cli.mjs +3 -3
- package/docs/CANDIDATE_ARTIFACTS.md +20 -6
- package/docs/CONFIGURATION.md +3 -1
- package/docs/GRADLE_CACHE.md +8 -3
- package/package.json +16 -2
- package/src/config/build-steps.mjs +2 -1
- package/src/config/merge.mjs +29 -1
- package/src/config/transaction.mjs +8 -4
- package/src/config/validation.mjs +10 -1
- package/src/config/workflows.mjs +17 -1
- package/src/install.mjs +65 -37
- package/templates/deploy-backend.yml +8 -9
- package/templates/deploy.yml +90 -82
- package/templates/history.json.gz +0 -0
- package/templates/mobile-candidate.yml +1 -2
- package/action/prompts/generate_dependent_fields.prompt.yml +0 -78
- package/action/prompts/generate_descriptions.prompt.yml +0 -62
- package/action/scripts/app_context_scanner.py +0 -239
- package/action/scripts/asc_metadata_applier.py +0 -432
- package/action/scripts/asc_metadata_detector.py +0 -250
- package/action/scripts/autoupdate_check.sh +0 -61
- package/action/scripts/autoupdate_stage.py +0 -62
- package/action/scripts/cert_factory.py +0 -102
- package/action/scripts/certificate_failure.py +0 -47
- package/action/scripts/fixtures/single-size-ios-icon.json +0 -38
- package/action/scripts/metadata_constants.py +0 -102
- package/action/scripts/profile_store.py +0 -87
- package/action/scripts/source_maintenance_fixture.py +0 -58
- package/action/scripts/test_action_step_order.py +0 -83
- package/action/scripts/test_app_context_scanner.py +0 -167
- package/action/scripts/test_app_group_requirements.py +0 -83
- package/action/scripts/test_asc_build_history.py +0 -221
- package/action/scripts/test_asc_builds_prerelease.py +0 -219
- package/action/scripts/test_asc_common_timeouts.py +0 -121
- package/action/scripts/test_asc_metadata_applier.py +0 -990
- package/action/scripts/test_asc_metadata_detector.py +0 -445
- package/action/scripts/test_asc_network_diagnostics.py +0 -92
- package/action/scripts/test_auto_detect.py +0 -492
- package/action/scripts/test_autoupdate_stage.py +0 -107
- package/action/scripts/test_capabilities.py +0 -261
- package/action/scripts/test_certificate_cap_policy.py +0 -72
- package/action/scripts/test_certificate_failure.py +0 -64
- package/action/scripts/test_certificate_request.py +0 -62
- package/action/scripts/test_cfg_resolve_credentials.py +0 -48
- package/action/scripts/test_compute_next_version.py +0 -95
- package/action/scripts/test_compute_next_version_patch_backcompat.py +0 -41
- package/action/scripts/test_compute_next_version_strictness.py +0 -67
- package/action/scripts/test_crashlytics_dsyms.py +0 -211
- package/action/scripts/test_crashlytics_phase_effects.py +0 -30
- package/action/scripts/test_delivery_icons.py +0 -76
- package/action/scripts/test_delivery_preflight.py +0 -354
- package/action/scripts/test_fetch_versions.py +0 -163
- package/action/scripts/test_flutter_native_preparation.py +0 -103
- package/action/scripts/test_ground_truth_floor.py +0 -104
- package/action/scripts/test_keychain.py +0 -145
- package/action/scripts/test_manage_marketing_version.py +0 -134
- package/action/scripts/test_manage_marketing_version_autoroll.py +0 -158
- package/action/scripts/test_manage_marketing_version_floor.py +0 -170
- package/action/scripts/test_manage_marketing_version_match.py +0 -193
- package/action/scripts/test_mmv_409_classifier.py +0 -231
- package/action/scripts/test_mmv_autobump_persist_gate.py +0 -131
- package/action/scripts/test_mmv_decide_create.py +0 -158
- package/action/scripts/test_mmv_floor_check.py +0 -158
- package/action/scripts/test_mmv_floor_crosscheck.py +0 -132
- package/action/scripts/test_mmv_helpers.py +0 -57
- package/action/scripts/test_mmv_testflight_only.py +0 -147
- package/action/scripts/test_mobile_artifact_restore.py +0 -93
- package/action/scripts/test_mobile_artifacts.py +0 -92
- package/action/scripts/test_native_bundle.py +0 -97
- package/action/scripts/test_native_cache.py +0 -37
- package/action/scripts/test_native_dependency_guard.py +0 -116
- package/action/scripts/test_native_dependency_wiring.py +0 -70
- package/action/scripts/test_native_pods.py +0 -151
- package/action/scripts/test_native_pods_diagnostics.py +0 -86
- package/action/scripts/test_native_pods_process.py +0 -41
- package/action/scripts/test_native_pods_retry.py +0 -182
- package/action/scripts/test_native_pods_timeout.py +0 -34
- package/action/scripts/test_native_prepare_evidence.py +0 -76
- package/action/scripts/test_next_build_number.py +0 -207
- package/action/scripts/test_pbxproj_editor.py +0 -153
- package/action/scripts/test_prepare_crashlytics.py +0 -281
- package/action/scripts/test_profile_app_groups.py +0 -103
- package/action/scripts/test_profile_reuse.py +0 -113
- package/action/scripts/test_read_config_auto_detect.py +0 -257
- package/action/scripts/test_registry_managed_signing.py +0 -116
- package/action/scripts/test_resolve_info_plist.py +0 -120
- package/action/scripts/test_resolve_marketing_version.py +0 -298
- package/action/scripts/test_retained_signing_identity.py +0 -110
- package/action/scripts/test_reuse_stale_editable.py +0 -182
- package/action/scripts/test_set_app_store_whats_new.py +0 -71
- package/action/scripts/test_signing_source_boundary.py +0 -82
- package/action/scripts/test_source_maintenance.py +0 -122
- package/action/scripts/test_source_preflight.py +0 -226
- package/action/scripts/test_team_fallback_wiring.py +0 -157
- package/action/scripts/test_team_resolver.py +0 -249
- package/action/scripts/test_testflight_version_slot_wiring.py +0 -75
- package/action/scripts/test_upload_build.py +0 -267
- package/action/scripts/test_upload_checksums.py +0 -74
- package/action/scripts/test_write_marketing_version.py +0 -101
- package/action/scripts/tests_common.py +0 -167
- package/android-action/scripts/bitrise_deploy.py +0 -160
- package/android-action/scripts/crashlytics_bootstrap_test_support.py +0 -60
- package/android-action/scripts/fixtures/flutter_test_loopback.dart +0 -58
- package/android-action/scripts/flutter_manifest_fixture.py +0 -164
- package/android-action/scripts/test_android_build_diagnostics.py +0 -145
- package/android-action/scripts/test_android_config.py +0 -281
- package/android-action/scripts/test_bitrise_deploy.py +0 -124
- package/android-action/scripts/test_crashlytics_bootstrap.py +0 -97
- package/android-action/scripts/test_crashlytics_prebuild.py +0 -40
- package/android-action/scripts/test_crashlytics_symbols.py +0 -212
- package/android-action/scripts/test_early_play_workflow.py +0 -82
- package/android-action/scripts/test_flutter_archive.py +0 -109
- package/android-action/scripts/test_flutter_archive_cache.py +0 -84
- package/android-action/scripts/test_flutter_archive_setup.py +0 -67
- package/android-action/scripts/test_flutter_archive_size.py +0 -28
- package/android-action/scripts/test_flutter_cache_setup.py +0 -108
- package/android-action/scripts/test_flutter_download_budget.py +0 -145
- package/android-action/scripts/test_flutter_manifest.py +0 -108
- package/android-action/scripts/test_flutter_manifest_scope.py +0 -44
- package/android-action/scripts/test_flutter_obfuscation.py +0 -115
- package/android-action/scripts/test_flutter_origin_retry.py +0 -66
- package/android-action/scripts/test_flutter_release_cache.py +0 -94
- package/android-action/scripts/test_flutter_release_cache_scope.py +0 -49
- package/android-action/scripts/test_flutter_transfer_progress.py +0 -81
- package/android-action/scripts/test_gradle_wrapper.py +0 -268
- package/android-action/scripts/test_play_connect_retry.py +0 -115
- package/android-action/scripts/test_play_inventory.py +0 -98
- package/android-action/scripts/test_play_preflight.py +0 -100
- package/android-action/scripts/test_play_preflight_transport.py +0 -96
- package/android-action/scripts/test_resolve_play_readiness.py +0 -109
- package/android-action/scripts/test_select_jdk.py +0 -213
- package/android-action/scripts/test_sign_bundle.py +0 -82
- package/android-action/scripts/test_version_override.py +0 -153
- package/backend-action/certificate_vhost.py +0 -259
- package/backend-action/network_contract.py +0 -119
- package/backend-action/network_diagnostics.py +0 -182
- package/backend-action/network_inventory.py +0 -235
- package/backend-action/network_owned_inventory.py +0 -118
- package/backend-action/network_pool_facts.json +0 -214
- package/backend-action/network_pools.py +0 -275
- package/backend-action/network_prepare.py +0 -152
- package/backend-action/network_provider.py +0 -213
- package/backend-action/network_provider_test_fixture.py +0 -30
- package/backend-action/network_readback.py +0 -31
- package/backend-action/network_runtime.py +0 -62
- package/backend-action/network_selected.py +0 -96
- package/backend-action/network_selected_receipt.py +0 -60
- package/backend-action/network_test_fixture.py +0 -57
- package/backend-action/nginx_test_fixture.py +0 -98
- package/backend-action/test_certificate_vhost.py +0 -453
- package/backend-action/test_edge_health.py +0 -75
- package/backend-action/test_edge_inputs.py +0 -79
- package/backend-action/test_edge_nginx.py +0 -125
- package/backend-action/test_edge_vhost.py +0 -112
- package/backend-action/test_identity_artifact.py +0 -77
- package/backend-action/test_identity_diagnostics.py +0 -101
- package/backend-action/test_identity_failures.py +0 -56
- package/backend-action/test_network_builtins.py +0 -28
- package/backend-action/test_network_diagnostics.py +0 -77
- package/backend-action/test_network_docker.py +0 -129
- package/backend-action/test_network_fixture_evidence.py +0 -23
- package/backend-action/test_network_inventory.py +0 -241
- package/backend-action/test_network_ipam_gateway.py +0 -46
- package/backend-action/test_network_noop.py +0 -64
- package/backend-action/test_network_owned_inventory.py +0 -128
- package/backend-action/test_network_prepare.py +0 -120
- package/backend-action/test_network_provider.py +0 -162
- package/backend-action/test_network_races.py +0 -73
- package/backend-action/test_network_rule_diagnostics.py +0 -69
- package/backend-action/test_network_runtime.py +0 -49
- package/backend-action/test_network_selected.py +0 -153
- package/backend-action/test_runtime_env.py +0 -229
- package/docs/BACKEND_NETWORKS.md +0 -159
package/README.md
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# gowalk-cicd
|
|
2
2
|
|
|
3
|
-
One installer for iOS TestFlight
|
|
4
|
-
|
|
3
|
+
One installer for iOS TestFlight and Android Google Play delivery, plus the
|
|
4
|
+
optional backend deploy. It supports native Swift/SwiftUI iOS projects, native Kotlin/Gradle
|
|
5
5
|
Android projects, and Flutter apps. Provision encrypted repository secrets, validate a
|
|
6
6
|
task candidate, and promote its release intent. Store builds and uploads run only in GitHub Actions.
|
|
7
7
|
|
|
8
8
|
App-specific workflow settings live in `.gowalk-cicd.yml`. The installer migrates supported
|
|
9
9
|
existing settings once and regenerates managed workflows without replacing custom behavior.
|
|
10
|
-
See [configuration
|
|
10
|
+
See [configuration](docs/CONFIGURATION.md).
|
|
11
11
|
|
|
12
12
|
## Install
|
|
13
13
|
|
|
@@ -23,12 +23,18 @@ Writes three core things into your repo:
|
|
|
23
23
|
- `.github/actions/android-app/` — Android build/sign action (Flutter or Gradle)
|
|
24
24
|
- `.github/workflows/deploy.yml` — workflow that builds and deploys both platforms
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
The installer no longer adds `.github/workflows/deploy-web.yml`. On re-adoption it
|
|
27
|
+
removes a `deploy-web.yml` that is still byte-for-byte the generated file and has no
|
|
28
|
+
overrides in `.gowalk-cicd.yml`; a customized one keeps upgrading (see
|
|
29
|
+
[Flutter web release](#flutter-web-release)).
|
|
30
30
|
|
|
31
|
-
Re-run the same command anytime to pull the latest version.
|
|
31
|
+
Re-run the same command anytime to pull the latest version. The vendored action
|
|
32
|
+
directories then mirror the package: a file the package no longer ships is deleted,
|
|
33
|
+
except the `.daemux-version` markers and any file a workflow under
|
|
34
|
+
`.github/workflows/` still names by path (the installer prints what it kept and
|
|
35
|
+
removed; `--dry-run` deletes nothing). Tests and fixtures are not shipped. A
|
|
36
|
+
workflow the package does not manage that fails to parse is skipped with
|
|
37
|
+
`[warn] skipped .github/workflows/<file>: <code>` instead of aborting the install.
|
|
32
38
|
|
|
33
39
|
Ready task PRs build shipping binaries alongside validation; the protected merge promotes matching
|
|
34
40
|
binaries through the existing store upload paths. See [candidate artifact reuse](docs/CANDIDATE_ARTIFACTS.md)
|
|
@@ -92,6 +98,11 @@ job. This bounds individual cache segments, not the total cache or SDK download,
|
|
|
92
98
|
and keeps existing cache keys. A successfully installed SDK is saved before app
|
|
93
99
|
checks run, so a later test/build failure does not force another cold SDK download.
|
|
94
100
|
Failed setup never saves an SDK cache; pub dependencies retain their job-end save.
|
|
101
|
+
Pull-request runs (`refs/pull/*`, which includes every candidate build) restore these caches
|
|
102
|
+
but never save them; task branches and the default branch still save. When the caller names
|
|
103
|
+
no Flutter version, a committed `.flutter-version` (`x.y.z`, a regular file of at most 64 bytes)
|
|
104
|
+
pins the SDK; a symlink or malformed pin fails with `Invalid project Flutter pin`, and no file
|
|
105
|
+
keeps the channel's latest release.
|
|
95
106
|
|
|
96
107
|
Native dependency preparation uses a committed `Gemfile` and `Gemfile.lock` beside
|
|
97
108
|
the selected iOS project, falling back to the repository root. It installs missing
|
|
@@ -109,9 +120,16 @@ Pods and verifies the selected workspace before release configuration. Preserve
|
|
|
109
120
|
order in customized validation and deployment workflows; updating action directories
|
|
110
121
|
alone cannot repair a configuration step that runs before the action.
|
|
111
122
|
|
|
123
|
+
The iOS action then skips `bundle install` and `pod install` when the Pods are already in
|
|
124
|
+
sync: `Pods/Manifest.lock` equals `Podfile.lock`, the lock's `PODFILE CHECKSUM` matches the
|
|
125
|
+
Podfile, every local `:path:` pod exists, a workspace exists and xcodegen did not just
|
|
126
|
+
generate the project. Its receipt then reports `pods: in_sync`, and its own native Pods
|
|
127
|
+
cache is not restored or saved for that run.
|
|
128
|
+
|
|
112
129
|
## Flutter web release
|
|
113
130
|
|
|
114
|
-
|
|
131
|
+
A repository whose `.gowalk-cicd.yml` customizes `deploy-web.yml` keeps it.
|
|
132
|
+
That workflow runs on changes to Flutter source,
|
|
115
133
|
web assets, package metadata, localization config, or the workflow itself. It
|
|
116
134
|
also supports manual dispatch. The build uses `GITHUB_RUN_NUMBER` as its build
|
|
117
135
|
number and uploads the complete `build/web` directory as a release artifact.
|
|
@@ -165,10 +183,6 @@ in App Store Connect; see [First-time app setup](#first-time-app-setup).
|
|
|
165
183
|
|
|
166
184
|
## Backend deploy (Python + Postgres, Docker)
|
|
167
185
|
|
|
168
|
-
New ordinary Compose projects receive small isolated networks inside Docker's verified existing pools.
|
|
169
|
-
Existing/custom/external networks and authored IPAM retain their contracts. Read-only
|
|
170
|
-
`network-diagnostics` uses the same deployment identity; see [capacity and diagnosis](docs/BACKEND_NETWORKS.md).
|
|
171
|
-
|
|
172
186
|
When a repo carries a Dockerized backend, the installer also vendors a backend deploy path:
|
|
173
187
|
`.github/actions/backend-app/` and `.github/workflows/deploy-backend.yml`. A
|
|
174
188
|
mobile-only repo is unaffected (the backend path is not installed).
|
|
@@ -211,13 +225,31 @@ wires an nginx vhost + Let's Encrypt cert for the API domain, and health-checks.
|
|
|
211
225
|
Hosts with several existing Let's Encrypt accounts select one deterministically,
|
|
212
226
|
and a domain deploy fails unless its public HTTPS certificate and health route validate.
|
|
213
227
|
Changing a container's published port preserves its existing HTTPS configuration; nginx must accept
|
|
214
|
-
the change, or the previous vhost is restored and the deploy fails.
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
228
|
+
the change, or the previous vhost is restored and the deploy fails.
|
|
229
|
+
When the domain's vhost has exactly one `ssl_certificate`, and that file exists, stays valid for more
|
|
230
|
+
than a day and lists `DNS:<domain>` in its subjectAltName, the deploy runs no Certbot, only follows the
|
|
231
|
+
published port, and logs `certificate state=current`. Otherwise the name is issued by webroot: the vhost
|
|
232
|
+
serves `/.well-known/acme-challenge/` from `/var/lib/gowalk-acme` on port 80 (and proxies the API there
|
|
233
|
+
until HTTPS exists); the deploy waits up to 20 s for this host's nginx to serve a probe file under the
|
|
234
|
+
domain's name; `certbot certonly --webroot --cert-name <domain> --keep-until-expiring` issues it (a lineage
|
|
235
|
+
of that name that is not due is kept); then the vhost is rendered with HTTPS: port 80 answers challenges
|
|
236
|
+
and redirects, port 443 proxies with `/etc/letsencrypt/live/<domain>/`. Certbot saves the webroot and a
|
|
237
|
+
deploy hook that reloads nginx under the host nginx lock, so the host's renew timer renews the lineage.
|
|
238
|
+
Vhosts that older releases configured with `certbot --nginx` keep their TLS directives; only their
|
|
239
|
+
upstream port changes. Every Certbot call runs under `flock -w 900 /run/gowalk-certbot.lock`, so deploys
|
|
240
|
+
on one host take turns; when the host's renew timer holds Certbot's own lock, the call retries every
|
|
241
|
+
10 s for up to 10 minutes. Vhost writes with their nginx test and reload, and the host port reservation,
|
|
242
|
+
run under the host nginx lock `/run/app-robot-nginx.lock` (`flock -w 120`), which the panel's domain
|
|
243
|
+
applier also takes. New Compose networks come from Docker's own address pools; the deploy hosts'
|
|
244
|
+
`default-address-pools` hand out `/24`s. After a healthy deploy the replaced build's images are pruned
|
|
245
|
+
(`docker image prune -f --filter label=com.docker.compose.project=<app>`); a refusal because another
|
|
246
|
+
prune is running defers it to the next deploy.
|
|
247
|
+
|
|
248
|
+
Each app gets one stable loopback port, reserved once in the host's `.env` as
|
|
249
|
+
`BACKEND_HTTP_PORT` (starting at `20000 + cksum(app) % 10000`, skipping ports other apps reserved or
|
|
250
|
+
already bound). A Compose file opts in by publishing `127.0.0.1:${BACKEND_HTTP_PORT:-}:<container-port>`;
|
|
251
|
+
a redeploy then leaves the nginx upstream unchanged. A literal `127.0.0.1:<port>:<container-port>`
|
|
252
|
+
keeps working as before.
|
|
221
253
|
|
|
222
254
|
Requirements on the consumer repo:
|
|
223
255
|
|
|
@@ -228,6 +260,11 @@ Requirements on the consumer repo:
|
|
|
228
260
|
never bake secrets in. A generated `.env` (with `POSTGRES_PASSWORD`) is created
|
|
229
261
|
on the host on first deploy and preserved across deploys (rsync excludes it).
|
|
230
262
|
- Repo **secret** `BACKEND_DEPLOY_SSH_KEY` (a private key with access to the host).
|
|
263
|
+
- Repo **variable** `BACKEND_DEPLOY_KNOWN_HOSTS` (recommended): `known_hosts` lines for the exact
|
|
264
|
+
host string the workflow connects to (`BACKEND_DEPLOY_HOST`, for example
|
|
265
|
+
`138.197.36.107 ssh-ed25519 AAAA...`). Deploys then require that key
|
|
266
|
+
(`StrictHostKeyChecking=yes`). While it is empty the job trusts `ssh-keyscan` and prints one
|
|
267
|
+
`backend_host_key_unpinned` warning.
|
|
231
268
|
- Repo **secret** `BACKEND_RUNTIME_ENV` (optional): newline-delimited `KEY=value`
|
|
232
269
|
runtime secrets. The action writes it as mode 0600 on the host and passes it
|
|
233
270
|
to Compose without copying values into the repository or action log.
|
|
@@ -238,10 +275,15 @@ Requirements on the consumer repo:
|
|
|
238
275
|
Malformed or ambiguous multiline structures refuse before deployment. Transport is bounded
|
|
239
276
|
to 1 MiB of UTF-8 input and 512 KiB per value, uses private SSH stdin, and atomically replaces
|
|
240
277
|
`.runtime.env`; application sync preserves the last installed file if validation fails.
|
|
241
|
-
- Repo **
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
278
|
+
- Repo **variable** `BACKEND_API_DOMAIN`: the bound API host name (for example
|
|
279
|
+
`api.<app-domain>`); its DNS A record must point at the host for the cert.
|
|
280
|
+
**Backend Deploy runs only when it is set**: a repository with no bound backend
|
|
281
|
+
origin holds no deploy key, so `deploy-backend.yml` is skipped and the feature-branch
|
|
282
|
+
`backend-preview` deploy ends with a `backend_origin_unbound` notice.
|
|
283
|
+
- Repo **variables** (optional): `BACKEND_APP_NAME` (defaults to the repo name),
|
|
284
|
+
`BACKEND_HEALTH_PATH` (default `/health`), `BACKEND_DEPLOY_HOST` (default
|
|
285
|
+
`138.197.36.107`). The action refuses an `api-domain` that is not a lowercase DNS
|
|
286
|
+
name, a `health-path` outside `/[A-Za-z0-9_./-]*` and a malformed `cert-email`.
|
|
245
287
|
|
|
246
288
|
The action directory is canonical here (like the iOS/Android actions): edit it in
|
|
247
289
|
`backend-action/`, never in a consumer's vendored copy.
|
|
@@ -354,7 +396,17 @@ rather than a failure, so it reads as a flake rather than an out-of-memory.
|
|
|
354
396
|
|
|
355
397
|
Before building, the Android job caps `-Xmx` at 4 GB and `MaxMetaspaceSize` at
|
|
356
398
|
2 GB in the checkout, with a `::warning::` naming the original value. Projects
|
|
357
|
-
already at or below those numbers are left untouched.
|
|
399
|
+
already at or below those numbers are left untouched. A runner with at least
|
|
400
|
+
16 GiB of `MemTotal` (for example an 8-core `ANDROID_RUNNER`) keeps the app's own
|
|
401
|
+
settings. Linux only.
|
|
402
|
+
|
|
403
|
+
### Android runner size
|
|
404
|
+
|
|
405
|
+
The Android job runs on `${{ vars.ANDROID_RUNNER || 'ubuntu-24.04' }}`. Set the
|
|
406
|
+
repository or organization variable `ANDROID_RUNNER` to a larger hosted runner
|
|
407
|
+
label to shorten the release build; unset it before deleting that runner. The
|
|
408
|
+
variable is not a build input: setting, changing or removing it never discards a
|
|
409
|
+
candidate binary.
|
|
358
410
|
|
|
359
411
|
### When Play will not accept a release for review
|
|
360
412
|
|
|
@@ -428,12 +480,11 @@ the situation and whose **message** is one line of JSON carrying a versioned
|
|
|
428
480
|
| `source_maintenance_pending` | `gowalk-cicd/source-maintenance-pending.v1` | `repo`, `base_sha`, `head_sha`, `branch`, `run_id` |
|
|
429
481
|
| `apple_build_upload_failed` (error) | `gowalk-cicd/apple-build-upload-failed.v2` | `category`, `stage`, `receipt_available`, receipt identifiers (`cfBundleVersion`, `upload_id`, `file_id`, `state`, `provider_status`, `provider_code`, `provider_pointer`), `action` |
|
|
430
482
|
| `flutter_download_failed` (error) | `gowalk-cicd/flutter-download-failed.v1` | `phase`, `curl_exit`, `http_status`, `proxy_status`, `attempts`, `retained_bytes` |
|
|
431
|
-
| `android_build_failed` (error) | `gowalk-cicd/android-build-failed.v1` | `phase`, `exit_code`, `signals` (fixed observed patterns; empty means unclassified) |
|
|
483
|
+
| `android_build_failed` (error) | `gowalk-cicd/android-build-failed.v1` | `phase`, `exit_code`, `signals` (fixed observed patterns; empty means unclassified), optional `hosts`, `artifacts` and `excerpt` (error lines plus the next line, URL userinfo removed, at most 4 KB) |
|
|
432
484
|
|
|
433
|
-
Android release compilers
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
with `phase` and `elapsed_seconds`; successful compiler output is not republished.
|
|
485
|
+
Android release compilers stream their output to the job log inside `::stop-commands::` markers,
|
|
486
|
+
so no build line can act as a workflow command. Their failure signals describe observed error
|
|
487
|
+
patterns, not retry permission or a unique root cause.
|
|
437
488
|
|
|
438
489
|
Native bundle and Pods failures emit `native_prepare_failed` with schema
|
|
439
490
|
`gowalk-cicd/native-prepare-failed.v1`, `phase`, a fixed refusal `code` and fixed observed `signals`.
|
|
@@ -565,10 +616,11 @@ reliably fit. The failure surfaces far from its cause:
|
|
|
565
616
|
zip I/O error: No space left on device
|
|
566
617
|
```
|
|
567
618
|
|
|
568
|
-
The Android job
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
and
|
|
619
|
+
The Android job prints `df -h /` and does nothing more when `/` already has
|
|
620
|
+
40 GB or more free (a larger runner). Otherwise it removes the preinstalled
|
|
621
|
+
toolchains a Flutter build never uses (.NET, GHC, PowerShell, Swift, Chromium)
|
|
622
|
+
and prunes Docker images in the background, reclaiming roughly 25 GB while the
|
|
623
|
+
JDK, Gradle restore and Flutter setup run. Linux only. npm survives on purpose: the
|
|
572
624
|
[Crashlytics symbol upload](#crashlytics-symbol-delivery-firebase_app_id) runs
|
|
573
625
|
the Firebase CLI through `npx`.
|
|
574
626
|
|
|
@@ -621,56 +673,12 @@ Both stores pick up per-locale release notes from committed files:
|
|
|
621
673
|
the deploy workflow passes it to the Play upload and the notes ship with
|
|
622
674
|
every release; when absent, releases upload without notes as before.
|
|
623
675
|
|
|
624
|
-
## Android delivery via Bitrise (alternative mode)
|
|
625
|
-
|
|
626
|
-
Use this when the Android **upload keystore password lives in Bitrise** (not in
|
|
627
|
-
the repo) — the GitHub runner then cannot sign the AAB locally. In this mode the
|
|
628
|
-
Android job triggers a Bitrise workflow (which holds the keystore + Play
|
|
629
|
-
service-account secrets) over the Bitrise API and waits for it, mirroring the
|
|
630
|
-
build result back into the GitHub Actions run. iOS still ships via GitHub
|
|
631
|
-
Actions as normal.
|
|
632
|
-
|
|
633
|
-
Enable it by committing `creds/bitrise.json`:
|
|
634
|
-
|
|
635
|
-
```json
|
|
636
|
-
{
|
|
637
|
-
"enabled": true,
|
|
638
|
-
"app_slug": "8b2a7a24-....",
|
|
639
|
-
"workflow": "android-deploy",
|
|
640
|
-
"branch": "main",
|
|
641
|
-
"api_token": "bitpat_...."
|
|
642
|
-
}
|
|
643
|
-
```
|
|
644
|
-
|
|
645
|
-
- `app_slug` — the Bitrise app slug (from the app's Bitrise URL or
|
|
646
|
-
`GET https://api.bitrise.io/v0.1/apps`).
|
|
647
|
-
- `workflow` — the Bitrise workflow that builds, signs, and runs
|
|
648
|
-
`google-play-deploy` (default `android-deploy`).
|
|
649
|
-
- `branch` — optional; defaults to the pushed ref.
|
|
650
|
-
- `api_token` — a Bitrise personal access token. Committing it to a **private**
|
|
651
|
-
repo's `creds/` follows the same trust model as the ASC `.p8`. For non-private
|
|
652
|
-
repos, omit it here and set the `BITRISE_API_TOKEN` Actions secret instead.
|
|
653
|
-
|
|
654
|
-
When `creds/bitrise.json` is present with `enabled: true`, the local
|
|
655
|
-
build/sign/upload steps are skipped and `bitrise_deploy.py` drives the Bitrise
|
|
656
|
-
build; otherwise the local path above runs unchanged.
|
|
657
|
-
|
|
658
|
-
The Bitrise `android-deploy` workflow must produce a versionCode higher than
|
|
659
|
-
what is already on Play. The convention used by this fleet is a `+200` offset
|
|
660
|
-
over `$BITRISE_BUILD_NUMBER` via a `change-android-versioncode-and-versionname`
|
|
661
|
-
step, with the versionName read from `pubspec.yaml`.
|
|
662
|
-
|
|
663
676
|
## Sharing one distribution cert across a team's apps
|
|
664
677
|
|
|
665
|
-
The iOS action
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
its cached cert already revoked by a sibling, mints a new one, and revokes
|
|
670
|
-
another. The symptom is a "Your Certificate Has Been Revoked" email on nearly
|
|
671
|
-
every deploy.
|
|
672
|
-
|
|
673
|
-
Fix: apps in the same Apple team should **share one cert**. A fleet registry can
|
|
678
|
+
The iOS action signs with the retained Apple Distribution identity in `creds/`
|
|
679
|
+
(cert alive + NotAfter > 30 days) and never creates or revokes a certificate.
|
|
680
|
+
Apple caps a team at **2** distribution certs, so apps in the same Apple team
|
|
681
|
+
should **share one cert**. A fleet registry can
|
|
674
682
|
provision the same `creds/cert.p12` + `creds/cert.meta.json` into every repo of
|
|
675
683
|
that team (an Apple Distribution cert is team-scoped, not app-scoped, so one
|
|
676
684
|
cert signs them all). Registry provisioning must also write
|
|
@@ -683,9 +691,10 @@ The marker is a fail-closed ownership boundary: the action may reuse the
|
|
|
683
691
|
identity and create per-app provisioning profiles, but it never creates,
|
|
684
692
|
replaces, or revokes a registry-managed distribution certificate. Missing,
|
|
685
693
|
partially written, corrupt, expired, Apple-revoked, or resource-ID/P12-mismatched
|
|
686
|
-
managed material aborts with a reconciliation error.
|
|
687
|
-
marker
|
|
688
|
-
|
|
694
|
+
managed material aborts with a reconciliation error. A legacy repo without the
|
|
695
|
+
marker whose retained identity is missing or unusable fails with
|
|
696
|
+
`apple_signing_identity_required` (`gowalk-cicd/apple-signing-identity-required.v1`)
|
|
697
|
+
and keeps its existing signing files.
|
|
689
698
|
|
|
690
699
|
## How it works
|
|
691
700
|
|
|
@@ -770,9 +779,7 @@ package produces — the Android App Bundle and the iOS archive — is compiled
|
|
|
770
779
|
config key that turns it off. Native Swift and Kotlin/Gradle apps are
|
|
771
780
|
unaffected: the flag belongs to the Dart compiler and they have no Dart code.
|
|
772
781
|
Flutter web builds are also untouched — `flutter build web` has no such flag;
|
|
773
|
-
dart2js minifies release output instead.
|
|
774
|
-
[Bitrise](#android-delivery-via-bitrise-alternative-mode) is built by Bitrise's
|
|
775
|
-
workflow, not by this action; put the same two flags in that workflow.
|
|
782
|
+
dart2js minifies release output instead.
|
|
776
783
|
|
|
777
784
|
What it does: the Dart AOT compiler replaces class, function and library names
|
|
778
785
|
with short random identifiers, so the app's Dart symbols cannot be read out of
|
|
@@ -847,7 +854,8 @@ is required. A completed CI run does not mean this deferred upload is complete.
|
|
|
847
854
|
|
|
848
855
|
### iOS delivery
|
|
849
856
|
|
|
850
|
-
The iOS composite action runs on `macos-15
|
|
857
|
+
The iOS composite action runs on `macos-15`; promoting a verified candidate IPA runs its first
|
|
858
|
+
attempt on `ubuntu-24.04` (see [Candidate artifacts](docs/CANDIDATE_ARTIFACTS.md)). It:
|
|
851
859
|
|
|
852
860
|
GitHub Actions reaches Apple and Google **directly**. No store proxy is configured, read
|
|
853
861
|
or inherited here: the account-pinned residential exit belongs to the panel and the runner
|
|
@@ -877,19 +885,16 @@ preserving each app's custom checks and artifact retention settings. An isolated
|
|
|
877
885
|
4. **Computes the next build number** by querying ASC for the latest uploaded
|
|
878
886
|
build and incrementing.
|
|
879
887
|
5. **Provisions signing** at runtime: reconciles the App ID's capabilities with
|
|
880
|
-
the target's entitlements (see below), then
|
|
881
|
-
Distribution
|
|
882
|
-
`CI-<bundle_id
|
|
883
|
-
|
|
888
|
+
the target's entitlements (see below), then signs with the retained Apple
|
|
889
|
+
Distribution identity and the per-target App Store provisioning profile named
|
|
890
|
+
`CI-<bundle_id>` that App Store Connect already holds, creating the profile
|
|
891
|
+
when it is missing or stale. Patches the `.pbxproj` to use Manual signing
|
|
892
|
+
against those profiles.
|
|
884
893
|
6. **Archives** with `xcodebuild archive`, exports the IPA, and uploads via
|
|
885
894
|
Apple's build-upload REST API.
|
|
886
895
|
7. **Sets "What's New"** on every declared localization (reads
|
|
887
896
|
`fastlane/metadata/ios/<locale>/release_notes.txt` if present, or from the
|
|
888
897
|
`app-store-whats-new` input).
|
|
889
|
-
8. **Auto-fills empty App Store metadata** (name, subtitle, keywords,
|
|
890
|
-
description, promotional text, what's new) via GitHub Models AI, on every
|
|
891
|
-
locale that has gaps. See [AI metadata auto-fill](#ai-metadata-auto-fill)
|
|
892
|
-
below.
|
|
893
898
|
|
|
894
899
|
The iOS action requires only the p8. Everything else is derived.
|
|
895
900
|
|
|
@@ -919,17 +924,16 @@ Before creating a profile, the action reads the target's
|
|
|
919
924
|
ID — Push Notifications, Associated Domains, HealthKit, SiriKit, HomeKit,
|
|
920
925
|
network extensions and the other plain on/off toggles.
|
|
921
926
|
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
before a capability was turned on — whether by this action or
|
|
926
|
-
developer portal —
|
|
927
|
-
failing on a capability the App ID already has.
|
|
927
|
+
An existing `CI-<bundle_id>` profile is found by name and reused only when it
|
|
928
|
+
is ACTIVE, issued for the current certificate, more than 30 days from expiry,
|
|
929
|
+
and carries those same entitlements. Otherwise it is deleted and regenerated, so
|
|
930
|
+
a profile issued before a capability was turned on — whether by this action or
|
|
931
|
+
by you in the developer portal — is never reused.
|
|
928
932
|
|
|
929
933
|
App Groups require registration and assignment to each participating App ID through
|
|
930
934
|
the account's Apple Developer console. The action reads the literal identifiers from
|
|
931
|
-
each archive target's entitlements and verifies their exact membership in both
|
|
932
|
-
and fresh profiles. A stale
|
|
935
|
+
each archive target's entitlements and verifies their exact membership in both reused
|
|
936
|
+
and fresh profiles. A stale profile regenerates; a fresh profile missing a required group
|
|
933
937
|
fails before installation with `apple_app_groups_required`, schema
|
|
934
938
|
`gowalk-cicd/apple-app-groups-required.v1`, containing the bundle ID and missing groups.
|
|
935
939
|
Complete those assignments through the scoped console and rerun CI. This check creates
|
|
@@ -948,63 +952,6 @@ Two other classes of capability are **not** enabled automatically, and each gets
|
|
|
948
952
|
→ <your App ID>**. Until then the archive fails with `Provisioning profile
|
|
949
953
|
"CI-<bundle>" doesn't include the App Attest capability`.
|
|
950
954
|
|
|
951
|
-
## AI metadata auto-fill
|
|
952
|
-
|
|
953
|
-
On every run, after the TestFlight upload succeeds, the action:
|
|
954
|
-
|
|
955
|
-
1. Queries App Store Connect for every `appInfoLocalization` and
|
|
956
|
-
`appStoreVersionLocalization` on the editable version.
|
|
957
|
-
2. Computes the set of empty fields per locale (URL fields are always
|
|
958
|
-
skipped — you must set those manually in ASC).
|
|
959
|
-
3. Scans your repo for context (README, Info.plist, dependency files, top
|
|
960
|
-
Swift files) and feeds it to `openai/gpt-4o` via GitHub Models with a
|
|
961
|
-
strict JSON schema.
|
|
962
|
-
4. PATCHes only the fields that were empty — never overwrites existing
|
|
963
|
-
content.
|
|
964
|
-
|
|
965
|
-
Fully idempotent: a second run with no empty fields skips the AI step
|
|
966
|
-
entirely (zero requests, zero PATCHes).
|
|
967
|
-
|
|
968
|
-
### Requirement: `permissions: models: read`
|
|
969
|
-
|
|
970
|
-
`actions/ai-inference` needs the `models: read` permission. The template
|
|
971
|
-
workflow written by `npx gowalk-cicd` already includes it:
|
|
972
|
-
|
|
973
|
-
```yaml
|
|
974
|
-
permissions:
|
|
975
|
-
contents: read
|
|
976
|
-
models: read
|
|
977
|
-
```
|
|
978
|
-
|
|
979
|
-
**Existing consumers must add this block to their `deploy.yml`** at the
|
|
980
|
-
workflow or job level. If it's missing, the AI step fails open with a
|
|
981
|
-
`::warning::` and the rest of the workflow continues unaffected.
|
|
982
|
-
|
|
983
|
-
### Rate limits
|
|
984
|
-
|
|
985
|
-
GitHub Models free tier allows **50 `gpt-4o` requests per day** (10 per
|
|
986
|
-
minute). One workflow run = one request. If you run many apps from the
|
|
987
|
-
same GitHub account, or trigger several builds per day, switch to the
|
|
988
|
-
cheaper mini model:
|
|
989
|
-
|
|
990
|
-
```yaml
|
|
991
|
-
- uses: ./.github/actions/swift-app
|
|
992
|
-
with:
|
|
993
|
-
ai-metadata-model: openai/gpt-4o-mini
|
|
994
|
-
```
|
|
995
|
-
|
|
996
|
-
`gpt-4o-mini` has a much higher free-tier quota.
|
|
997
|
-
|
|
998
|
-
### Disabling AI metadata
|
|
999
|
-
|
|
1000
|
-
Pass `ai-metadata: 'false'` to skip the AI steps entirely:
|
|
1001
|
-
|
|
1002
|
-
```yaml
|
|
1003
|
-
- uses: ./.github/actions/swift-app
|
|
1004
|
-
with:
|
|
1005
|
-
ai-metadata: 'false'
|
|
1006
|
-
```
|
|
1007
|
-
|
|
1008
955
|
## Update
|
|
1009
956
|
|
|
1010
957
|
```bash
|
|
@@ -1012,7 +959,8 @@ npx --yes gowalk-cicd
|
|
|
1012
959
|
```
|
|
1013
960
|
|
|
1014
961
|
Overwrites both vendored actions and `.github/workflows/deploy.yml` with the
|
|
1015
|
-
latest versions
|
|
962
|
+
latest versions, and deletes vendored files the package no longer ships (see
|
|
963
|
+
[Install](#install)). Because the actions are vendored locally, builds use the
|
|
1016
964
|
reviewed copy in your app repository; updates arrive through this npm package.
|
|
1017
965
|
|
|
1018
966
|
## Override config (rare)
|
|
@@ -1040,22 +988,14 @@ common ones:
|
|
|
1040
988
|
| `bundle-id` | Override the auto-detected bundle identifier |
|
|
1041
989
|
| `team-id` | Override the auto-detected team ID |
|
|
1042
990
|
| `app-store-apple-id` | Numeric ASC app ID (override auto-lookup) |
|
|
1043
|
-
| `certificate-cap-policy` |
|
|
991
|
+
| `certificate-cap-policy` | Deprecated and ignored: CI never creates or revokes certificates. |
|
|
1044
992
|
| `run-tests` | `false` to skip the simulator test stage |
|
|
1045
993
|
| `uses-non-exempt-encryption` | Value for `ITSAppUsesNonExemptEncryption` |
|
|
1046
994
|
| `archive` | `false` to build-only (PR runs without secrets) |
|
|
1047
995
|
| `upload` | `false` to archive but not upload to TestFlight |
|
|
1048
996
|
| `manage-app-store-version` | `false` to upload without creating/editing the App Store release slot |
|
|
1049
997
|
| `app-store-whats-new` | Inline "What's New" text (overrides files) |
|
|
1050
|
-
| `ai-metadata` |
|
|
1051
|
-
| `ai-metadata-model` | GitHub Models model id (default `openai/gpt-4o`) |
|
|
1052
|
-
|
|
1053
|
-
Certificate creation sends the complete PEM CSR in Apple's `csrContent` field, including its framing and newlines.
|
|
1054
|
-
Certificate creation refusals emit `apple_certificate_rejected` with schema
|
|
1055
|
-
`gowalk-cicd/apple-certificate-rejected.v1`, `operation`, `http_status`, `reason` and `error_codes`.
|
|
1056
|
-
HTTP 409 is classified as `certificate_limit` only when Apple's returned detail identifies the limit;
|
|
1057
|
-
otherwise it remains `unclassified_conflict`. Codes come from a fixed allowlist. Raw provider text and
|
|
1058
|
-
CSR data are excluded. Neither outcome permits automatic certificate deletion or another creation attempt.
|
|
998
|
+
| `ai-metadata`, `ai-metadata-model` | Deprecated and ignored: the action no longer writes App Store metadata with AI. |
|
|
1059
999
|
|
|
1060
1000
|
## First-time app setup
|
|
1061
1001
|
|
|
@@ -1067,10 +1007,9 @@ inside GitHub Actions.
|
|
|
1067
1007
|
Once the app exists, all subsequent builds and uploads are fully automated via
|
|
1068
1008
|
the ASC API key.
|
|
1069
1009
|
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
commits any completed cache files, then re-raises the failure so the private key is not lost.
|
|
1010
|
+
CI never creates, lists for deletion or revokes an Apple Distribution certificate; it
|
|
1011
|
+
signs only with the retained identity (see
|
|
1012
|
+
[Sharing one distribution cert](#sharing-one-distribution-cert-across-a-teams-apps)).
|
|
1074
1013
|
|
|
1075
1014
|
## Troubleshooting
|
|
1076
1015
|
|
|
@@ -1162,29 +1101,13 @@ generated pbxproj). Either move `MARKETING_VERSION` under
|
|
|
1162
1101
|
`settings.base` in `project.yml`, or pin
|
|
1163
1102
|
`marketing-version-auto-bump: 'none'` and bump manually.
|
|
1164
1103
|
|
|
1165
|
-
##
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
`gowalk-cicd
|
|
1170
|
-
`.
|
|
1171
|
-
|
|
1172
|
-
on a verified task branch (under both `.github/actions/swift-app/` and
|
|
1173
|
-
`.github/actions/android-app/`).
|
|
1174
|
-
`.github/workflows/deploy.yml` is NEVER auto-committed — see
|
|
1175
|
-
"deploy.yml is not auto-updated" below.
|
|
1176
|
-
|
|
1177
|
-
| Aspect | Behaviour |
|
|
1178
|
-
|--------|-----------|
|
|
1179
|
-
| Trigger | Push to default branch only (PR / branch runs do nothing) |
|
|
1180
|
-
| Landing | The app session adopts the exact receipt on its current task branch and uses the protected PR |
|
|
1181
|
-
| Isolation | CI leaves HEAD and worktree bytes intact; no default-branch push or rebase |
|
|
1182
|
-
| Candidates | Action updates and later version changes have separate verified receipts |
|
|
1183
|
-
| Failure mode | npm discovery remains optional; unconfirmed source preservation fails the job |
|
|
1184
|
-
|
|
1185
|
-
The shipped `deploy.yml` watches only the release intent. Adopting an action-directory
|
|
1186
|
-
update on its own therefore does not launch another mobile upload. Review and adopt the template
|
|
1187
|
-
as well as the action directories to enable this behavior in an existing consumer.
|
|
1104
|
+
## Updates
|
|
1105
|
+
|
|
1106
|
+
CI never updates the vendored actions: the `auto-update` input is deprecated and
|
|
1107
|
+
ignored. A repository adopts a new release only when its task runs
|
|
1108
|
+
`npx --yes gowalk-cicd` and lands the result through the protected PR. The
|
|
1109
|
+
`.daemux-version` markers the installer writes name the release the vendored
|
|
1110
|
+
actions came from.
|
|
1188
1111
|
|
|
1189
1112
|
### deploy.yml is not auto-updated
|
|
1190
1113
|
|
|
@@ -1194,9 +1117,9 @@ of `contents: write` — this is a built-in safeguard against CI
|
|
|
1194
1117
|
self-modification. When a new version of `gowalk-cicd`
|
|
1195
1118
|
requires `deploy.yml` schema changes (e.g., new permissions, new
|
|
1196
1119
|
paths-ignore entries), the action's release notes will call this out
|
|
1197
|
-
and the app session runs the
|
|
1120
|
+
and the app session runs the `npx --yes gowalk-cicd` adoption in its task
|
|
1198
1121
|
workspace, preserving app-specific workflow inputs and landing the full change through
|
|
1199
|
-
its checked PR.
|
|
1122
|
+
its checked PR.
|
|
1200
1123
|
|
|
1201
1124
|
Changes that need that manual run:
|
|
1202
1125
|
|
|
@@ -1207,24 +1130,6 @@ Changes that need that manual run:
|
|
|
1207
1130
|
passed to both actions. Until it is, setting the variable does nothing.
|
|
1208
1131
|
See [Crashlytics symbol upload](#crashlytics-symbol-delivery-firebase_app_id).
|
|
1209
1132
|
|
|
1210
|
-
### Opt out
|
|
1211
|
-
|
|
1212
|
-
Pin the vendored copy by passing `auto-update: 'false'` to the action:
|
|
1213
|
-
|
|
1214
|
-
```yaml
|
|
1215
|
-
- uses: ./.github/actions/swift-app
|
|
1216
|
-
with:
|
|
1217
|
-
auto-update: 'false'
|
|
1218
|
-
```
|
|
1219
|
-
|
|
1220
|
-
### First-run bootstrap
|
|
1221
|
-
|
|
1222
|
-
The marker is written by `npx gowalk-cicd` itself. A repo
|
|
1223
|
-
without a marker (e.g. an old hand-vendored copy) will be treated as
|
|
1224
|
-
out-of-date on its first run, after which updates land incrementally.
|
|
1225
|
-
Run `npx --yes gowalk-cicd` once locally if you want to skip
|
|
1226
|
-
even that first auto-bootstrap.
|
|
1227
|
-
|
|
1228
1133
|
## License
|
|
1229
1134
|
|
|
1230
1135
|
MIT
|