From c43ced8b008492ae839e43786ea5443f8cdacd63 Mon Sep 17 00:00:00 2001 From: Balazs Toldi Date: Fri, 20 Oct 2023 09:31:53 +0200 Subject: [PATCH] Merge Reproducible Builds This commit makes release builds reproducible. This will help folks update the app from F-Droid when it's released there. --- .woodpecker/build.yaml | 1 + .woodpecker/nightly.yaml | 1 + app/build.gradle | 55 ++++++++++++++++++++++++++++++++++++++++ build.gradle | 6 +---- scripts/fixEventBus.py | 32 +++++++++++++++++++++++ 5 files changed, 90 insertions(+), 5 deletions(-) create mode 100644 scripts/fixEventBus.py diff --git a/.woodpecker/build.yaml b/.woodpecker/build.yaml index 7df8928d..9e0e30fc 100644 --- a/.woodpecker/build.yaml +++ b/.woodpecker/build.yaml @@ -2,6 +2,7 @@ steps: build: image: alvrme/alpine-android:android-33-jdk11 commands: + - apk add --no-cache python3 - ./gradlew :app:assembleRelease when: path: [ app/**, build.gradle ] diff --git a/.woodpecker/nightly.yaml b/.woodpecker/nightly.yaml index 9c90e61f..36c306d1 100644 --- a/.woodpecker/nightly.yaml +++ b/.woodpecker/nightly.yaml @@ -8,6 +8,7 @@ steps: build: image: alvrme/alpine-android:android-33-jdk11 commands: + - apk add --no-cache python3 - ./gradlew :app:assembleNightly sign: image: alvrme/alpine-android:android-33-jdk11 diff --git a/app/build.gradle b/app/build.gradle index c9d7175e..234240d3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -98,6 +98,30 @@ android { doNotStrip '**/*.so' } namespace 'eu.toldi.infinityforlemmy' + + + task rearrangeClass(type: Exec) { + commandLine 'python', '../scripts/fixEventBus.py' + } + + applicationVariants.all { variant -> + if (variant.name == 'release') { + task("compileSingleFile${variant.name.capitalize()}", type: JavaCompile, dependsOn: rearrangeClass) { + def filePath = project.rootDir.absolutePath + '/app/build/generated/ap_generated_sources/release/out/eu/toldi/infinityforlemmy/' + source = files(filePath) + includes = ["**/EventBusIndex.java"] + classpath = variant.getCompileClasspath() + files(project.rootDir.absolutePath + '/app/build/intermediates/javac/release/classes') + destinationDir = file("$buildDir/intermediates/javac/release/classes") + } + + tasks.withType(JavaCompile).all { task -> + if (task.name == 'compileReleaseJavaWithJavac') { + task.finalizedBy "compileSingleFile${variant.name.capitalize()}" + } + } + } + } + } dependencies { @@ -246,3 +270,34 @@ dependencies { //debugImplementation 'com.squareup.leakcanary:leakcanary-android:x.y' } +// NB: Android Studio can't find the imports; this does not affect the +// actual build since Gradle can find them just fine. + +import com.android.tools.profgen.ArtProfileKt +import com.android.tools.profgen.ArtProfileSerializer +import com.android.tools.profgen.DexFile + +project.afterEvaluate { + tasks.each { task -> + if (task.name.startsWith("compile") && task.name.endsWith("ReleaseArtProfile")) { + task.doLast { + outputs.files.each { file -> + if (file.name.endsWith(".profm")) { + println("Sorting ${file} ...") + def version = ArtProfileSerializer.valueOf("METADATA_0_0_2") + def profile = ArtProfileKt.ArtProfile(file) + def keys = new ArrayList(profile.profileData.keySet()) + def sortedData = new LinkedHashMap() + Collections.sort keys, new DexFile.Companion() + keys.each { key -> sortedData[key] = profile.profileData[key] } + new FileOutputStream(file).with { + write(version.magicBytes$profgen) + write(version.versionBytes$profgen) + version.write$profgen(it, sortedData, "") + } + } + } + } + } + } +} \ No newline at end of file diff --git a/build.gradle b/build.gradle index 4eb65b79..e3cc6ea7 100644 --- a/build.gradle +++ b/build.gradle @@ -24,8 +24,4 @@ allprojects { maven { url "https://jitpack.io" } jcenter() } -} - -task clean(type: Delete) { - delete rootProject.buildDir -} +} \ No newline at end of file diff --git a/scripts/fixEventBus.py b/scripts/fixEventBus.py new file mode 100644 index 00000000..b927f7a6 --- /dev/null +++ b/scripts/fixEventBus.py @@ -0,0 +1,32 @@ +import re +import sys + + +def rearrange(filename): + with open(filename, 'r') as file: + content = file.read() + + # Regex to find the blocks of code to rearrange + pattern = re.compile(r'(putIndex\(new SimpleSubscriberInfo\(.*?\)\);)', re.DOTALL) + blocks = pattern.findall(content) + + # Sort blocks based on the class names mentioned in SimpleSubscriberInfo instances + sorted_blocks = sorted(blocks, key=lambda x: re.search(r'SimpleSubscriberInfo\((.*?),', x).group(1)) + + # Replace the original blocks with the sorted blocks + sorted_content = pattern.sub(lambda match: sorted_blocks.pop(0), content) + + with open(filename, 'w') as file: + file.write(sorted_content) + + +# Project root relative to the script +project_root = __file__[:-len('/scripts/fixEventBus.py')] + +path = './build/generated/ap_generated_sources/release/out/eu/toldi/infinityforlemmy/EventBusIndex.java' + +# Print the path to the file to stderr +print(path, file=sys.stderr) + +# Call the function with the path to EventBusIndex.java +rearrange(path)