Skip to content

Commit 737d680

Browse files
Merge pull request #518 from dekusms/staging
New release: bump version (0.73.0)
2 parents b1269a0 + 3863778 commit 737d680

13 files changed

Lines changed: 305 additions & 284 deletions

File tree

.github/workflows/playstore-release.yml

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -75,18 +75,15 @@ jobs:
7575
-Dkotlin.daemon.jvm.options="-Xmx512m,-Xss1m" \
7676
-Dkotlin.compiler.execution.strategy=in-process
7777
78-
- name: Sign AAB with apksigner
78+
- name: Sign AAB with jarsigner
7979
run: |
80-
BUILD_TOOLS=$(ls $ANDROID_HOME/build-tools | sort -V | tail -1)
81-
$ANDROID_HOME/build-tools/$BUILD_TOOLS/apksigner sign \
82-
--ks ${{ github.workspace }}/release.keystore \
83-
--ks-type JKS \
84-
--ks-key-alias "${{ secrets.KEY_ALIAS }}" \
85-
--ks-pass pass:"${{ secrets.STORE_PASSWORD }}" \
86-
--key-pass pass:"${{ secrets.KEY_PASSWORD }}" \
87-
--out app/build/outputs/bundle/release/app-release-signed.aab \
88-
--min-sdk-version 24 \
89-
app/build/outputs/bundle/release/app-release.aab
80+
# Use jarsigner (standard JDK tool) instead of apksigner for AAB bundles
81+
jarsigner -keystore ${{ github.workspace }}/release.keystore \
82+
-storepass "${{ secrets.STORE_PASSWORD }}" \
83+
-keypass "${{ secrets.KEY_PASSWORD }}" \
84+
-signedjar app/build/outputs/bundle/release/app-release-signed.aab \
85+
app/build/outputs/bundle/release/app-release.aab \
86+
"${{ secrets.KEY_ALIAS }}"
9087
9188
- name: Set up Python
9289
uses: actions/setup-python@v5

.github/workflows/reproducible-build-check-release.yml

Lines changed: 83 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ on:
66

77
jobs:
88
build-1:
9-
name: Build 1 (signed)
9+
name: Build 1 (signed splits)
1010
runs-on: ubuntu-latest
1111
environment: production
1212
steps:
@@ -20,14 +20,12 @@ jobs:
2020
echo "Keystore file is empty — check the KEYSTORE_BASE64 secret."
2121
exit 1
2222
fi
23-
ls -lh ${{ github.workspace }}/release.keystore
24-
echo "Keystore decoded successfully."
2523
2624
- name: Build Docker image
2725
working-directory: ci
2826
run: docker build -t deku_rep_build_release .
2927

