gowalk-cicd 1.0.104 → 1.0.105

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
@@ -264,6 +264,10 @@ node /path/to/gowalk-cicd/bin/cli.mjs
264
264
  Both Flutter configuration and the Pods helper use that bundle in their child process,
265
265
  preserving Podfile.lock and the parent job environment. Deliver the workflow wrapper and
266
266
  action helper together; action-only updates cannot repair earlier custom configuration steps.
267
+ Flutter `--config-only` can query Xcode and install Pods before returning. In the workflow,
268
+ generate Flutter inputs with `pub get`, run the locked `native_pods.py` preparation and
269
+ completed graph guard, then configure the release with its existing obfuscation/define flags.
270
+ The graph guard still applies when there is no Podfile. Preserve this order in custom CI.
267
271
  - Locked Pod installation retries once only when its own attempt reports curl 18 and a partial-transfer
268
272
  symptom. Both attempts share the existing 900-second budget and recheck Podfile, Podfile.lock and
269
273
  selected Ruby bundle inputs. TLS/auth/permission, checksum, version and deployment errors never retry.
package/README.md CHANGED
@@ -58,6 +58,12 @@ When adopting this update, retain the `native_bundle.py` configuration wrapper i
58
58
  custom workflows as well as updating the action files. Apps without a Gemfile keep
59
59
  their existing CocoaPods runtime.
60
60
 
61
+ Flutter `--config-only` can query Xcode and invoke `pod install`. The workflow first
62
+ runs `flutter pub get` to generate the Podfile's Flutter inputs, then installs locked
63
+ Pods and verifies the selected workspace before release configuration. Preserve this
64
+ order in customized validation and deployment workflows; updating action directories
65
+ alone cannot repair a configuration step that runs before the action.
66
+
61
67
  ## Flutter web release
62
68
 
63
69
  The conditional `deploy-web.yml` workflow runs on changes to Flutter source,
