Skip to content

Commit 1b8bfb5

Browse files
feat: ship hardened Windows and Android beta
1 parent 2c41522 commit 1b8bfb5

145 files changed

Lines changed: 15109 additions & 712 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/quality.yml

Lines changed: 180 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Windows quality gate
1+
name: Windows and Android quality gate
22

33
on:
44
push:
@@ -69,6 +69,15 @@ jobs:
6969
- name: Test the fail-closed translation-key audit
7070
run: pnpm run test:i18n
7171

72+
- name: Test the fail-closed Android libbox release-evidence generator
73+
run: pnpm run test:license-android-libbox-release
74+
75+
- name: Test the fail-closed Windows sing-box release-evidence generator
76+
run: pnpm run test:license-windows-sing-box-release
77+
78+
- name: Test the sysproxy corresponding-source evidence verifier
79+
run: pnpm run test:license-sysproxy
80+
7281
- name: Test final release extraction safety logic
7382
run: pnpm run test:verify-release
7483

@@ -85,3 +94,173 @@ jobs:
8594
env:
8695
AIKOBOX_ELECTRON_SMOKE_TOKEN: aikobox-github-windows-electron-smoke-v1
8796
run: pnpm run smoke:electron:ci
97+
98+
android-quality:
99+
name: Analyze, test, and compile (Android arm64-v8a)
100+
runs-on: ubuntu-latest
101+
timeout-minutes: 75
102+
env:
103+
ANDROID_COMPILE_SDK: '36'
104+
ANDROID_NDK_VERSION: 28.0.13004108
105+
ANDROID_APP_NDK_VERSION: 28.2.13676358
106+
ANDROID_BUILD_TOOLS: 36.0.0
107+
FLUTTER_VERSION: 3.44.4
108+
GO_VERSION: 1.24.7
109+
LIBBOX_COMMIT: 25a600db24f7680ad9806ce5427bd0ab8afe1114
110+
LIBBOX_GOMOBILE_VERSION: v0.1.12
111+
ANDROID_APPLICATION_ID: com.aikobox.app
112+
113+
steps:
114+
- name: Check out source
115+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
116+
with:
117+
persist-credentials: false
118+
119+
- name: Enable pnpm
120+
uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9
121+
with:
122+
version: 10.27.0
123+
run_install: false
124+
125+
- name: Set up Node.js
126+
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
127+
with:
128+
node-version: 22
129+
cache: pnpm
130+
131+
- name: Install verifier dependencies
132+
run: pnpm install --frozen-lockfile --ignore-scripts
133+
134+
- name: Verify the cross-platform release version contract
135+
shell: bash
136+
run: |
137+
set -euo pipefail
138+
node scripts/release-version-contract.mjs
139+
node --test scripts/release-version-contract.test.mjs
140+
141+
- name: Set up OpenJDK 17
142+
uses: actions/setup-java@03ad4de0992f5dab5e18fcb136590ce7c4a0ac95 # v5
143+
with:
144+
distribution: temurin
145+
java-version: '17'
146+
cache: gradle
147+
148+
- name: Set up Go 1.24.7
149+
uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6
150+
with:
151+
go-version: 1.24.7
152+
cache: false
153+
154+
- name: Install fixed Android SDK and NDK
155+
shell: bash
156+
run: |
157+
set -euo pipefail
158+
yes | sdkmanager --licenses >/dev/null
159+
sdkmanager \
160+
"platforms;android-${ANDROID_COMPILE_SDK}" \
161+
"build-tools;${ANDROID_BUILD_TOOLS}" \
162+
"ndk;${ANDROID_NDK_VERSION}" \
163+
"ndk;${ANDROID_APP_NDK_VERSION}"
164+
echo "ANDROID_NDK_HOME=${ANDROID_SDK_ROOT}/ndk/${ANDROID_NDK_VERSION}" >> "$GITHUB_ENV"
165+
echo "${ANDROID_SDK_ROOT}/build-tools/${ANDROID_BUILD_TOOLS}" >> "$GITHUB_PATH"
166+
167+
- name: Install Flutter 3.44.4
168+
shell: bash
169+
run: |
170+
set -euo pipefail
171+
metadata="$RUNNER_TEMP/flutter-releases.json"
172+
archive="$RUNNER_TEMP/flutter.tar.xz"
173+
curl --fail --location --retry 3 \
174+
https://storage.googleapis.com/flutter_infra_release/releases/releases_linux.json \
175+
--output "$metadata"
176+
archive_path="$(jq -r --arg version "$FLUTTER_VERSION" \
177+
'.releases[] | select(.channel == "stable" and .version == $version) | .archive' \
178+
"$metadata" | head -n1)"
179+
archive_sha="$(jq -r --arg version "$FLUTTER_VERSION" \
180+
'.releases[] | select(.channel == "stable" and .version == $version) | .sha256' \
181+
"$metadata" | head -n1)"
182+
test "$archive_path" = "stable/linux/flutter_linux_${FLUTTER_VERSION}-stable.tar.xz"
183+
test "$archive_sha" != "null" && test -n "$archive_sha"
184+
curl --fail --location --retry 3 \
185+
"https://storage.googleapis.com/flutter_infra_release/releases/${archive_path}" \
186+
--output "$archive"
187+
printf '%s %s\n' "$archive_sha" "$archive" | sha256sum --check -
188+
tar -xJf "$archive" -C "$RUNNER_TEMP"
189+
echo "$RUNNER_TEMP/flutter/bin" >> "$GITHUB_PATH"
190+
191+
- name: Verify fixed toolchain versions
192+
shell: bash
193+
run: |
194+
set -euo pipefail
195+
java --version 2>&1 | tee /tmp/java-version
196+
grep -E 'openjdk 17(\.| )' /tmp/java-version
197+
test "$(go env GOVERSION)" = "go${GO_VERSION}"
198+
flutter --version --machine > /tmp/flutter-version.json
199+
test "$(jq -r .frameworkVersion /tmp/flutter-version.json)" = "${FLUTTER_VERSION}"
200+
test -f "${ANDROID_NDK_HOME}/source.properties"
201+
grep -F "Pkg.Revision = ${ANDROID_NDK_VERSION}" "${ANDROID_NDK_HOME}/source.properties"
202+
grep -F "Pkg.Revision = ${ANDROID_APP_NDK_VERSION}" \
203+
"${ANDROID_SDK_ROOT}/ndk/${ANDROID_APP_NDK_VERSION}/source.properties"
204+
205+
- name: Build the locked arm64 libbox AAR
206+
shell: bash
207+
run: |
208+
set -euo pipefail
209+
git clone --filter=blob:none https://github.com/SagerNet/sing-box.git "$RUNNER_TEMP/sing-box"
210+
git -C "$RUNNER_TEMP/sing-box" checkout --detach "${LIBBOX_COMMIT}"
211+
test "$(git -C "$RUNNER_TEMP/sing-box" rev-parse HEAD)" = "${LIBBOX_COMMIT}"
212+
go install "github.com/sagernet/gomobile/cmd/gomobile@${LIBBOX_GOMOBILE_VERSION}"
213+
go install "github.com/sagernet/gomobile/cmd/gobind@${LIBBOX_GOMOBILE_VERSION}"
214+
(
215+
cd "$RUNNER_TEMP/sing-box"
216+
go run ./cmd/internal/build_libbox -target android -platform android/arm64
217+
)
218+
mkdir -p apps/android/android/app/libs
219+
cp "$RUNNER_TEMP/sing-box/libbox.aar" apps/android/android/app/libs/libbox.aar
220+
unzip -Z1 apps/android/android/app/libs/libbox.aar | tee /tmp/libbox-aar.txt
221+
test "$(grep -Ec '^jni/[^/]+/libbox\.so$' /tmp/libbox-aar.txt)" -eq 1
222+
grep -Fx 'jni/arm64-v8a/libbox.so' /tmp/libbox-aar.txt
223+
test -z "$(grep -E '^jni/[^/]+/.*\.so$' /tmp/libbox-aar.txt | grep -v '^jni/arm64-v8a/' || true)"
224+
225+
- name: Analyze and test Flutter application
226+
working-directory: apps/android
227+
shell: bash
228+
run: |
229+
set -euo pipefail
230+
chmod +x android/gradlew
231+
flutter pub get --enforce-lockfile
232+
flutter analyze --fatal-infos --fatal-warnings
233+
flutter test
234+
./android/gradlew -p android lintDebug testDebugUnitTest
235+
236+
- name: Build signed debug APK for the quality gate
237+
working-directory: apps/android
238+
shell: bash
239+
run: |
240+
set -euo pipefail
241+
version="$(jq -r .version ../../package.json)"
242+
version_code="$(sed -n 's/^version: [^+]*+\([0-9][0-9]*\)$/\1/p' pubspec.yaml)"
243+
test -n "$version_code"
244+
flutter build apk \
245+
--debug \
246+
--target-platform android-arm64 \
247+
--build-name "$version" \
248+
--build-number "$version_code"
249+
apk="$(realpath build/app/outputs/flutter-apk/app-debug.apk)"
250+
sidecar="${apk}.sha256"
251+
digest="$(sha256sum "$apk" | cut -d' ' -f1)"
252+
printf '%s %s\n' "$digest" "$(basename "$apk")" > "$sidecar"
253+
signer_output="$(apksigner verify --verbose --print-certs "$apk")"
254+
certificate="$(printf '%s\n' "$signer_output" | sed -n 's/^Signer #1 certificate SHA-256 digest: //p')"
255+
node ../../scripts/verify-android-release.mjs \
256+
--apk "$apk" \
257+
--sha256 "$sidecar" \
258+
--apkanalyzer "$(command -v apkanalyzer)" \
259+
--apksigner "$(command -v apksigner)" \
260+
--application-id "$ANDROID_APPLICATION_ID" \
261+
--certificate-sha256 "$certificate" \
262+
--version "$version" \
263+
--version-code "$version_code"
264+
265+
- name: Test the Android release verifier
266+
run: node --test scripts/verify-android-release.test.mjs

0 commit comments

Comments
 (0)