30-
- name: Build unsigned APK
28+
- name: Build unsigned split APKs
3129
run: |
3230
docker run --rm \
3331
-v "$(pwd)":/project \
@@ -44,34 +42,43 @@ jobs:
4442
-Dkotlin.daemon.jvm.options="-Xmx512m,-Xss1m" \
4543
-Dkotlin.compiler.execution.strategy=in-process
4644
47-
- name: Sign APK with apksigner
45+
- name: Sign split APKs with apksigner
4846
run: |
4947
BUILD_TOOLS=$(ls $ANDROID_HOME/build-tools | sort -V | tail -1)
50-
$ANDROID_HOME/build-tools/$BUILD_TOOLS/apksigner sign \
51-
--ks ${{ github.workspace }}/release.keystore \
52-
--ks-type JKS \
53-
--ks-key-alias "${{ secrets.KEY_ALIAS }}" \
54-
--ks-pass pass:"${{ secrets.STORE_PASSWORD }}" \
55-
--key-pass pass:"${{ secrets.KEY_PASSWORD }}" \
56-
--out app/build/outputs/apk/release/app-release-signed.apk \
57-
app/build/outputs/apk/release/app-release-unsigned.apk
48+
cd app/build/outputs/apk/release/
49+
50+
# Loop through each unsigned split and sign it uniquely
51+
for unsigned_apk in app-*-release-unsigned.apk; do
52+
abi=$(echo "$unsigned_apk" | sed 's/app-//;s/-release-unsigned.apk//')
53+
echo "Signing split for ABI: $abi"
54+
55+
$ANDROID_HOME/build-tools/$BUILD_TOOLS/apksigner sign \
56+
--ks ${{ github.workspace }}/release.keystore \
57+
--ks-type JKS \
58+
--ks-key-alias "${{ secrets.KEY_ALIAS }}" \
59+
--ks-pass pass:"${{ secrets.STORE_PASSWORD }}" \
60+
--key-pass pass:"${{ secrets.KEY_PASSWORD }}" \
61+
--out "app-${abi}-release-signed.apk" \
62+
"$unsigned_apk"
63+
done
5864
59-
- name: Verify signature
65+
- name: Verify signatures
6066
run: |
6167
BUILD_TOOLS=$(ls $ANDROID_HOME/build-tools | sort -V | tail -1)
62-
$ANDROID_HOME/build-tools/$BUILD_TOOLS/apksigner verify \
63-
--verbose \
64-
app/build/outputs/apk/release/app-release-signed.apk
68+
for signed_apk in app/build/outputs/apk/release/app-*-release-signed.apk; do
69+
echo "Verifying $signed_apk"
70+
$ANDROID_HOME/build-tools/$BUILD_TOOLS/apksigner verify --verbose "$signed_apk"
71+
done
6572
66-
- name: Upload signed APK
73+
- name: Upload signed APKs
6774
uses: actions/upload-artifact@v4
6875
with:
6976
name: apk-build-1
70-
path: app/build/outputs/apk/release/app-release-signed.apk
77+
path: app/build/outputs/apk/release/app-*-release-signed.apk
7178
retention-days: 1
7279

7380
build-2:
74-
name: Build 2 (signed)
81+
name: Build 2 (signed splits)
7582
runs-on: ubuntu-latest
7683
environment: production
7784
steps:
@@ -82,17 +89,15 @@ jobs:
8289
run: |
8390
echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 --decode > ${{ github.workspace }}/release.keystore
8491
if [ ! -s ${{ github.workspace }}/release.keystore ]; then
85-
echo "Keystore file is empty — check the KEYSTORE_BASE64 secret."
92+
echo "Keystore file is empty."
8693
exit 1
8794
fi
88-
ls -lh ${{ github.workspace }}/release.keystore
89-
echo "Keystore decoded successfully."
9095
9196
- name: Build Docker image
9297
working-directory: ci
9398
run: docker build -t deku_rep_build_release .
9499

95-
- name: Build unsigned APK
100+
- name: Build unsigned split APKs
96101
run: |
97102
docker run --rm \
98103
-v "$(pwd)":/project \
@@ -109,44 +114,48 @@ jobs:
109114
-Dkotlin.daemon.jvm.options="-Xmx512m,-Xss1m" \
110115
-Dkotlin.compiler.execution.strategy=in-process
111116
112-
- name: Sign APK with apksigner
117+
- name: Sign split APKs with apksigner
113118
run: |
114119
BUILD_TOOLS=$(ls $ANDROID_HOME/build-tools | sort -V | tail -1)
115-
$ANDROID_HOME/build-tools/$BUILD_TOOLS/apksigner sign \
116-
--ks ${{ github.workspace }}/release.keystore \
117-
--ks-type JKS \
118-
--ks-key-alias "${{ secrets.KEY_ALIAS }}" \
119-
--ks-pass pass:"${{ secrets.STORE_PASSWORD }}" \
120-
--key-pass pass:"${{ secrets.KEY_PASSWORD }}" \
121-
--out app/build/outputs/apk/release/app-release-signed.apk \
122-
app/build/outputs/apk/release/app-release-unsigned.apk
120+
cd app/build/outputs/apk/release/
121+
for unsigned_apk in app-*-release-unsigned.apk; do
122+
abi=$(echo "$unsigned_apk" | sed 's/app-//;s/-release-unsigned.apk//')
123+
$ANDROID_HOME/build-tools/$BUILD_TOOLS/apksigner sign \
124+
--ks ${{ github.workspace }}/release.keystore \
125+
--ks-type JKS \
126+
--ks-key-alias "${{ secrets.KEY_ALIAS }}" \
127+
--ks-pass pass:"${{ secrets.STORE_PASSWORD }}" \
128+
--key-pass pass:"${{ secrets.KEY_PASSWORD }}" \
129+
--out "app-${abi}-release-signed.apk" \
130+
"$unsigned_apk"
131+
done
123132
124-
- name: Verify signature
133+
- name: Verify signatures
125134
run: |
126135
BUILD_TOOLS=$(ls $ANDROID_HOME/build-tools | sort -V | tail -1)
127-
$ANDROID_HOME/build-tools/$BUILD_TOOLS/apksigner verify \
128-
--verbose \
129-
app/build/outputs/apk/release/app-release-signed.apk
136+
for signed_apk in app/build/outputs/apk/release/app-*-release-signed.apk; do
137+
$ANDROID_HOME/build-tools/$BUILD_TOOLS/apksigner verify --verbose "$signed_apk"
138+
done
130139
131-
- name: Upload signed APK
140+
- name: Upload signed APKs
132141
uses: actions/upload-artifact@v4
133142
with:
134143
name: apk-build-2
135-
path: app/build/outputs/apk/release/app-release-signed.apk
144+
path: app/build/outputs/apk/release/app-*-release-signed.apk
136145
retention-days: 1
137146

