chore(release): one-shot export of the signing key for Play App Signing
All checks were successful
Play key export (one-shot) / export (push) Successful in 50s
All checks were successful
Play key export (one-shot) / export (push) Successful in 50s
Never merged. Runs PEPK against the release keystore secret and uploads output.zip, encrypted to Google's public key, as a one-day artifact for the Play Console's "Export and upload a key from Java keystore". Refuses unless the keystore's certificate is the one the release APKs carry. The branch is deleted once the zip is uploaded. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
11
.gitea/play-key-export/encryption_public_key.pem
Normal file
11
.gitea/play-key-export/encryption_public_key.pem
Normal file
@@ -0,0 +1,11 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAsovs0QR6VmHX+q1Zv3SQ
|
||||
WIkcR04Vwv4WLhbOt/OAaW2dBFsmRyskPx5W5RJ9gS12/BU8sUKAUh4aALwQMfLS
|
||||
u4Tugb6FpI5rBY10ydMx6D1EbU+UMwdIlBnm8EYoI5oUdY9VEjWihUZHSoBnC/LW
|
||||
/UbJx+HmA7tA7BEIx4KBmOmZUTnDSCRTi48IBjfKslZem6bkcTeIrxzY+faBZYRM
|
||||
s9Q11kxEsHbpIJ8af1HTO7JtCRxAlGkzFsT7IyVOtVdpLTKlPcuVsocyY0/Wl641
|
||||
O9YmEutJnyoQbAekQnkJxyNeq1BuT5syhS6nEDUwqKgiahKHuWr99MqFLDEkuZZ+
|
||||
rKXDlb1j3CJ0wTAu68aizCtOFMoOuVJjd/rHmuyRePpvZXsql03tQW5PP3R2yrKe
|
||||
KFSPVNmhWhWqZiaXoqyyLK7uoxjLgF/K0ekHHcKivTm4WvT52V5TTsN2jleMbkpM
|
||||
EO2KajkBwWkvVBcTaUmt9yFq4fzifPq2z1sebP3RRycTAgMBAAE=
|
||||
-----END PUBLIC KEY-----
|
||||
77
.gitea/workflows/play-key-export.yml
Normal file
77
.gitea/workflows/play-key-export.yml
Normal file
@@ -0,0 +1,77 @@
|
||||
# ONE-SHOT, never merged: exports the release signing key for Play App Signing
|
||||
# ("Export and upload a key from Java keystore"). Lives only on the branch
|
||||
# chore/play-key-export and runs when that branch is pushed; the branch is
|
||||
# deleted once the zip is uploaded to the Play Console.
|
||||
#
|
||||
# What leaves the run: output.zip, which PEPK encrypts with Google's public key
|
||||
# (.gitea/play-key-export/encryption_public_key.pem), so only Google can open it.
|
||||
# What the log shows: the certificate's SHA-256 (public; it is in every APK) and
|
||||
# pepk.jar's checksum. Nothing derived from a secret is ever printed: no set -x,
|
||||
# no echo of a variable, the keystore is decoded to a private temp dir and removed.
|
||||
|
||||
name: Play key export (one-shot)
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- chore/play-key-export
|
||||
|
||||
jobs:
|
||||
export:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- name: Install JDK 17
|
||||
run: |
|
||||
apt-get update
|
||||
apt-get install -y curl openjdk-17-jdk-headless
|
||||
|
||||
- name: Check out this branch
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Export the signing key, encrypted to Google
|
||||
env:
|
||||
ANDROID_KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
|
||||
ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
|
||||
ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
|
||||
ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }}
|
||||
# The certificate every Gitea release APK is signed with (v0.6.0).
|
||||
EXPECTED_SHA256: '59:7B:79:ED:54:2A:91:43:73:59:03:5D:3F:C4:39:B5:DA:8B:D8:E7:26:E7:30:03:B8:B4:1A:F6:0E:14:A4:82'
|
||||
run: |
|
||||
set -euo pipefail
|
||||
umask 077
|
||||
WORK="$(mktemp -d)"
|
||||
trap 'rm -rf "$WORK"' EXIT
|
||||
printf '%s' "$ANDROID_KEYSTORE_BASE64" | base64 -d > "$WORK/release.jks"
|
||||
|
||||
FP="$(keytool -list -v -keystore "$WORK/release.jks" -storepass "$ANDROID_KEYSTORE_PASSWORD" \
|
||||
-alias "$ANDROID_KEY_ALIAS" | sed -n 's/^[[:space:]]*SHA256: //p')"
|
||||
echo "Keystore certificate SHA-256: ${FP}"
|
||||
if [ "$FP" != "$EXPECTED_SHA256" ]; then
|
||||
echo "::error::not the key the release APKs are signed with; nothing exported"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
curl -fsSL -o "$WORK/pepk.jar" \
|
||||
https://www.gstatic.com/play-apps-publisher-rapid/signing-tool/prod/pepk.jar
|
||||
echo "pepk.jar SHA-256: $(sha256sum "$WORK/pepk.jar" | cut -d' ' -f1)"
|
||||
|
||||
mkdir -p out
|
||||
java -jar "$WORK/pepk.jar" \
|
||||
--keystore="$WORK/release.jks" \
|
||||
--alias="$ANDROID_KEY_ALIAS" \
|
||||
--keystore-pass="$ANDROID_KEYSTORE_PASSWORD" \
|
||||
--key-pass="$ANDROID_KEY_PASSWORD" \
|
||||
--output="$PWD/out/output.zip" \
|
||||
--include-cert \
|
||||
--rsa-aes-encryption \
|
||||
--encryption-key-path=.gitea/play-key-export/encryption_public_key.pem \
|
||||
> /dev/null 2>&1 || { echo "::error::pepk failed (its output is suppressed)"; exit 1; }
|
||||
ls -l out/output.zip
|
||||
|
||||
- name: Upload the encrypted zip
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: play-signing-key-export
|
||||
path: out/output.zip
|
||||
retention-days: 1
|
||||
Reference in New Issue
Block a user