#!/usr/bin/env python3 """Check this release's build pins and plugin IDs; NOT Gradle/Kotlin type checking.""" from pathlib import Path import hashlib import re ROOT = Path(__file__).resolve().parent.parent checks = 0 def verify(condition, message): global checks if not condition: raise SystemExit("FAIL build configuration: " + message) checks += 1 print("PASS " + message) def text(name): return (ROOT / name).read_text(encoding="utf-8") def properties(name): return dict(line.split("=", 1) for line in text(name).splitlines() if "=" in line and not line.lstrip().startswith("#")) DIST = "6f74b601422d6d6fc4e1f9a1ab6522f642c2fdcbc15ae33ebd30ba3d7198e854" JAR = "7d3a4ac4de1c32b59bc6a4eb8ecb8e612ccd0cf1ae1e99f66902da64df296172" wrapper = properties("gradle/wrapper/gradle-wrapper.properties") verify(wrapper["distributionUrl"].replace(chr(92), "") == "https://services.gradle.org/distributions/gradle-8.14.5-bin.zip", "Gradle distribution is exactly 8.14.5") verify(wrapper["distributionSha256Sum"] == DIST, "official 8.14.5 distribution SHA-256 is pinned") for script in ["scripts/bootstrap-wrapper.sh", "scripts/bootstrap-wrapper.ps1"]: content = text(script) verify(JAR in content and DIST in content and "v8.14.5/" in content and "gradle-8.14.5-bin.zip" in content and "8.13" not in content, script + " uses matching 8.14.5 downloads and hashes") verify(properties("gradle/gradle-daemon-jvm.properties").get("toolchainVersion") == "17", "Gradle daemon requires JDK 17") verify(text(".java-version").strip() == "17", "Java-version hint is 17") verify("JavaVersion.VERSION_17" in text("settings.gradle.kts") and 'gradle.gradleVersion == "8.14.5"' in text("settings.gradle.kts"), "settings reject conflicting Gradle/JVM overrides") for module in ["androidApp", "core", "platform-jvm"]: verify("jvmToolchain(17)" in text(module + "/build.gradle.kts"), module + " uses toolchain 17") android = text("androidApp/build.gradle.kts") verify("sourceCompatibility = JavaVersion.VERSION_17" in android and "targetCompatibility = JavaVersion.VERSION_17" in android, "Android Java bytecode targets 17") verify('versionName = "0.2.3"' in android and "versionCode = 5" in android, "application version is 0.2.3/code 5") # Deliberately limited to the project's simple version-catalog/alias structure. root_build = text("build.gradle.kts") catalog = text("gradle/libs.versions.toml") plugin_section = catalog.split("[plugins]", 1)[1] entries = re.findall(r'^([\w-]+)\s*=\s*\{\s*id\s*=\s*"([^"]+)"', plugin_section, re.M) ids = dict(entries) aliases = [a.replace(".", "-") for a in re.findall(r'alias\(libs\.plugins\.([\w.]+)\)', root_build)] expected = {"com.android.application", "org.jetbrains.kotlin.android", "org.jetbrains.kotlin.multiplatform", "org.jetbrains.kotlin.jvm", "org.jetbrains.kotlin.plugin.compose"} resolved = [ids.get(a) for a in aliases] verify(len(entries) == len(ids) == 5 and len(resolved) == 5 and set(resolved) == expected, "five root plugin aliases resolve to five distinct expected IDs") verify(not re.search(r'\b(?:id|kotlin)\s*\(', root_build), "root has no extra direct plugin requests") verify('kotlin = "2.2.21"' in catalog and 'agp = "8.11.1"' in catalog, "Kotlin/AGP versions are unchanged") verify("java-version: '17'" in text(".github/workflows/verify.yml"), "existing CI uses Java 17") verify("[SAF-D1/NULL_CURSOR]" in text("androidApp/src/main/kotlin/dev/fileworkbench/android/browser/SafBrowserStore.kt") and "Fileworkbench 0.2.3 ยท Browser diagnostics SAF-D1" in text("androidApp/src/main/kotlin/dev/fileworkbench/android/ui/BrowserScreen.kt"), "source contains the diagnostic error and visible release marker") verify("org.gradle.java.home" not in properties("gradle.properties"), "tracked Gradle properties contain no machine-specific JDK home") jar = ROOT / "gradle/wrapper/gradle-wrapper.jar" if jar.exists(): verify(hashlib.sha256(jar.read_bytes()).hexdigest() == JAR, "bundled official wrapper JAR matches its checksum") else: print("INFO wrapper JAR is not bundled; the first wrapper launch bootstraps the verified binary.") print(f"Build-configuration checks: {checks} passed. Source checks only, not an Android build.")