From 9b024ffcdcf6a7adb14f031ced94e03ab6ec2e79 Mon Sep 17 00:00:00 2001 From: Kurt Himebauch <136133082+xXJSONDeruloXx@users.noreply.github.com> Date: Sun, 1 Nov 2026 00:09:11 -0400 Subject: [PATCH] chore: quick_deploy reuses runtime assets prepared on another branch (#1934) --- app/build.gradle | 4 +++- tools/quick_deploy.sh | 3 ++- tools/release/runtime_inputs.py | 14 +++++++++++--- tools/tests/test_runtime_inputs.py | 13 +++++++++++++ 4 files changed, 29 insertions(+), 5 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 38c5d72b0..92b5a906e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -313,7 +313,9 @@ if (!ciBuild) { def verifyRuntimeInputs = tasks.register('verifyRuntimeInputs', Exec) { mustRunAfter(stageSessionScripts, stageRuntimeAssets) workingDir rootProject.projectDir - commandLine pythonExecutable, 'tools/release/runtime_inputs.py', 'verify' + def allowStale = (project.findProperty('allowStaleRuntime') + ?: localBuildOptions.getProperty('droiddeck.allowStaleRuntime', 'false')).toString().toBoolean() + commandLine([pythonExecutable, 'tools/release/runtime_inputs.py', 'verify'] + (allowStale ? ['--allow-stale-sources'] : [])) } tasks.configureEach { task -> if (task.name in ['packageDebug', 'packageRelease']) task.dependsOn(verifyRuntimeInputs) diff --git a/tools/quick_deploy.sh b/tools/quick_deploy.sh index 57e585c4a..5216ad740 100755 --- a/tools/quick_deploy.sh +++ b/tools/quick_deploy.sh @@ -23,7 +23,8 @@ while IFS= read -r dir; do done < <(ls -d "${sdk_dir}"/build-tools/* 2>/dev/null | sort -rV) [[ -n "${build_tools}" ]] || { echo "No build-tools with aapt, zipalign and apksigner under ${sdk_dir}." >&2; exit 1; } -./gradlew -q :app:assembleRelease +# Runtime assets from another branch are fine for a Kotlin/UI loop; CI and releases stay strict. +./gradlew -q -PallowStaleRuntime=true :app:assembleRelease ( cd "$(dirname "${signing_env}")" set -a; . "${signing_env}"; set +a diff --git a/tools/release/runtime_inputs.py b/tools/release/runtime_inputs.py index a375bbed5..4aefaa3da 100644 --- a/tools/release/runtime_inputs.py +++ b/tools/release/runtime_inputs.py @@ -149,13 +149,21 @@ def record(root=ROOT): (root / MANIFEST).write_text(json.dumps(data, sort_keys=True, indent=2) + '\n') -def verify(root=ROOT): +def verify(root=ROOT, stale_sources_ok=False): try: data = json.loads((root / MANIFEST).read_text()) except (OSError, ValueError): raise ValueError('Runtime inputs have not been prepared. Run tools/build_local.sh.') - if data.get('version') != 1 or data.get('sources') != sources(root): + if data.get('version') != 1: raise ValueError('Runtime sources changed since preparation. Run tools/build_local.sh.') + current = sources(root) + if data.get('sources') != current: + if not stale_sources_ok: + raise ValueError('Runtime sources changed since preparation. Run tools/build_local.sh.') + recorded = data.get('sources') or {} + changed = sorted(name for name in recorded.keys() | current.keys() if recorded.get(name) != current.get(name)) + print('Warning: reusing runtime assets prepared from other sources (run tools/build_local.sh if these matter):\n ' + + '\n '.join(changed[:20]) + ('\n ...' if len(changed) > 20 else ''), file=sys.stderr) for name in required(): if name not in data['outputs']: raise ValueError('Runtime manifest missing ' + name) @@ -224,7 +232,7 @@ if __name__ == '__main__': if sys.argv[1] == 'record': record() elif sys.argv[1] == 'verify': - verify() + verify(stale_sources_ok='--allow-stale-sources' in sys.argv[2:]) elif sys.argv[1] == 'apk': check_apk(sys.argv[2]) else: diff --git a/tools/tests/test_runtime_inputs.py b/tools/tests/test_runtime_inputs.py index 1ace64e40..ebb6cf97e 100644 --- a/tools/tests/test_runtime_inputs.py +++ b/tools/tests/test_runtime_inputs.py @@ -88,6 +88,19 @@ class RuntimeInputsTest(unittest.TestCase): with self.assertRaisesRegex(ValueError, 'sources changed'): runtime.verify(self.root) + def test_dev_loop_can_reuse_assets_from_other_sources(self): + runtime.record(self.root) + self.source.write_text('new implementation') + with mock.patch('sys.stderr', new_callable=io.StringIO) as stderr: + runtime.verify(self.root, stale_sources_ok=True) + self.assertIn('tools/linuxfs/preload/test.c', stderr.getvalue()) + + def test_dev_loop_still_rejects_changed_outputs(self): + runtime.record(self.root) + (self.root / 'app/src/main/jniLibs/arm64-v8a/libproot.so').write_bytes(b'old APK binary') + with self.assertRaisesRegex(ValueError, 'changed runtime input'): + runtime.verify(self.root, stale_sources_ok=True) + def test_changed_quest_source_rejects_old_outputs(self): source = self.root / 'tools/quest/kgsl_compat.c' source.parent.mkdir(parents=True)