Files
matrix-screen-controller/移动端相关内容/安卓app/构建与发布/package_debug.py
T

66 lines
3.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Package an independently built debug APK without overwriting an old delivery."""
import argparse
import hashlib
import json
from pathlib import Path
import re
import shutil
import subprocess
import tomllib
def digest(path):
return hashlib.sha256(path.read_bytes()).hexdigest()
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--build', type=Path, required=True)
parser.add_argument('--sdk', type=Path, required=True)
args = parser.parse_args()
root = Path(__file__).resolve().parent
source = root.parent / '安卓程序源代码'
config = (source / 'androidApp/build.gradle.kts').read_text(encoding='utf-8')
version = re.search(r'versionName = "([^"]+)"', config)[1]
code = int(re.search(r'versionCode = (\d+)', config)[1])
entries = []
for path in sorted(source.rglob('*')):
relative = path.relative_to(source)
if not path.is_file() or any(p in {'build', '.gradle', '.kotlin'} for p in relative.parts) or path.name == 'local.properties':
continue
built = args.build / relative
if not built.is_file() or digest(built) != digest(path):
raise RuntimeError('Build source differs from current source: ' + relative.as_posix())
entries.append(dict(path=relative.as_posix(), sha256=digest(path)))
apk = args.build / 'androidApp/build/outputs/apk/debug/androidApp-debug.apk'
signer = args.sdk / 'build-tools/36.0.0/apksigner.bat'
result = subprocess.run([str(signer), 'verify', '--print-certs', str(apk)],
capture_output=True, text=True, encoding='utf-8', errors='replace')
if result.returncode or 'CN=Android Debug' not in result.stdout:
raise RuntimeError('APK must verify with the existing Android Debug certificate')
certificate = re.search(r'certificate SHA-256 digest: ([0-9a-fA-F]+)', result.stdout)[1].lower()
destination = root / '交付包' / f'{version}-{code}'
destination.mkdir(parents=True, exist_ok=False)
name = f'奇妙小屏幕-{version}-debug.apk'
shutil.copyfile(apk, destination / name)
versions = tomllib.loads((source / 'gradle/libs.versions.toml').read_text(encoding='utf-8'))['versions']
build_config = (args.build / 'androidApp/build/generated/source/buildConfig/debug/org/qimiaoscreen/controller/BuildConfig.java').read_text(encoding='utf-8')
build_date = re.search(r'BUILD_DATE = "([^"]+)"', build_config)[1]
manifest = dict(app_version=version, version_code=code, signing='debug', build_date=build_date,
status='development-validation-see-test-report', apk_sha256=digest(apk),
certificate_sha256=certificate, protocol_major=1, protocol_minor=2, minimum_android_api=26,
target_android_api=37, build_tools='36.0.0', toolchain=versions, sources=entries)
(destination / 'manifest.json').write_text(json.dumps(manifest, ensure_ascii=False, indent=2) + '\n', encoding='utf-8')
(destination / 'SHA256SUMS').write_text(f'{digest(apk)} {name}\n', encoding='utf-8')
(destination / 'README.md').write_text(
f'# 奇妙小屏幕 {version} debug(versionCode {code})\n\n'
'仅 debug 签名,可覆盖安装相同调试证书的旧包。Android 8.0 以上,真实验证机为 Android 13。\n\n'
'本包为当前开发验证产物;验收范围和未验证项见 `../../../测试结果归档/实施状态.md`。'
'不能将 APK 成功生成视为所有首版验收通过。设备需已部署移动控制功能,历史设备版本号本身不代表支持 BLE。\n\n'
f'SHA-256:`{digest(apk)}`。源码摘要与签名证书摘要见 manifest.json。\n', encoding='utf-8')
print(json.dumps(dict(delivery=destination.relative_to(root).as_posix(), apk_sha256=digest(apk), certificate_sha256=certificate), ensure_ascii=False))
if __name__ == '__main__':
main()