ZapretKVN-android/scripts/create-test-bundle.sh
loop-uh 28bc460c95
All checks were successful
Android CI / build (push) Successful in 19m26s
Fix Hysteria2 transport preservation and diagnostics
2026-08-31 17:15:48 +03:00

122 lines
5 KiB
Shell
Executable file

#!/usr/bin/env bash
set -euo pipefail
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
TAG="${1:?test tag is required}"
MATRIX_DIR="${2:?debug APK matrix directory is required}"
OUTPUT_DIR="${3:?output directory is required}"
TESTED_APIS="${ZAPRET_TESTED_EMULATOR_APIS:-unknown}"
TEST_STATUS="${ZAPRET_TEST_STATUS:-compiled}"
ABIS=(arm64-v8a armeabi-v7a)
source "$PROJECT_ROOT/core.properties"
while IFS='=' read -r name value; do
case "$name" in
ZAPRET_VERSION_NAME|ZAPRET_VERSION_CODE|ZAPRET_PRERELEASE|ZAPRET_RELEASE_CHANNEL)
printf -v "$name" '%s' "$value"
;;
*) echo "Unexpected test version variable: $name" >&2; exit 1 ;;
esac
done < <("$PROJECT_ROOT/scripts/derive-test-version.sh" "$TAG")
if [[ "$ZAPRET_PRERELEASE" != true || "$ZAPRET_RELEASE_CHANNEL" != test ]]; then
echo "Only test prerelease bundles are accepted" >&2
exit 1
fi
for command in jq realpath sha256sum stat; do
command -v "$command" >/dev/null || { echo "Missing required command: $command" >&2; exit 1; }
done
[[ -d "$MATRIX_DIR" ]]
safe_output_root="$(realpath -m "$PROJECT_ROOT/build/local-test")"
resolved_output="$(realpath -m "$OUTPUT_DIR")"
[[ "$resolved_output" == "$safe_output_root/"* ]] || {
echo "Test bundle output must be below $safe_output_root" >&2
exit 1
}
if [[ -z "${ANDROID_HOME:-}" && -f "$PROJECT_ROOT/local.properties" ]]; then
ANDROID_HOME="$(sed -n 's/^sdk\.dir=//p' "$PROJECT_ROOT/local.properties" | tail -n 1)"
fi
: "${ANDROID_HOME:?ANDROID_HOME must point to an installed Android SDK}"
APKSIGNER="$ANDROID_HOME/build-tools/$ANDROID_BUILD_TOOLS/apksigner"
[[ -x "$APKSIGNER" ]]
mkdir -p "$OUTPUT_DIR"
find "$OUTPUT_DIR" -mindepth 1 -maxdepth 1 -type f -delete
artifacts='[]'
for abi in "${ABIS[@]}"; do
source_apk="$MATRIX_DIR/app-$abi-debug.apk"
apk_name="Zapret-KVN-$TAG-$abi-debug.apk"
target_apk="$OUTPUT_DIR/$apk_name"
[[ -f "$source_apk" ]] || { echo "Missing debug APK: $source_apk" >&2; exit 1; }
cp "$source_apk" "$target_apk"
digest="$(sha256sum "$target_apk" | awk '{print $1}')"
size="$(stat -c '%s' "$target_apk")"
printf '%s %s\n' "$digest" "$apk_name" > "$target_apk.sha256"
artifacts="$(jq -cn \
--argjson prior "$artifacts" \
--arg abi "$abi" \
--arg apk_file "$apk_name" \
--arg apk_sha256 "$digest" \
--argjson apk_size "$size" \
'$prior + [{abi:$abi,apk_file:$apk_file,apk_sha256:$apk_sha256,apk_size:$apk_size}]')"
done
first_apk="$OUTPUT_DIR/Zapret-KVN-$TAG-arm64-v8a-debug.apk"
signer_sha256="$("$APKSIGNER" verify --print-certs "$first_apk" \
| sed -n 's/^Signer #[0-9][0-9]* certificate SHA-256 digest: //p' \
| tr '[:upper:]' '[:lower:]' | tr -d ':[:space:]')"
[[ "$signer_sha256" =~ ^[0-9a-f]{64}$ ]]
jq -n \
--arg version_name "$ZAPRET_VERSION_NAME" \
--argjson version_code "$ZAPRET_VERSION_CODE" \
--arg source_commit "$(git -C "$PROJECT_ROOT" rev-parse HEAD)" \
--arg core_tag "$CORE_TAG" \
--arg core_commit "$CORE_COMMIT" \
--arg core_patch_sha256 "$CORE_PATCH_SHA256" \
--arg hysteria_core_tag "$HYSTERIA_CORE_TAG" \
--arg hysteria_core_commit "$HYSTERIA_CORE_COMMIT" \
--arg tested_apis "$TESTED_APIS" \
--arg test_status "$TEST_STATUS" \
--arg signer_sha256 "$signer_sha256" \
--argjson artifacts "$artifacts" \
'{
schema:1,
channel:"test",
emulator_only:true,
beta_updater_compatible:false,
application_id:"io.github.zapretkvn.android.debug",
build_type:"debug",
version_name:$version_name,
version_code:$version_code,
source_commit:$source_commit,
core_tag:$core_tag,
hysteria_core_tag:$hysteria_core_tag,
hysteria_core_commit:$hysteria_core_commit,
core_commit:$core_commit,
core_patch_sha256:$core_patch_sha256,
tested_emulator_apis:$tested_apis,
test_status:$test_status,
signer_sha256:$signer_sha256,
artifacts:$artifacts
}' > "$OUTPUT_DIR/build-metadata.json"
cat > "$OUTPUT_DIR/RELEASE_NOTES.md" <<EOF
# Zapret KVN $ZAPRET_VERSION_NAME
host/emulator-verified; physical Android device not verified.
Hysteria2 URI, TLS and diagnostics emulator-only test build.
- Embeds official Hysteria core/extras app/v2.12.2 for plain, Salamander and Gecko.
- Preserves the exact imported URI and uses a secret-safe transport fingerprint for subscription identity.
- Preserves certificate SHA-256 pinning, ECH, port hopping and Android-protected sockets; native JSON also supports custom CA and mTLS.
- Adds diagnostic schema v6 with attempt/stage/profile/outbound/protocol context and opaque endpoints.
- Uses synthetic test credentials only; Gecko is not confirmed on a physical Android device.
- Not a Stable or Beta-updater release.
- Not for F-Droid or Telegram distribution.
- Tested emulator APIs: $TESTED_APIS.
- Automated test status: $TEST_STATUS.
- Physical Pixel/device verification remains open.
EOF
echo "Test bundle created: $OUTPUT_DIR"