gowalk-cicd 1.0.92 → 1.0.93

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 CHANGED
@@ -172,6 +172,11 @@ node /path/to/gowalk-cicd/bin/cli.mjs
172
172
  errors still fail the job. Never use `continue-on-error` or a timeout around all SDK setup
173
173
  to hide an optional cache failure. Do not alter cache keys or disable caches as part of
174
174
  this timeout handling.
175
+ - Flutter SDK caching restores first and saves immediately after successful setup, before
176
+ consumer tests/builds can fail and suppress a combined cache action's success-only post hook.
177
+ Save only on a cache miss with caching enabled, a real successful install and verified cache
178
+ scope. Preserve resolved keys/paths and the official pinned restore/save programs. Failed or
179
+ dry-run setup never publishes an SDK cache; pub dependency caching retains its job-end behavior.
175
180
  - Gradle caches use explicit checksum-pinned restore/save actions, each optional and bounded
176
181
  to two minutes. Preserve setup-java's key inputs and absolute cache paths to reuse existing
177
182
  caches. Java setup, builds and store uploads remain mandatory; save runs after delivery.
package/README.md CHANGED
@@ -30,7 +30,9 @@ Flutter's optional SDK and pub cache restores have a one-minute timeout per
30
30
  download segment. A slow segment becomes a cache miss and normal SDK setup
31
31
  continues through the assigned Google proxy; SDK setup errors still fail the
32
32
  job. This bounds individual cache segments, not the total cache or SDK download,
33
- and keeps existing cache keys and the successful restore/save behavior.
33
+ and keeps existing cache keys. A successfully installed SDK is saved before app
34
+ checks run, so a later test/build failure does not force another cold SDK download.
35
+ Failed setup never saves an SDK cache; pub dependencies retain their job-end save.
34
36
 
35
37
  ## Flutter web release
36
38
 
@@ -1 +1 @@
1
- 1.0.92
1
+ 1.0.93
@@ -1 +1 @@
1
- 1.0.92
1
+ 1.0.93
@@ -119,7 +119,7 @@ runs:
119
119
  - name: Cache Flutter
120
120
  id: cache-flutter
121
121
  if: ${{ inputs.cache == 'true' }}
122
- uses: actions/cache@caa296126883cff596d87d8935842f9db880ef25
122
+ uses: actions/cache/restore@caa296126883cff596d87d8935842f9db880ef25
123
123
  continue-on-error: true
124
124
  env:
125
125
  NODE_OPTIONS: --require "${{ steps.scope.outputs.preloader }}"
@@ -139,6 +139,7 @@ runs:
139
139
  path: ${{ steps.flutter-action.outputs.PUB-CACHE-PATH }}
140
140
  key: ${{ steps.flutter-action.outputs.PUB-CACHE-KEY }}-${{ hashFiles('**/pubspec.lock') }}
141
141
  - name: Install or reuse the resolved Flutter SDK
142
+ id: install
142
143
  if: ${{ inputs.dry-run != 'true' }}
143
144
  uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2
144
145
  env:
@@ -157,3 +158,16 @@ runs:
157
158
  pub-cache-path: ${{ steps.flutter-action.outputs.PUB-CACHE-PATH }}
158
159
  dry-run: 'false'
159
160
  git-source: ${{ inputs.git-source }}
161
+ # A later app failure must not discard a successfully installed, expensive SDK.
162
+ - name: Save installed Flutter SDK
163
+ if: >-
164
+ ${{ inputs.cache == 'true' && inputs.dry-run != 'true'
165
+ && steps.install.outcome == 'success' && steps.scope.outcome == 'success'
166
+ && steps.cache-flutter.outputs.cache-hit != 'true' }}
167
+ uses: actions/cache/save@caa296126883cff596d87d8935842f9db880ef25
168
+ continue-on-error: true
169
+ env:
170
+ NODE_OPTIONS: --require "${{ steps.scope.outputs.preloader }}"
171
+ with:
172
+ path: ${{ steps.flutter-action.outputs.CACHE-PATH }}
173
+ key: ${{ steps.flutter-action.outputs.CACHE-KEY }}
@@ -24,7 +24,7 @@ class BootstrapWiringTests(unittest.TestCase):
24
24
  self.assertNotIn("continue-on-error", step)