@@ -1 +1 @@
1
- 1.0.104
1
+ 1.0.105
@@ -0,0 +1,107 @@
1
+ """Execute the shipped Flutter preparation shell with real guards and offline tool fixtures."""
2
+ import json
3
+ import os
4
+ from pathlib import Path
5
+ import subprocess
6
+ import sys
7
+ import tempfile
8
+ import textwrap
9
+ import unittest
10
+
11
+ import native_bundle
12
+ from test_native_dependency_guard import project
13
+
14
+ REPO = Path(__file__).resolve().parents[2]
15
+
16
+
17
+ class FlutterPreparationTests(unittest.TestCase):
18
+ def setUp(self):
19
+ temporary = tempfile.TemporaryDirectory(prefix="flutter-native-preparation-")
20
+ self.addCleanup(temporary.cleanup)
21
+ self.root = Path(temporary.name).resolve()
22
+ project(self.root, "ios/Runner.xcodeproj")
23
+ workspace = self.root / "ios/Runner.xcworkspace"
24
+ workspace.mkdir()
25
+ (workspace / "contents.xcworkspacedata").write_text(
26
+ '<Workspace><FileRef location="group:Runner.xcodeproj"/></Workspace>')
27
+ for name in ("Podfile", "Podfile.lock"):
28
+ (self.root / "ios" / name).write_text("fixture lock\n")
29
+ (self.root / "pubspec.yaml").write_text("name: fixture\n")
30
+ for argv in (["git", "init", "-q"], ["git", "add", "."],
31
+ ["git", "-c", "user.name=Fixture", "-c", "user.email=fixture@example.invalid",
32
+ "commit", "-qm", "Freeze native fixture"]):
33
+ subprocess.run(argv, cwd=self.root, capture_output=True, check=True)
34
+ actions = self.root / ".github/actions"
35
+ actions.mkdir(parents=True)
36
+ (actions / "swift-app").symlink_to(REPO / "action", target_is_directory=True)
37
+ (actions / "android-app").symlink_to(REPO / "android-action", target_is_directory=True)
38
+ self.env = {**os.environ, "PATH": str(self.root) + os.pathsep + os.environ["PATH"],
39
+ "GITHUB_WORKSPACE": str(self.root), "RUNNER_TEMP": str(self.root / "scratch"),
40
+ "ONBOARDING_PUBLIC_ORIGIN": "https://flow.example.invalid",
41
+ "GOOGLE_STORE_PROXY_URL": "http://fixture:PRIVATE_SENTINEL@127.0.0.1:9"}
42
+ self.install_tools()
43
+
44
+ def executable(self, name, source):
45
+ path = self.root / name
46
+ path.write_text("#!" + sys.executable + "\n" + textwrap.dedent(source))
47
+ path.chmod(0o700)
48
+
49
+ def install_tools(self):
50
+ self.executable("flutter", '''
51
+ import json,sys
52
+ from pathlib import Path
53
+ if sys.argv[1:3] == ["pub", "get"]:
54
+ folder=Path("ios/Flutter");folder.mkdir()
55
+ (folder/"Generated.xcconfig").write_text("generated")
56
+ elif sys.argv[1:3] == ["build", "ios"]:
57
+ Path("configuration.json").write_text(json.dumps(sys.argv[1:]))
58
+ assert Path("ios/pods-ready").is_file(), "Configuration reached before locked Pods"
59
+ else:
60
+ raise SystemExit(9)
61
+ ''')
62
+ self.executable("pod", '''
63
+ import json,os,sys
64
+ from pathlib import Path
65
+ assert Path("Flutter/Generated.xcconfig").is_file()
66
+ assert sys.argv[1:] == ["install", "--deployment", "--no-repo-update"]
67
+ assert os.environ["HTTPS_PROXY"].startswith("http://127.0.0.1:")
68
+ Path("pod-called").touch()
69
+ if os.environ.get("FAIL_PODS"):
70
+ raise SystemExit(7)
71
+ Path("pods-ready").touch()
72
+ ''')
73
+
74
+ def run_preparation(self):
75
+ body = (REPO / "templates/deploy.yml").read_text().split(
76
+ "- name: Prepare Flutter iOS project\n", 1)[1].split("\n - ", 1)[0]
77
+ script = textwrap.dedent(body.split(" run: |\n", 1)[1])
78
+ result = subprocess.run([sys.executable, native_bundle.__file__, "--folder", "ios",
79
+ "--proxy-helper", str(REPO / "android-action/scripts/play_store_proxy.py"),
80
+ "--", "bash", "--noprofile", "--norc", "-e", "-o", "pipefail", "-c", script],
81
+ cwd=self.root, env=self.env, capture_output=True, text=True, timeout=20)
82
+ self.assertNotIn("PRIVATE_SENTINEL", result.stdout + result.stderr)
83
+ return result
84
+
85
+ def test_locked_pods_precede_configuration_without_losing_release_arguments(self):
86
+ result = self.run_preparation()
87
+ self.assertEqual(result.returncode, 0, result.stdout)
88
+ self.assertTrue((self.root / "ios/pod-called").exists())
89
+ args = json.loads((self.root / "configuration.json").read_text())
90
+ for arg in ("--release", "--no-codesign", "--config-only", "--obfuscate",
91
+ "--split-debug-info=" + str(self.root / "scratch/dart-symbols/ios"),
92
+ "ONBOARDING_PUBLIC_ORIGIN=https://flow.example.invalid"):
93
+ self.assertIn(arg, args)
94
+ self.assertEqual((self.root / "ios/Podfile.lock").read_text(), "fixture lock\n")
95
+
96
+ def test_failed_locked_install_stops_before_flutter_configuration(self):
97
+ self.env["FAIL_PODS"] = "1"
98
+ self.assertNotEqual(self.run_preparation().returncode, 0)
99
+ self.assertTrue((self.root / "ios/pod-called").exists())
100
+ self.assertFalse((self.root / "configuration.json").exists())
101
+
102
+ def test_remote_package_graph_refuses_before_configuration_without_podfile(self):
103
+ (self.root / "ios/Podfile").unlink()
104
+ project(self.root, "ios/Runner.xcodeproj", {"remote": {"isa": "XCRemoteSwiftPackageReference"}})
105
+ self.assertNotEqual(self.run_preparation().returncode, 0)
106
+ self.assertFalse((self.root / "ios/pod-called").exists())
107
+ self.assertFalse((self.root / "configuration.json").exists())
@@ -1 +1 @@
1
- 1.0.104
1
+ 1.0.105
@@ -1 +1 @@
1
- 1.0.104
1
+ 1.0.105
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gowalk-cicd",
3
- "version": "1.0.104",
3
+ "version": "1.0.105",
4
4
  "description": "Zero-config GitHub Actions delivery for iOS TestFlight and Android Google Play.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -149,6 +149,13 @@ jobs:
149
149
  ONBOARDING_PUBLIC_ORIGIN: ${{ vars.ONBOARDING_PUBLIC_ORIGIN }}
150
150
  run: |
151
151
  flutter pub get
152
+ # Even --config-only can query Xcode and run pod install. Pub generates
153
+ # the Flutter configuration needed by the Podfile without resolving Pods.
154
+ python3 .github/actions/swift-app/scripts/native_pods.py "$GITHUB_WORKSPACE" \
155
+ --container ios/Runner.xcworkspace \
156
+ --proxy-helper .github/actions/android-app/scripts/play_store_proxy.py
157
+ python3 .github/actions/swift-app/scripts/native_dependency_guard.py "$GITHUB_WORKSPACE" \
158
+ --container ios/Runner.xcworkspace
152
159
  # Flutter removed the synthetic `package:flutter_gen`, so apps that use
153
160
  # AppLocalizations now generate real sources. Nothing else generates them,
154
161
  # and analyze/compile fail on the missing import if we skip this.