gowalk-cicd 1.0.67 → 1.0.69
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 +13 -0
- package/README.md +10 -0
- package/action/.daemux-version +1 -1
- package/android-action/.daemux-version +1 -1
- package/android-action/action.yml +12 -4
- package/android-action/scripts/play_store_proxy.py +27 -6
- package/android-action/scripts/test_google_bootstrap_proxy.py +77 -0
- package/android-action/scripts/test_google_bootstrap_wiring.py +50 -0
- package/android-action/scripts/test_play_store_proxy.py +2 -1
- package/backend-action/.daemux-version +1 -1
- package/package.json +1 -1
- package/templates/deploy-web.yml +10 -1
- package/templates/deploy.yml +19 -2
package/CLAUDE.md
CHANGED
|
@@ -128,6 +128,19 @@ node /path/to/gowalk-cicd/bin/cli.mjs
|
|
|
128
128
|
Crashlytics Buildtools reads them first and rejects authenticated proxy URLs. HTTPS is tunneled
|
|
129
129
|
without TLS interception; no upstream failure may fall back to the destination.
|
|
130
130
|
The wrapper disables Gradle daemons and closes its relay when the command ends.
|
|
131
|
+
- Flutter bootstrap is part of that boundary: before the Flutter setup action,
|
|
132
|
+
`play_store_proxy.py --bootstrap-env` validates the Google account pin and writes
|
|
133
|
+
both proxy/bypass spellings to the private job environment without console output.
|
|
134
|
+
SDK manifest/archive curl requests use that pin. Subsequent pub, analysis, tests,
|
|
135
|
+
localization, global activation and builds run through the existing owned relay.
|
|
136
|
+
The helper's bootstrap and command modes require only Python's standard library;
|
|
137
|
+
importing the Google API client must not become an unprotected bootstrap prerequisite.
|
|
138
|
+
- Flutter setup scopes `SEGMENT_DOWNLOAD_TIMEOUT_MINS=1` to the composite action's optional
|
|
139
|
+
SDK/pub cache restores. This bounds each cache segment, not the whole cache or SDK download.
|
|
140
|
+
A cache timeout becomes a cache miss; normal proxied SDK setup remains mandatory and its
|
|
141
|
+
errors still fail the job. Never use `continue-on-error` or a timeout around all SDK setup
|
|
142
|
+
to hide an optional cache failure. Do not alter cache keys or disable caches as part of
|
|
143
|
+
this timeout handling.
|
|
131
144
|
- Backend runtime credentials use the single encrypted `BACKEND_RUNTIME_ENV`
|
|
132
145
|
secret. The action writes it to host-side `.runtime.env` with mode 0600 and
|
|
133
146
|
supplies it to Compose after the generated `.env`; never print its content.
|
package/README.md
CHANGED
|
@@ -26,6 +26,12 @@ are unaffected.
|
|
|
26
26
|
|
|
27
27
|
Re-run the same command anytime to pull the latest version.
|
|
28
28
|
|
|
29
|
+
Flutter's optional SDK and pub cache restores have a one-minute timeout per
|
|
30
|
+
download segment. A slow segment becomes a cache miss and normal SDK setup
|
|
31
|
+
continues through the assigned Google proxy; SDK setup errors still fail the
|
|
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.
|
|
34
|
+
|
|
29
35
|
## Flutter web release
|
|
30
36
|
|
|
31
37
|
The conditional `deploy-web.yml` workflow runs on changes to Flutter source,
|
|
@@ -634,6 +640,10 @@ metadata and binary transfer. Provision `APPLE_STORE_PROXY_URL` and
|
|
|
634
640
|
`GOOGLE_STORE_PROXY_URL` as encrypted repository secrets before deployment. A missing
|
|
635
641
|
proxy refuses provider calls; there is no direct fallback. Refresh existing workflow
|
|
636
642
|
files with the released installer while preserving application-specific build inputs.
|
|
643
|
+
The Google pin also covers Flutter SDK manifest/archive downloads and early `pub`
|
|
644
|
+
operations in iOS, Android and web workflows. Bootstrap validates it before SDK setup;
|
|
645
|
+
subsequent Dart and JVM operations use the same owned relay as release builds. A fork
|
|
646
|
+
without the repository secret cannot start provider downloads through these workflows.
|
|
637
647
|
The Apple uploader retains `apple-upload-<run>-<attempt>` receipts with IPA SHA-256,
|
|
638
648
|
upload ID and processing readback, and resumes matching bytes after interruption.
|
|
639
649
|
|
package/action/.daemux-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.0.
|
|
1
|
+
1.0.69
|
|
@@ -1 +1 @@
|
|
|
1
|
-
1.0.
|
|
1
|
+
1.0.69
|
|
@@ -83,7 +83,9 @@ runs:
|
|
|
83
83
|
# Missing dependencies or an indeterminate store read must fail here; they are
|
|
84
84
|
# not evidence of a new package with no existing version codes.
|
|
85
85
|
- name: Install Play API dependencies
|
|
86
|
-
shell:
|
|
86
|
+
shell: >-
|
|
87
|
+
python3 ${{ github.action_path }}/scripts/play_store_proxy.py
|
|
88
|
+
-- bash --noprofile --norc -e -o pipefail {0}
|
|
87
89
|
run: python3 -m pip install --disable-pip-version-check -q 'google-auth>=2.40,<3' 'requests>=2.32,<3'
|
|
88
90
|
|
|
89
91
|
- name: Resolve Android app and credentials
|
|
@@ -98,19 +100,25 @@ runs:
|
|
|
98
100
|
# --- Flutter --------------------------------------------------------
|
|
99
101
|
- name: Get Flutter dependencies
|
|
100
102
|
if: ${{ steps.config.outputs.project_kind == 'flutter' }}
|
|
101
|
-
shell:
|
|
103
|
+
shell: >-
|
|
104
|
+
python3 ${{ github.action_path }}/scripts/play_store_proxy.py
|
|
105
|
+
-- bash --noprofile --norc -e -o pipefail {0}
|
|
102
106
|
run: flutter pub get
|
|
103
107
|
|
|
104
108
|
- name: Analyze Flutter app
|
|
105
109
|
if: ${{ steps.config.outputs.project_kind == 'flutter' && inputs.run-tests == 'true' }}
|
|
106
|
-
shell:
|
|
110
|
+
shell: >-
|
|
111
|
+
python3 ${{ github.action_path }}/scripts/play_store_proxy.py
|
|
112
|
+
-- bash --noprofile --norc -e -o pipefail {0}
|
|
107
113
|
run: flutter analyze
|
|
108
114
|
|
|
109
115
|
# `flutter test` hard-fails with "Test directory \"test\" not found" when a repo
|
|
110
116
|
# has no tests, which is not a real failure. Skip instead of blowing up the deploy.
|
|
111
117
|
- name: Test Flutter app
|
|
112
118
|
if: ${{ steps.config.outputs.project_kind == 'flutter' && inputs.run-tests == 'true' }}
|
|
113
|
-
shell:
|
|
119
|
+
shell: >-
|
|
120
|
+
python3 ${{ github.action_path }}/scripts/play_store_proxy.py
|
|
121
|
+
-- bash --noprofile --norc -e -o pipefail {0}
|
|
114
122
|
run: |
|
|
115
123
|
if [ -d test ]; then
|
|
116
124
|
flutter test
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Google CI transport uses only the account-pinned proxy, including OAuth exchanges.
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Four entry points, all from the one validated ``GOOGLE_STORE_PROXY_URL``:
|
|
4
4
|
|
|
5
5
|
* ``python3 play_store_proxy.py`` refuses a missing or malformed proxy.
|
|
6
6
|
* ``python3 play_store_proxy.py -- <command …>`` runs a build tool with the explicit
|
|
@@ -10,6 +10,8 @@ Three entry points, all from the one validated ``GOOGLE_STORE_PROXY_URL``:
|
|
|
10
10
|
* ``python3 play_store_proxy.py --github-env`` clears the lower-case ambient bypass
|
|
11
11
|
(``no_proxy``) for the rest of the job, so a JavaScript upload step that can only
|
|
12
12
|
carry upper-case ``env`` keys cannot be bypassed by a runner's ambient value.
|
|
13
|
+
* ``python3 play_store_proxy.py --bootstrap-env`` protects the curl-based Flutter
|
|
14
|
+
SDK setup through its private job environment, before Python dependencies exist.
|
|
13
15
|
"""
|
|
14
16
|
from __future__ import annotations
|
|
15
17
|
|
|
@@ -18,16 +20,16 @@ import subprocess
|
|
|
18
20
|
import sys
|
|
19
21
|
from urllib.parse import urlsplit
|
|
20
22
|
|
|
21
|
-
import requests
|
|
22
|
-
|
|
23
23
|
LOWERCASE_BYPASS = ("no_proxy",)
|
|
24
|
+
BOOTSTRAP_VARIABLES = ("HTTP_PROXY", "HTTPS_PROXY", "http_proxy", "https_proxy", "NO_PROXY", "no_proxy")
|
|
24
25
|
|
|
25
26
|
|
|
26
27
|
def proxy_url() -> str:
|
|
27
28
|
value = os.environ.get("GOOGLE_STORE_PROXY_URL", "").strip()
|
|
28
29
|
try:
|
|
29
30
|
parsed = urlsplit(value)
|
|
30
|
-
valid = parsed.scheme in {"http", "https"} and parsed.hostname and parsed.port
|
|
31
|
+
valid = (parsed.scheme in {"http", "https"} and parsed.hostname and parsed.port
|
|
32
|
+
and not any(char in value for char in "\r\n\0"))
|
|
31
33
|
except ValueError:
|
|
32
34
|
valid = False
|
|
33
35
|
if not valid:
|
|
@@ -41,8 +43,10 @@ def environment() -> dict[str, str]:
|
|
|
41
43
|
"http_proxy": value, "https_proxy": value, "NO_PROXY": "", "no_proxy": ""}
|
|
42
44
|
|
|
43
45
|
|
|
44
|
-
def session()
|
|
46
|
+
def session():
|
|
45
47
|
value = proxy_url()
|
|
48
|
+
import requests
|
|
49
|
+
|
|
46
50
|
client = requests.Session()
|
|
47
51
|
client.trust_env = False
|
|
48
52
|
client.proxies = {"http": value, "https": value}
|
|
@@ -72,14 +76,31 @@ def clear_github_env_bypass(path: str | None = None) -> list[str]:
|
|
|
72
76
|
return lines
|
|
73
77
|
|
|
74
78
|
|
|
79
|
+
def bootstrap_github_env() -> None:
|
|
80
|
+
"""Protect curl-based SDK setup before Python dependencies or a JVM exist.
|
|
81
|
+
|
|
82
|
+
GITHUB_ENV is a runner-owned environment file, never console output. Dart
|
|
83
|
+
and JVM commands still use ``--`` and its credential-free owned relay.
|
|
84
|
+
"""
|
|
85
|
+
env = environment()
|
|
86
|
+
target = os.environ.get("GITHUB_ENV", "")
|
|
87
|
+
if not target:
|
|
88
|
+
raise SystemExit("GITHUB_ENV is not set; run this inside a GitHub Actions step")
|
|
89
|
+
with open(target, "a", encoding="utf-8") as handle:
|
|
90
|
+
handle.writelines(f"{name}={env[name]}\n" for name in BOOTSTRAP_VARIABLES)
|
|
91
|
+
|
|
92
|
+
|
|
75
93
|
def main(args: list[str]) -> int:
|
|
94
|
+
if args == ["--bootstrap-env"]:
|
|
95
|
+
bootstrap_github_env()
|
|
96
|
+
return 0
|
|
76
97
|
if args[:1] == ["--github-env"]:
|
|
77
98
|
clear_github_env_bypass()
|
|
78
99
|
return 0
|
|
79
100
|
if args[:1] == ["--"]:
|
|
80
101
|
return run(args[1:])
|
|
81
102
|
if args:
|
|
82
|
-
raise SystemExit("usage: play_store_proxy.py [--github-env | -- <command …>]")
|
|
103
|
+
raise SystemExit("usage: play_store_proxy.py [--bootstrap-env | --github-env | -- <command …>]")
|
|
83
104
|
proxy_url()
|
|
84
105
|
return 0
|
|
85
106
|
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"""SDK bootstrap and real curl/Dart clients cannot silently use direct transport."""
|
|
2
|
+
import base64
|
|
3
|
+
import os
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
import subprocess
|
|
6
|
+
import sys
|
|
7
|
+
import tempfile
|
|
8
|
+
import unittest
|
|
9
|
+
from unittest import mock
|
|
10
|
+
|
|
11
|
+
import play_store_proxy
|
|
12
|
+
from test_jvm_proxy_relay import upstream
|
|
13
|
+
|
|
14
|
+
SCRIPT = Path(play_store_proxy.__file__).resolve()
|
|
15
|
+
DART = os.environ.get("DART_SDK_BIN", "")
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class BootstrapTests(unittest.TestCase):
|
|
19
|
+
def test_bootstrap_has_no_python_dependency_and_curl_uses_the_pinned_exit(self):
|
|
20
|
+
with tempfile.TemporaryDirectory() as directory, upstream() as (proxy, seen):
|
|
21
|
+
target = Path(directory) / "github.env"
|
|
22
|
+
env = {**os.environ, "GOOGLE_STORE_PROXY_URL": proxy, "GITHUB_ENV": str(target),
|
|
23
|
+
"https_proxy": "http://127.0.0.1:1", "no_proxy": "*", "NO_PROXY": "*"}
|
|
24
|
+
result = subprocess.run([sys.executable, "-S", str(SCRIPT), "--bootstrap-env"],
|
|
25
|
+
env=env, capture_output=True, text=True, timeout=10)
|
|
26
|
+
self.assertEqual((result.returncode, result.stdout, result.stderr), (0, "", ""))
|
|
27
|
+
env.update(line.split("=", 1) for line in target.read_text().splitlines())
|
|
28
|
+
result = subprocess.run(["curl", "--fail", "--silent", "--show-error", "--max-time", "5",
|
|
29
|
+
"http://unresolvable.invalid/flutter-sdk"],
|
|
30
|
+
env=env, capture_output=True, text=True, timeout=10)
|
|
31
|
+
self.assertEqual(result.returncode, 0, result.stderr)
|
|
32
|
+
self.assertEqual(result.stdout, "through pinned proxy")
|
|
33
|
+
auth = "Basic " + base64.b64encode(b"fixture-user:fixture-pass").decode()
|
|
34
|
+
self.assertEqual(seen, [("GET", "http://unresolvable.invalid/flutter-sdk", auth)])
|
|
35
|
+
self.assertNotIn("fixture-pass", result.stderr)
|
|
36
|
+
|
|
37
|
+
def test_missing_malformed_or_injected_proxy_refuses_before_creating_bootstrap_environment(self):
|
|
38
|
+
with tempfile.TemporaryDirectory() as directory:
|
|
39
|
+
target = Path(directory) / "github.env"
|
|
40
|
+
for proxy in ("", "private-malformed-value", "http://assigned.test:12\nNO_PROXY=*"):
|
|
41
|
+
env = {**os.environ, "GOOGLE_STORE_PROXY_URL": proxy, "GITHUB_ENV": str(target)}
|
|
42
|
+
result = subprocess.run([sys.executable, "-S", str(SCRIPT), "--bootstrap-env"],
|
|
43
|
+
env=env, capture_output=True, text=True, timeout=10)
|
|
44
|
+
self.assertNotEqual(result.returncode, 0)
|
|
45
|
+
self.assertFalse(target.exists())
|
|
46
|
+
self.assertNotIn(proxy or "never-matches", result.stderr)
|
|
47
|
+
|
|
48
|
+
def test_command_wrapper_also_runs_before_requests_is_installed(self):
|
|
49
|
+
env = {**os.environ, "GOOGLE_STORE_PROXY_URL": "http://127.0.0.1:1"}
|
|
50
|
+
result = subprocess.run([sys.executable, "-S", str(SCRIPT), "--", sys.executable, "-c", "pass"],
|
|
51
|
+
env=env, capture_output=True, text=True, timeout=10)
|
|
52
|
+
self.assertEqual((result.returncode, result.stdout, result.stderr), (0, "", ""))
|
|
53
|
+
|
|
54
|
+
@unittest.skipUnless(DART and Path(DART).is_file(), "set DART_SDK_BIN to an installed native Dart executable")
|
|
55
|
+
def test_actual_dart_http_client_uses_the_relay_and_rejects_invalid_tls(self):
|
|
56
|
+
source = ("import 'dart:io'; import 'dart:convert'; "
|
|
57
|
+
"Future<void> main(List<String> args) async { var c=HttpClient(); "
|
|
58
|
+
"try { var r=await (await c.getUrl(Uri.parse(args[0]))).close(); "
|
|
59
|
+
"stdout.write(await r.transform(utf8.decoder).join()); } "
|
|
60
|
+
"catch (_) { exitCode=7; } finally { c.close(force:true); } }")
|
|
61
|
+
with tempfile.TemporaryDirectory() as directory, upstream() as (proxy, seen):
|
|
62
|
+
script = Path(directory) / "probe.dart"
|
|
63
|
+
script.write_text(source)
|
|
64
|
+
for scheme, expected in (("http", 0), ("https", 7)):
|
|
65
|
+
env = {"GOOGLE_STORE_PROXY_URL": proxy, "NO_PROXY": "*", "no_proxy": "*"}
|
|
66
|
+
with mock.patch.dict(os.environ, env):
|
|
67
|
+
result = subprocess.run([sys.executable, str(SCRIPT), "--", DART, "--disable-dart-dev",
|
|
68
|
+
str(script), f"{scheme}://unresolvable.invalid/pub"],
|
|
69
|
+
env=os.environ, capture_output=True, text=True, timeout=20)
|
|
70
|
+
self.assertEqual(result.returncode, expected, result.stderr)
|
|
71
|
+
self.assertNotIn("fixture-pass", result.stdout + result.stderr)
|
|
72
|
+
self.assertEqual([(method, url) for method, url, _auth in seen], [
|
|
73
|
+
("GET", "http://unresolvable.invalid/pub"), ("CONNECT", "unresolvable.invalid:443")])
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
if __name__ == "__main__":
|
|
77
|
+
unittest.main()
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"""Every distributed Flutter bootstrap enters the shared protected transport first."""
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
import re
|
|
4
|
+
import unittest
|
|
5
|
+
|
|
6
|
+
import yaml
|
|
7
|
+
|
|
8
|
+
ROOT = Path(__file__).resolve().parents[2]
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class BootstrapWiringTests(unittest.TestCase):
|
|
12
|
+
def test_each_flutter_sdk_setup_has_a_prior_mandatory_account_guard(self):
|
|
13
|
+
checked = 0
|
|
14
|
+
for name in ("deploy.yml", "deploy-web.yml"):
|
|
15
|
+
workflow = yaml.safe_load((ROOT / "templates" / name).read_text())
|
|
16
|
+
for job in workflow["jobs"].values():
|
|
17
|
+
steps = job.get("steps", [])
|
|
18
|
+
for index, step in enumerate(steps):
|
|
19
|
+
if not step.get("uses", "").startswith("subosito/flutter-action@"):
|
|
20
|
+
continue
|
|
21
|
+
checked += 1
|
|
22
|
+
guard = steps[index - 1]
|
|
23
|
+
self.assertEqual(guard.get("if"), step.get("if"))
|
|
24
|
+
self.assertEqual(job["env"]["GOOGLE_STORE_PROXY_URL"],
|
|
25
|
+
"${{ secrets.GOOGLE_STORE_PROXY_URL }}")
|
|
26
|
+
self.assertTrue(guard["run"].endswith("play_store_proxy.py --bootstrap-env"))
|
|
27
|
+
self.assertNotIn("continue-on-error", guard)
|
|
28
|
+
self.assertEqual(checked, 3)
|
|
29
|
+
|
|
30
|
+
def test_remaining_flutter_commands_run_inside_the_owned_relay(self):
|
|
31
|
+
groups = []
|
|
32
|
+
for name in ("deploy.yml", "deploy-web.yml"):
|
|
33
|
+
workflow = yaml.safe_load((ROOT / "templates" / name).read_text())
|
|
34
|
+
groups.extend(job.get("steps", []) for job in workflow["jobs"].values())
|
|
35
|
+
groups.append(yaml.safe_load((ROOT / "android-action/action.yml").read_text())["runs"]["steps"])
|
|
36
|
+
checked = 0
|
|
37
|
+
for steps in groups:
|
|
38
|
+
for step in steps:
|
|
39
|
+
run = step.get("run", "")
|
|
40
|
+
if not re.search(r"\b(?:flutter (?:pub|analyze|test|build|gen-l10n)|dart pub)\b", run):
|
|
41
|
+
continue
|
|
42
|
+
if 'play_store_proxy.py" --' in run:
|
|
43
|
+
continue
|
|
44
|
+
checked += 1
|
|
45
|
+
self.assertIn("play_store_proxy.py -- bash", step.get("shell", ""), step.get("name"))
|
|
46
|
+
self.assertEqual(checked, 6)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
if __name__ == "__main__":
|
|
50
|
+
unittest.main()
|
|
@@ -4,6 +4,7 @@ from pathlib import Path
|
|
|
4
4
|
import sys
|
|
5
5
|
import unittest
|
|
6
6
|
from unittest import mock
|
|
7
|
+
import requests
|
|
7
8
|
|
|
8
9
|
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
|
9
10
|
import play_store_proxy
|
|
@@ -12,7 +13,7 @@ import play_store_proxy
|
|
|
12
13
|
class PlayProxyTests(unittest.TestCase):
|
|
13
14
|
def test_missing_proxy_never_constructs_a_direct_session(self):
|
|
14
15
|
with mock.patch.dict(os.environ, {"GOOGLE_STORE_PROXY_URL": ""}), \
|
|
15
|
-
mock.patch.object(
|
|
16
|
+
mock.patch.object(requests, "Session") as session:
|
|
16
17
|
with self.assertRaises(SystemExit):
|
|
17
18
|
play_store_proxy.session()
|
|
18
19
|
session.assert_not_called()
|
|
@@ -1 +1 @@
|
|
|
1
|
-
1.0.
|
|
1
|
+
1.0.69
|
package/package.json
CHANGED
package/templates/deploy-web.yml
CHANGED
|
@@ -26,9 +26,16 @@ jobs:
|
|
|
26
26
|
name: Flutter Web Artifact
|
|
27
27
|
runs-on: ubuntu-24.04
|
|
28
28
|
timeout-minutes: 20
|
|
29
|
+
env:
|
|
30
|
+
GOOGLE_STORE_PROXY_URL: ${{ secrets.GOOGLE_STORE_PROXY_URL }}
|
|
29
31
|
steps:
|
|
30
32
|
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
|
33
|
+
- name: Require the Google proxy before Flutter SDK setup
|
|
34
|
+
shell: bash
|
|
35
|
+
run: python3 .github/actions/android-app/scripts/play_store_proxy.py --bootstrap-env
|
|
31
36
|
- uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2.23.0
|
|
37
|
+
env:
|
|
38
|
+
SEGMENT_DOWNLOAD_TIMEOUT_MINS: "1"
|
|
32
39
|
with:
|
|
33
40
|
channel: stable
|
|
34
41
|
cache: true
|
|
@@ -45,7 +52,9 @@ jobs:
|
|
|
45
52
|
git config --global \
|
|
46
53
|
url."https://x-access-token:${GIT_PRIVATE_TOKEN}@github.com/".insteadOf "https://github.com/"
|
|
47
54
|
- name: Build Flutter web release
|
|
48
|
-
shell:
|
|
55
|
+
shell: >-
|
|
56
|
+
python3 .github/actions/android-app/scripts/play_store_proxy.py
|
|
57
|
+
-- bash --noprofile --norc -e -o pipefail {0}
|
|
49
58
|
run: |
|
|
50
59
|
flutter pub get
|
|
51
60
|
if [ -f l10n.yaml ]; then flutter gen-l10n; fi
|
package/templates/deploy.yml
CHANGED
|
@@ -77,9 +77,16 @@ jobs:
|
|
|
77
77
|
else
|
|
78
78
|
echo "enabled=false" >> "$GITHUB_OUTPUT"
|
|
79
79
|
fi
|
|
80
|
+
- name: Require the Google proxy before Flutter SDK setup
|
|
81
|
+
if: ${{ steps.flutter.outputs.enabled == 'true' }}
|
|
82
|
+
shell: bash
|
|
83
|
+
run: python3 .github/actions/android-app/scripts/play_store_proxy.py --bootstrap-env
|
|
80
84
|
- name: Set up Flutter
|
|
81
85
|
if: ${{ steps.flutter.outputs.enabled == 'true' }}
|
|
82
86
|
uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2.23.0
|
|
87
|
+
env:
|
|
88
|
+
# Optional SDK/pub cache segments must finish promptly; normal SDK setup still fails on errors.
|
|
89
|
+
SEGMENT_DOWNLOAD_TIMEOUT_MINS: "1"
|
|
83
90
|
with:
|
|
84
91
|
channel: stable
|
|
85
92
|
cache: true
|
|
@@ -113,7 +120,9 @@ jobs:
|
|
|
113
120
|
echo "Configured authenticated github.com remotes for pub."
|
|
114
121
|
- name: Prepare Flutter iOS project
|
|
115
122
|
if: ${{ steps.flutter.outputs.enabled == 'true' }}
|
|
116
|
-
shell:
|
|
123
|
+
shell: >-
|
|
124
|
+
python3 .github/actions/android-app/scripts/play_store_proxy.py
|
|
125
|
+
-- bash --noprofile --norc -e -o pipefail {0}
|
|
117
126
|
env:
|
|
118
127
|
ONBOARDING_PUBLIC_ORIGIN: ${{ vars.ONBOARDING_PUBLIC_ORIGIN }}
|
|
119
128
|
run: |
|
|
@@ -326,9 +335,15 @@ jobs:
|
|
|
326
335
|
distribution: temurin
|
|
327
336
|
java-version: ${{ steps.jdk.outputs.version }}
|
|
328
337
|
cache: gradle
|
|
338
|
+
- name: Require the Google proxy before Flutter SDK setup
|
|
339
|
+
if: ${{ steps.mode.outputs.mode == 'local' && steps.flutter.outputs.enabled == 'true' }}
|
|
340
|
+
shell: bash
|
|
341
|
+
run: python3 .github/actions/android-app/scripts/play_store_proxy.py --bootstrap-env
|
|
329
342
|
- name: Set up Flutter
|
|
330
343
|
if: ${{ steps.mode.outputs.mode == 'local' && steps.flutter.outputs.enabled == 'true' }}
|
|
331
344
|
uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2.23.0
|
|
345
|
+
env:
|
|
346
|
+
SEGMENT_DOWNLOAD_TIMEOUT_MINS: "1"
|
|
332
347
|
with:
|
|
333
348
|
channel: stable
|
|
334
349
|
cache: true
|
|
@@ -393,7 +408,9 @@ jobs:
|
|
|
393
408
|
# before anything analyses or compiles them. No-op for apps without l10n.
|
|
394
409
|
- name: Generate localizations
|
|
395
410
|
if: ${{ steps.mode.outputs.mode == 'local' && steps.flutter.outputs.enabled == 'true' }}
|
|
396
|
-
shell:
|
|
411
|
+
shell: >-
|
|
412
|
+
python3 .github/actions/android-app/scripts/play_store_proxy.py
|
|
413
|
+
-- bash --noprofile --norc -e -o pipefail {0}
|
|
397
414
|
run: |
|
|
398
415
|
if [ -f l10n.yaml ]; then
|
|
399
416
|
flutter pub get
|