138147
compare:
139148
name: Compare signed APKs
140149
runs-on: ubuntu-latest
141150
needs: [ build-1, build-2 ]
142151
steps:
143-
- name: Download APK from build 1
152+
- name: Download APKs from build 1
144153
uses: actions/download-artifact@v4
145154
with:
146155
name: apk-build-1
147156
path: apk-build-1
148157

149-
- name: Download APK from build 2
158+
- name: Download APKs from build 2
150159
uses: actions/download-artifact@v4
151160
with:
152161
name: apk-build-2
@@ -155,11 +164,13 @@ jobs:
155164
- name: Compare hashes
156165
id: compare
157166
run: |
158-
SHA1=$(sha256sum apk-build-1/app-release-signed.apk | awk '{ print $1 }')
159-
SHA2=$(sha256sum apk-build-2/app-release-signed.apk | awk '{ print $1 }')
160-
echo "Build 1: $SHA1"
161-
echo "Build 2: $SHA2"
162-
if [ "$SHA1" = "$SHA2" ]; then
167+
cd apk-build-1 && sha256sum app-*-release-signed.apk > ../hashes1.txt && cd ..
168+
cd apk-build-2 && sha256sum app-*-release-signed.apk > ../hashes2.txt && cd ..
169+
170+
awk '{print $1}' hashes1.txt > clean_hashes1.txt
171+
awk '{print $1}' hashes2.txt > clean_hashes2.txt
172+
173+
if cmp -s clean_hashes1.txt clean_hashes2.txt; then
163174
echo "Reproducible build verified — hashes match."
164175
echo "reproducible=true" >> "$GITHUB_OUTPUT"
165176
else
@@ -176,11 +187,7 @@ jobs:
176187
- name: Run diffoscope
177188
if: steps.compare.outputs.reproducible == 'false'
178189
run: |
179-
diffoscope \
180-
--text diffoscope-report.txt \
181-
--html diffoscope-report.html \
182-
apk-build-1/app-release-signed.apk \
183-
apk-build-2/app-release-signed.apk || true
190+
diffoscope --text diffoscope-report.txt --html diffoscope-report.html apk-build-1/ apk-build-2/ || true
184191
185192
- name: Upload diffoscope report
186193
if: steps.compare.outputs.reproducible == 'false'
@@ -195,7 +202,6 @@ jobs:
195202
- name: Fail if not reproducible
196203
if: steps.compare.outputs.reproducible == 'false'
197204
run: |
198-
echo "See the diffoscope-report artifact for a full breakdown of differences."
199205
exit 1
200206
201207
tag-and-release:
@@ -220,57 +226,50 @@ jobs:
220226
exit 1
221227
fi
222228
VERSION_NAME=$(grep "^versionName=" version.properties | cut -d'=' -f2)
223-
if [ -z "$VERSION_NAME" ]; then
224-
echo "ERROR: versionName missing from version.properties"
225-
exit 1
226-
fi
229+
TAG_VERSION=$(grep "^tagVersion=" version.properties | cut -d'=' -f2)
227230
echo "version_name=$VERSION_NAME" >> "$GITHUB_OUTPUT"
228-
echo "versionName=$VERSION_NAME"
229-
230-
- name: Compute next tag
231-
id: next_tag
232-
run: |
233-
LATEST=$(git tag --sort=-v:refname | head -1)
234-
if [ -z "$LATEST" ]; then
235-
LATEST="0"
236-
fi
237-
echo "Latest tag: $LATEST"
238-
NEW_TAG=$((LATEST + 1))
239-
echo "New tag: $NEW_TAG"
240-
echo "new_tag=$NEW_TAG" >> "$GITHUB_OUTPUT"
231+
echo "tag_version=$TAG_VERSION" >> "$GITHUB_OUTPUT"
241232
242233
- name: Create and push tag
243234
run: |
244235
git config user.name "github-actions[bot]"
245236
git config user.email "github-actions[bot]@users.noreply.github.com"
246-
git tag "${{ steps.next_tag.outputs.new_tag }}" -m "Release ${{ steps.version.outputs.version_name }} — reproducible build verified"
247-
git push origin "${{ steps.next_tag.outputs.new_tag }}"
248-
echo "Tagged ${{ steps.next_tag.outputs.new_tag }} and pushed."
237+
# Tags using the clean tagVersion tracking integer
238+
git tag "${{ steps.version.outputs.tag_version }}" -m "Release ${{ steps.version.outputs.version_name }} — reproducible splits verified"
239+
git push origin "${{ steps.version.outputs.tag_version }}"
249240
250-
- name: Download signed APK from build-1
241+
- name: Download signed APKs from build-1
251242
uses: actions/download-artifact@v4
252243
with:
253244
name: apk-build-1
254245
path: apk-release
255246

