gowalk-cicd 1.0.67 → 1.0.68
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 +7 -0
- package/README.md +4 -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 +8 -1
- package/templates/deploy.yml +14 -2
package/CLAUDE.md
CHANGED
|
@@ -128,6 +128,13 @@ 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.
|
|
131
138
|
- Backend runtime credentials use the single encrypted `BACKEND_RUNTIME_ENV`
|
|
132
139
|
secret. The action writes it to host-side `.runtime.env` with mode 0600 and
|
|
133
140
|
supplies it to Compose after the generated `.env`; never print its content.
|
package/README.md
CHANGED
|
@@ -634,6 +634,10 @@ metadata and binary transfer. Provision `APPLE_STORE_PROXY_URL` and
|
|
|
634
634
|
`GOOGLE_STORE_PROXY_URL` as encrypted repository secrets before deployment. A missing
|
|
635
635
|
proxy refuses provider calls; there is no direct fallback. Refresh existing workflow
|
|
636
636
|
files with the released installer while preserving application-specific build inputs.
|
|
637
|
+
The Google pin also covers Flutter SDK manifest/archive downloads and early `pub`
|
|
638
|
+
operations in iOS, Android and web workflows. Bootstrap validates it before SDK setup;
|
|
639
|
+
subsequent Dart and JVM operations use the same owned relay as release builds. A fork
|
|
640
|
+
without the repository secret cannot start provider downloads through these workflows.
|
|
637
641
|
The Apple uploader retains `apple-upload-<run>-<attempt>` receipts with IPA SHA-256,
|
|
638
642
|
upload ID and processing readback, and resumes matching bytes after interruption.
|
|
639
643
|
|
package/action/.daemux-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.0.
|
|
1
|
+
1.0.68
|
|
@@ -1 +1 @@
|
|
|
1
|
-
1.0.
|
|
1
|
+
1.0.68
|
|
@@ -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.68
|
package/package.json
CHANGED
package/templates/deploy-web.yml
CHANGED
|
@@ -26,8 +26,13 @@ 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
|
|
32
37
|
with:
|
|
33
38
|
channel: stable
|
|
@@ -45,7 +50,9 @@ jobs:
|
|
|
45
50
|
git config --global \
|
|
46
51
|
url."https://x-access-token:${GIT_PRIVATE_TOKEN}@github.com/".insteadOf "https://github.com/"
|
|
47
52
|
- name: Build Flutter web release
|
|
48
|
-
shell:
|
|
53
|
+
shell: >-
|
|
54
|
+
python3 .github/actions/android-app/scripts/play_store_proxy.py
|
|
55
|
+
-- bash --noprofile --norc -e -o pipefail {0}
|
|
49
56
|
run: |
|
|
50
57
|
flutter pub get
|
|
51
58
|
if [ -f l10n.yaml ]; then flutter gen-l10n; fi
|
package/templates/deploy.yml
CHANGED
|
@@ -77,6 +77,10 @@ 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
|
|
@@ -113,7 +117,9 @@ jobs:
|
|
|
113
117
|
echo "Configured authenticated github.com remotes for pub."
|
|
114
118
|
- name: Prepare Flutter iOS project
|
|
115
119
|
if: ${{ steps.flutter.outputs.enabled == 'true' }}
|
|
116
|
-
shell:
|
|
120
|
+
shell: >-
|
|
121
|
+
python3 .github/actions/android-app/scripts/play_store_proxy.py
|
|
122
|
+
-- bash --noprofile --norc -e -o pipefail {0}
|
|
117
123
|
env:
|
|
118
124
|
ONBOARDING_PUBLIC_ORIGIN: ${{ vars.ONBOARDING_PUBLIC_ORIGIN }}
|
|
119
125
|
run: |
|
|
@@ -326,6 +332,10 @@ jobs:
|
|
|
326
332
|
distribution: temurin
|
|
327
333
|
java-version: ${{ steps.jdk.outputs.version }}
|
|
328
334
|
cache: gradle
|
|
335
|
+
- name: Require the Google proxy before Flutter SDK setup
|
|
336
|
+
if: ${{ steps.mode.outputs.mode == 'local' && steps.flutter.outputs.enabled == 'true' }}
|
|
337
|
+
shell: bash
|
|
338
|
+
run: python3 .github/actions/android-app/scripts/play_store_proxy.py --bootstrap-env
|
|
329
339
|
- name: Set up Flutter
|
|
330
340
|
if: ${{ steps.mode.outputs.mode == 'local' && steps.flutter.outputs.enabled == 'true' }}
|
|
331
341
|
uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2.23.0
|
|
@@ -393,7 +403,9 @@ jobs:
|
|
|
393
403
|
# before anything analyses or compiles them. No-op for apps without l10n.
|
|
394
404
|
- name: Generate localizations
|
|
395
405
|
if: ${{ steps.mode.outputs.mode == 'local' && steps.flutter.outputs.enabled == 'true' }}
|
|
396
|
-
shell:
|
|
406
|
+
shell: >-
|
|
407
|
+
python3 .github/actions/android-app/scripts/play_store_proxy.py
|
|
408
|
+
-- bash --noprofile --norc -e -o pipefail {0}
|
|
397
409
|
run: |
|
|
398
410
|
if [ -f l10n.yaml ]; then
|
|
399
411
|
flutter pub get
|