mirror of
https://github.com/austinried/subtracks.git
synced 2026-11-10 15:11:58 +01:00
release: publish checksums and the signing certificate
Print the artifact SHA-256 and the APK signer certificate in the release log, attach SHA256SUMS and the public release certificate to the GitHub release, list the APK and certificate SHA-256 in the release notes, print the next build checksums, and commit the next build's public certificate with verification steps in signing/README.md.
This commit is contained in:
@@ -20,6 +20,8 @@ jobs:
|
||||
- uses: ./.github/actions/build
|
||||
with:
|
||||
gradle-args: ":app:assembleDebug :app:assembleNext --no-daemon"
|
||||
- name: Checksums
|
||||
run: sha256sum app/build/outputs/apk/debug/app-debug.apk app/build/outputs/apk/next/app-next.apk
|
||||
- uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: subtracks-next
|
||||
|
||||
@@ -29,6 +29,17 @@ jobs:
|
||||
keyproperties-base64: ${{ secrets.SUBTRACKS_KEYPROPERTIES_BASE64 }}
|
||||
keystore-password: ${{ secrets.SUBTRACKS_UPLOAD_STORE_PASSWORD }}
|
||||
key-password: ${{ secrets.SUBTRACKS_UPLOAD_KEY_PASSWORD }}
|
||||
- name: Export release certificate
|
||||
env:
|
||||
KEYSTORE_BASE64: ${{ secrets.SUBTRACKS_KEYSTORE_BASE64 }}
|
||||
KEYPROPERTIES_BASE64: ${{ secrets.SUBTRACKS_KEYPROPERTIES_BASE64 }}
|
||||
KEYSTORE_PASSWORD: ${{ secrets.SUBTRACKS_UPLOAD_STORE_PASSWORD }}
|
||||
run: |
|
||||
umask 077
|
||||
echo "$KEYSTORE_BASE64" | base64 -d > "$RUNNER_TEMP/keystore"
|
||||
alias=$(printf '%s' "$KEYPROPERTIES_BASE64" | base64 -d | sed -n 's/^keyAlias=//p' | tr -d '\r')
|
||||
nix develop --command keytool -exportcert -rfc -keystore "$RUNNER_TEMP/keystore" -alias "$alias" -storepass "$KEYSTORE_PASSWORD" -file app/build/outputs/release-certificate.pem
|
||||
rm -f "$RUNNER_TEMP/keystore"
|
||||
- uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: release
|
||||
@@ -75,14 +86,37 @@ jobs:
|
||||
- name: Remove Play service account
|
||||
if: always()
|
||||
run: rm -f "$RUNNER_TEMP/play.json"
|
||||
- name: Collect release APK
|
||||
run: cp dist/apk/release/app-release.apk subtracks.apk
|
||||
- name: Checksums and signature
|
||||
id: checksums
|
||||
run: |
|
||||
cp dist/apk/release/app-release.apk subtracks.apk
|
||||
sha256sum subtracks.apk > SHA256SUMS
|
||||
echo "Artifact SHA-256:"
|
||||
sha256sum dist/apk/release/app-release.apk dist/bundle/release/app-release.aab
|
||||
echo "APK signature:"
|
||||
certs=$(nix develop --command bash -c '"$ANDROID_HOME/build-tools/37.0.0/apksigner" verify --print-certs subtracks.apk')
|
||||
printf '%s\n' "$certs"
|
||||
fingerprint=$(printf '%s\n' "$certs" | sed -n 's/.*certificate SHA-256 digest: //p' | head -1)
|
||||
echo "fingerprint=$fingerprint" >> "$GITHUB_OUTPUT"
|
||||
- name: Compose release notes
|
||||
run: |
|
||||
{
|
||||
cat "metadata/en-US/changelogs/${{ needs.build.outputs.version-code }}.txt"
|
||||
echo
|
||||
echo '---'
|
||||
echo
|
||||
echo "APK SHA-256: \`$(cut -d ' ' -f1 SHA256SUMS)\`"
|
||||
echo
|
||||
echo "Signing certificate SHA-256: \`${{ steps.checksums.outputs.fingerprint }}\`"
|
||||
echo
|
||||
echo 'The signing certificate is attached as `release-certificate.pem`.'
|
||||
} > release-notes.md
|
||||
- name: Create GitHub release
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
args=(--verify-tag --title "$GITHUB_REF_NAME" --notes-file "metadata/en-US/changelogs/${{ needs.build.outputs.version-code }}.txt")
|
||||
args=(--verify-tag --title "$GITHUB_REF_NAME" --notes-file release-notes.md)
|
||||
if [ "${{ steps.stable.outputs.value }}" != "true" ]; then
|
||||
args+=(--prerelease)
|
||||
fi
|
||||
gh release create "$GITHUB_REF_NAME" subtracks.apk "${args[@]}"
|
||||
gh release create "$GITHUB_REF_NAME" subtracks.apk SHA256SUMS dist/release-certificate.pem "${args[@]}"
|
||||
|
||||
@@ -26,6 +26,10 @@ subtracks is an open source Android client for [Subsonic-compatible](http://www.
|
||||
<a href="https://github.com/austinried/subtracks/releases/"><img src=".assets/github-badge.png" width="250"/></a>
|
||||
</div>
|
||||
|
||||
## Verifying releases
|
||||
|
||||
APKs are signed. Every GitHub release attaches `SHA256SUMS` and the signing certificate (`release-certificate.pem`); the `next` build key is committed. See [signing/README.md](signing/README.md) for the fingerprints and the commands to verify a download.
|
||||
|
||||
## Features
|
||||
|
||||
- **Large Libraries:** Built for very large libraries, from syncing the whole collection to playing playlists with thousands of tracks.
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
# Verifying a subtracks download
|
||||
|
||||
subtracks ships through three channels, each with its own signer:
|
||||
|
||||
- **GitHub releases and Google Play** — signed with the release key. Every GitHub
|
||||
release attaches `subtracks.apk`, a `SHA256SUMS` file and the public certificate
|
||||
`release-certificate.pem`.
|
||||
- **`next` builds** (the `subtracks-next` artifact from CI) — signed with the
|
||||
public debug key committed here as [`next-certificate.pem`](next-certificate.pem).
|
||||
- **F-Droid** — re-signed by F-Droid with its own key; see F-Droid's published
|
||||
signing key.
|
||||
|
||||
## `next` builds
|
||||
|
||||
Certificate SHA-256:
|
||||
|
||||
```
|
||||
DF:31:3F:18:58:E9:AD:F4:7F:44:65:B2:80:8F:DC:E5:B9:F8:8A:48:35:DC:D0:79:95:19:61:C3:05:05:08:37
|
||||
```
|
||||
|
||||
To check a `next` APK:
|
||||
|
||||
```sh
|
||||
apksigner verify --print-certs subtracks-next.apk
|
||||
```
|
||||
|
||||
The `SHA-256 digest` line must equal the fingerprint above (the certificate is
|
||||
committed at [`next-certificate.pem`](next-certificate.pem)).
|
||||
|
||||
## GitHub releases
|
||||
|
||||
Each release attaches the APK, the checksums and the certificate:
|
||||
|
||||
```sh
|
||||
sha256sum -c SHA256SUMS
|
||||
apksigner verify --print-certs subtracks.apk # compare with the .pem
|
||||
keytool -printcert -file release-certificate.pem # prints its SHA-256
|
||||
```
|
||||
|
||||
The signing certificate SHA-256 is also listed in the release notes.
|
||||
@@ -0,0 +1,19 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDEzCCAfugAwIBAgIIWpLReZ2f+20wDQYJKoZIhvcNAQEMBQAwNzELMAkGA1UE
|
||||
BhMCVVMxEDAOBgNVBAoTB0FuZHJvaWQxFjAUBgNVBAMTDUFuZHJvaWQgRGVidWcw
|
||||
IBcNMjYxMDA0MDMyNTU4WhgPMjA1NDAyMTkwMzI1NThaMDcxCzAJBgNVBAYTAlVT
|
||||
MRAwDgYDVQQKEwdBbmRyb2lkMRYwFAYDVQQDEw1BbmRyb2lkIERlYnVnMIIBIjAN
|
||||
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn4/a05V9p2CHVx2YWwPFHtecUocy
|
||||
WmGQGPhN0VepKU2DC6LDCM7X8YBqS+RyIiDDVqmlUrnYu1CgbaglAySz8vMQBjUo
|
||||
4XUiC7iyNX9JP5exfnGmFsWMM6zHIVyOViX1ZryZlMUAA+CXXj72Mkv1YAijtEu0
|
||||
JFHvGgUDDhPsJmToHQtEDHhvN+nUWR7zl7mVcrE3Al6YT+rfSgGOl5Sg6umjyx3c
|
||||
VwtiQCR5eDW9YiGCDufjBJYox2oNFdvMViPcn9bJu1maAS+SMHL9gpcysriSDLp/
|
||||
rDs6an1zIP76zRPOVMJ/Aqi1JvMtcCBREY5qk3qwtNWQ6YnBcHKJ+7oHzwIDAQAB
|
||||
oyEwHzAdBgNVHQ4EFgQUM7dLj1ZLZvtvLOlI9cap5RldteAwDQYJKoZIhvcNAQEM
|
||||
BQADggEBACDujVeOnL95ybrTm9mwlVsG0DZ5ttRxt6JHEnVjHWOxv/W0F5FanEz1
|
||||
DonQIpRa4eOJ06eBvPcBVpNuLKzczpO1Ue3AaX6kwjWD4n6XYMVWZP6euOj2wvwK
|
||||
93Kf4iG6ObMJ6WMA91VIvtTMvDGhzoL/5Kk5+esBbzLrBWLU/VJrySABFU5cwnqF
|
||||
cP7kGR5JvHuJKiuJ/99yXZeg0piI3n/rdEYsjWkpIIIfaFY2j/n1r+evQ9J/aln/
|
||||
i0dif06Fl11KdFF4456nGH59S0SeckG9jKo04nj4fKeMqwE/7MDRpDa+a0e9Xu7Z
|
||||
0jGgQKg1SFbI8xMrJn2ybdWquVZtKHo=
|
||||
-----END CERTIFICATE-----
|
||||
Reference in New Issue
Block a user