25
25
  self.assertEqual(checked, 3)
26
26
  setup = yaml.safe_load((ROOT / "android-action/flutter-setup/action.yml").read_text())
27
- guard, scope, resolve, sdk_cache, pub_cache, install = setup["runs"]["steps"]
27
+ guard, scope, resolve, sdk_cache, pub_cache, install, save = setup["runs"]["steps"]
28
28
  self.assertIn('play_store_proxy.py" --bootstrap-env', guard["run"])
29
29
  self.assertNotIn("continue-on-error", guard)
30
30
  self.assertTrue(scope["continue-on-error"])
@@ -39,7 +39,7 @@ class BootstrapWiringTests(unittest.TestCase):
39
39
  self.assertEqual(step["with"]["pub-cache"], "false")
40
40
  self.assertNotIn("continue-on-error", step)
41
41
  self.assertNotIn("BASH_ENV", setup.get("env", {}))
42
- for step in (guard, scope, sdk_cache, pub_cache):
42
+ for step in (guard, scope, sdk_cache, pub_cache, save):
43
43
  self.assertNotIn("BASH_ENV", step.get("env", {}))
44
44
  self.assertEqual(guard["id"], "transport")
45
45
  self.assertIn('>> "$GITHUB_OUTPUT"', guard["run"])
@@ -59,6 +59,25 @@ class BootstrapWiringTests(unittest.TestCase):
59
59
  self.assertEqual(setup["outputs"]["CACHE-HIT"]["value"], "${{ steps.cache-flutter.outputs.cache-hit }}")
60
60
  self.assertEqual(setup["outputs"]["PUB-CACHE-HIT"]["value"], "${{ steps.cache-pub.outputs.cache-hit }}")
61
61
 
62
+ def test_successful_sdk_is_saved_before_later_consumer_failure_can_discard_it(self):
63
+ setup = yaml.safe_load((ROOT / "android-action/flutter-setup/action.yml").read_text())
64
+ steps = setup["runs"]["steps"]
65
+ restore = next(step for step in steps if step.get("id") == "cache-flutter")
66
+ self.assertEqual(restore["uses"],
67
+ "actions/cache/restore@caa296126883cff596d87d8935842f9db880ef25")
68
+ install = next(step for step in steps if step.get("id") == "install")
69
+ save = steps[steps.index(install) + 1]
70
+ self.assertEqual(save["uses"], "actions/cache/save@caa296126883cff596d87d8935842f9db880ef25")
71
+ self.assertEqual(save["with"], restore["with"])
72
+ self.assertTrue(save["continue-on-error"])
73
+ self.assertEqual(save["env"], {"NODE_OPTIONS": '--require "${{ steps.scope.outputs.preloader }}"'})
74
+ condition = " ".join(save["if"].split())
75
+ self.assertEqual(condition, "${{ inputs.cache == 'true' && inputs.dry-run != 'true' "
76
+ "&& steps.install.outcome == 'success' && steps.scope.outcome == 'success' "
77
+ "&& steps.cache-flutter.outputs.cache-hit != 'true' }}")
78
+ self.assertNotIn("continue-on-error", install)
79
+ self.assertNotIn("timeout-minutes", save) # Unsupported in composite action steps.
80
+
62
81
  def test_pods_cache_keeps_identity_and_uses_the_same_optional_scope(self):
63
82
  workflow = yaml.safe_load((ROOT / "templates/deploy.yml").read_text())
64
83
  steps = workflow["jobs"]["ios"]["steps"]
@@ -1 +1 @@
1
- 1.0.92
1
+ 1.0.93
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gowalk-cicd",
3
- "version": "1.0.92",
3
+ "version": "1.0.93",
4
4
  "description": "Zero-config GitHub Actions delivery for iOS TestFlight and Android Google Play.",
5
5
  "type": "module",
6
6
  "bin": {