Merge Reproducible Builds

This commit makes release builds reproducible. This will help folks update the app from F-Droid when it's released there.
This commit is contained in:
Balazs Toldi 2023-10-20 09:31:53 +02:00
parent 908f294130
commit c43ced8b00
No known key found for this signature in database
GPG Key ID: 6C7D440036F99D58
5 changed files with 90 additions and 5 deletions

View File

@ -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 ]

View File

@ -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

View File

@ -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, "")
}
}
}
}
}
}
}

View File

@ -24,8 +24,4 @@ allprojects {
maven { url "https://jitpack.io" }
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
}

32
scripts/fixEventBus.py Normal file
View File

@ -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)