256-
- name: Rename APK with version name
247+
- name: Rename split APKs with version and ABI info
257248
run: |
258-
mv apk-release/app-release-signed.apk \
259-
"apk-release/${{ steps.version.outputs.version_name }}.apk"
249+
cd apk-release
250+
# Example: transforms app-arm64-v8a-release-signed.apk -> [AppName]-0.72.0-arm64-v8a.apk
251+
for signed_apk in app-*-release-signed.apk; do
252+
abi=$(echo "$signed_apk" | sed 's/app-//;s/-release-signed.apk//')
253+
mv "$signed_apk" "${{ steps.version.outputs.version_name }}-${abi}.apk"
254+
done
260255
261256
- name: Create GitHub release
262257
env:
263258
GH_TOKEN: ${{ secrets.GH_LIB_SYNC_TOKEN }}
264259
run: |
265-
gh release create "${{ steps.next_tag.outputs.new_tag }}" \
266-
"apk-release/${{ steps.version.outputs.version_name }}.apk" \
260+
cd apk-release
261+
262+
# Build a release notes string displaying hashes for all 3 versions
263+
NOTE_HASHES=$(sha256sum *.apk | awk '{print "**" $2 ":** " $1 "\n"}')
264+
265+
gh release create "${{ steps.version.outputs.tag_version }}" \
266+
*.apk \
267267
--title "${{ steps.version.outputs.version_name }}" \
268-
--notes "Reproducible build verified
268+
--notes "Reproducible split builds verified
269269
270270
**Release:** ${{ steps.version.outputs.version_name }}
271-
**Build No:** ${{ steps.next_tag.outputs.new_tag }}
272-
**sha256sum:** $(sha256sum "apk-release/${{ steps.version.outputs.version_name }}.apk" | awk '{print $1}')
271+
**Build No:** ${{ steps.version.outputs.tag_version }}
273272
274-
**changelogs:** " \
275-
--fail-on-no-commits \
276-
--verify-tag
273+
**SHA-256 Checksums:**
274+
$NOTE_HASHES" \
275+
--fail-on-no-commits

0 commit comments

Comments
 (0)