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
78 lines
3.2 KiB
YAML
78 lines
3.2 KiB
YAML
# 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
|