1- name : Bump Version
1+ name : Reproducible Build Check
22
33on :
44 push :
5- branches :
6- - staging-release
7- - staging-release-*
8- workflow_dispatch :
5+ branches : [ "staging" ]
96
107jobs :
11- bump-version :
8+ build-1 :
9+ name : Build 1
1210 runs-on : ubuntu-latest
11+ steps :
12+ - name : Checkout repository
13+ uses : actions/checkout@v4
14+
15+ - name : Build Docker image
16+ working-directory : ci
17+ run : docker build -t deku_rep_build_release .
18+
19+ - name : Build APK
20+ run : |
21+ docker run --rm \
22+ -v "$(pwd)":/project \
23+ -w /project \
24+ --user "$(id -u):$(id -g)" \
25+ -e ANDROID_USER_HOME=/project/.android \
26+ -e GRADLE_USER_HOME=/project/.gradle \
27+ deku_rep_build_release \
28+ ./gradlew assembleRelease \
29+ --no-daemon \
30+ --max-workers=2 \
31+ --console=plain \
32+ -Dorg.gradle.jvmargs="-Xmx2048m -Xms512m -XX:MaxMetaspaceSize=512m -Dfile.encoding=UTF-8" \
33+ -Dkotlin.daemon.jvm.options="-Xmx512m,-Xss1m" \
34+ -Dkotlin.compiler.execution.strategy=in-process
35+
36+ - name : Upload APK
37+ uses : actions/upload-artifact@v4
38+ with :
39+ name : apk-build-1
40+ path : app/build/outputs/apk/release/app-release-unsigned.apk
41+ retention-days : 1
42+
43+ build-2 :
44+ name : Build 2
45+ runs-on : ubuntu-latest
46+ steps :
47+ - name : Checkout repository
48+ uses : actions/checkout@v4
49+
50+ - name : Build Docker image
51+ working-directory : ci
52+ run : docker build -t deku_rep_build_release .
53+
54+ - name : Build APK
55+ run : |
56+ docker run --rm \
57+ -v "$(pwd)":/project \
58+ -w /project \
59+ --user "$(id -u):$(id -g)" \
60+ -e ANDROID_USER_HOME=/project/.android \
61+ -e GRADLE_USER_HOME=/project/.gradle \
62+ deku_rep_build_release \
63+ ./gradlew assembleRelease \
64+ --no-daemon \
65+ --max-workers=2 \
66+ --console=plain \
67+ -Dorg.gradle.jvmargs="-Xmx2048m -Xms512m -XX:MaxMetaspaceSize=512m -Dfile.encoding=UTF-8" \
68+ -Dkotlin.daemon.jvm.options="-Xmx512m,-Xss1m" \
69+ -Dkotlin.compiler.execution.strategy=in-process
70+
71+ - name : Upload APK
72+ uses : actions/upload-artifact@v4
73+ with :
74+ name : apk-build-2
75+ path : app/build/outputs/apk/release/app-release-unsigned.apk
76+ retention-days : 1
77+
78+ compare :
79+ name : Compare APKs
80+ runs-on : ubuntu-latest
81+ needs : [ build-1, build-2 ]
82+ steps :
83+ - name : Download APK from build 1
84+ uses : actions/download-artifact@v4
85+ with :
86+ name : apk-build-1
87+ path : apk-build-1
88+
89+ - name : Download APK from build 2
90+ uses : actions/download-artifact@v4
91+ with :
92+ name : apk-build-2
93+ path : apk-build-2
94+
95+ - name : Compare hashes
96+ id : compare
97+ run : |
98+ SHA1=$(sha256sum apk-build-1/app-release-unsigned.apk | awk '{ print $1 }')
99+ SHA2=$(sha256sum apk-build-2/app-release-unsigned.apk | awk '{ print $1 }')
100+ echo "Build 1: $SHA1"
101+ echo "Build 2: $SHA2"
102+ if [ "$SHA1" = "$SHA2" ]; then
103+ echo "✅ Reproducible build verified — hashes match."
104+ echo "reproducible=true" >> "$GITHUB_OUTPUT"
105+ else
106+ echo "❌ Build is NOT reproducible — hashes differ!"
107+ echo "reproducible=false" >> "$GITHUB_OUTPUT"
108+ fi
109+
110+ - name : Install diffoscope
111+ if : steps.compare.outputs.reproducible == 'false'
112+ run : |
113+ sudo apt-get update -qq
114+ sudo apt-get install -y diffoscope
115+
116+ - name : Run diffoscope
117+ if : steps.compare.outputs.reproducible == 'false'
118+ run : |
119+ diffoscope \
120+ --text diffoscope-report.txt \
121+ --html diffoscope-report.html \
122+ apk-build-1/app-release-unsigned.apk \
123+ apk-build-2/app-release-unsigned.apk || true
124+
125+ - name : Upload diffoscope report
126+ if : steps.compare.outputs.reproducible == 'false'
127+ uses : actions/upload-artifact@v4
128+ with :
129+ name : diffoscope-report
130+ path : |
131+ diffoscope-report.txt
132+ diffoscope-report.html
133+ retention-days : 7
134+
135+ - name : Fail if not reproducible
136+ if : steps.compare.outputs.reproducible == 'false'
137+ run : |
138+ echo "See the diffoscope-report artifact for a full breakdown of differences."
139+ exit 1
140+
141+ bump-version-and-pr :
142+ name : Bump Version and Open PR to master
143+ runs-on : ubuntu-latest
144+ needs : [ compare ]
13145 permissions :
14146 contents : write
15147 pull-requests : write
16-
17- defaults :
18- run :
19- working-directory : ${{ github.workspace }}
20-
21148 steps :
22149 - name : Checkout repository
23150 uses : actions/checkout@v4
24151 with :
25152 fetch-depth : 0
26153 token : ${{ secrets.GITHUB_TOKEN }}
27- ref : ${{ github.ref }}
28-
29- - name : Get current branch name
30- id : branch
31- run : echo "name=${GITHUB_REF#refs/heads/}" >> $GITHUB_OUTPUT
154+ ref : staging
32155
33156 - name : Get latest tag
34157 id : previoustag
44167 - name : Verify version.properties exists
45168 run : |
46169 if [ ! -f version.properties ]; then
47- echo "ERROR: version.properties not found in ${{ github.workspace }} "
170+ echo "ERROR: version.properties not found"
48171 ls -la
49172 exit 1
50173 fi
56179 run : |
57180 python ci/bump_version.py \
58181 "${{ steps.previoustag.outputs.tag }}" \
59- "${{ steps.branch.outputs.name }} " \
182+ "staging " \
60183 > /tmp/version_bumped.properties
61184 cp /tmp/version_bumped.properties version.properties
62185 echo "result<<EOF" >> $GITHUB_OUTPUT
@@ -69,29 +192,28 @@ jobs:
69192 git config user.email "github-actions[bot]@users.noreply.github.com"
70193 git add version.properties
71194 git diff --cached --quiet || git commit -m "chore: bump version [skip ci]"
72- git push origin HEAD:${{ steps.branch.outputs.name }}
195+ git push origin HEAD:staging
73196
74197 - name : Open or update PR to master
75198 env :
76199 GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
77200 run : |
78- PR_BODY="Automated version bump from \`${{ steps.branch.outputs.name }}\`
201+ PR_BODY="Automated version bump from \`staging\` — reproducible build verified ✅
79202
80203 **version.properties:**
81204 \`\`\`
82205 ${{ steps.bump.outputs.result }}
83206 \`\`\`"
84207
85- # Try to create, if it already exists update the body instead
86208 if gh pr create \
87- --base staging \
88- --head "${{ steps.branch.outputs.name }}" \
89- --title "release: bump version (${{ steps.previoustag.outputs.tag }} → ${{ steps.branch.outputs.name }} )" \
209+ --base master \
210+ --head staging \
211+ --title "release: bump version (${{ steps.previoustag.outputs.tag }} → staging )" \
90212 --body "$PR_BODY"; then
91213 echo "PR created"
92214 else
93215 echo "PR already exists, updating body..."
94- gh pr edit "${{ steps.branch.outputs.name }}" \
95- --title "release: bump version (${{ steps.previoustag.outputs.tag }} → ${{ steps.branch.outputs.name }} )" \
216+ gh pr edit staging \
217+ --title "release: bump version (${{ steps.previoustag.outputs.tag }} → staging )" \
96218 --body "$PR_BODY"
97219 fi
0 commit comments