|
| 1 | +#!/usr/bin/env bash |
| 2 | +# One-shot signing setup for iLINK releases. |
| 3 | +# |
| 4 | +# Generates the release keystore, derives its certificate fingerprint, and |
| 5 | +# uploads the five secrets the release workflow needs to the `prod` GitHub |
| 6 | +# environment. Run it yourself: passwords are read from your terminal with |
| 7 | +# echo disabled and are never printed, logged, or passed as arguments. |
| 8 | +# |
| 9 | +# bash scripts/setup-signing.sh |
| 10 | +# |
| 11 | +# Re-running with an existing keystore is safe — it will reuse that file and |
| 12 | +# only refresh the secrets. |
| 13 | +set -euo pipefail |
| 14 | + |
| 15 | +REPO="${REPO:-i99dev/ilink}" |
| 16 | +ALIAS="${ALIAS:-dash}" |
| 17 | +# Deliberately outside the repository so the key can never be committed. |
| 18 | +KEYSTORE="${KEYSTORE:-$HOME/ilink-release.jks}" |
| 19 | + |
| 20 | +command -v keytool >/dev/null || { echo "keytool not found — install a JDK or add Android Studio's jbr/bin to PATH" >&2; exit 1; } |
| 21 | +command -v gh >/dev/null || { echo "gh not found — install the GitHub CLI" >&2; exit 1; } |
| 22 | +gh auth status >/dev/null 2>&1 || { echo "gh is not authenticated — run: gh auth login" >&2; exit 1; } |
| 23 | + |
| 24 | +echo "Repository : $REPO" |
| 25 | +echo "Keystore : $KEYSTORE" |
| 26 | +echo "Alias : $ALIAS" |
| 27 | +echo |
| 28 | + |
| 29 | +if [ -f "$KEYSTORE" ]; then |
| 30 | + echo "Keystore already exists — reusing it (no new key is generated)." |
| 31 | + read -r -s -p "Store password: " STORE_PW; echo |
| 32 | + read -r -s -p "Key password : " KEY_PW; echo |
| 33 | +else |
| 34 | + echo "Creating a new keystore. Choose a strong password and store it in a" |
| 35 | + echo "password manager — losing it means no future build can ever update an" |
| 36 | + echo "installed iLINK." |
| 37 | + echo |
| 38 | + read -r -s -p "Store password : " STORE_PW; echo |
| 39 | + read -r -s -p "Confirm store password: " STORE_PW2; echo |
| 40 | + [ "$STORE_PW" = "$STORE_PW2" ] || { echo "Passwords do not match." >&2; exit 1; } |
| 41 | + [ ${#STORE_PW} -ge 12 ] || { echo "Use at least 12 characters." >&2; exit 1; } |
| 42 | + # One password for both is normal for a release keystore and keeps Gradle simple. |
| 43 | + KEY_PW="$STORE_PW" |
| 44 | + |
| 45 | + keytool -genkeypair -v \ |
| 46 | + -keystore "$KEYSTORE" \ |
| 47 | + -alias "$ALIAS" \ |
| 48 | + -keyalg RSA -keysize 4096 -validity 10000 \ |
| 49 | + -storepass:env STORE_PW -keypass:env KEY_PW \ |
| 50 | + -dname "CN=iLINK, OU=iLINK, O=iLINK, L=, ST=, C=" \ |
| 51 | + >/dev/null |
| 52 | + chmod 600 "$KEYSTORE" 2>/dev/null || true |
| 53 | + echo "Created $KEYSTORE" |
| 54 | +fi |
| 55 | +export STORE_PW KEY_PW |
| 56 | + |
| 57 | +SIGNER=$(keytool -list -v -keystore "$KEYSTORE" -alias "$ALIAS" \ |
| 58 | + -storepass:env STORE_PW 2>/dev/null \ |
| 59 | + | awk '/SHA256:/ {gsub(":", ""); print tolower($2); exit}') |
| 60 | +printf '%s' "$SIGNER" | grep -Eq '^[0-9a-f]{64}$' || { |
| 61 | + echo "Could not read the certificate — wrong password or alias?" >&2; exit 1; } |
| 62 | +echo "Certificate SHA-256: $SIGNER" |
| 63 | + |
| 64 | +# base64 of the keystore, written with a restrictive umask and removed after upload. |
| 65 | +B64=$(mktemp) |
| 66 | +trap 'rm -f "$B64"' EXIT |
| 67 | +( umask 077; base64 -w0 "$KEYSTORE" > "$B64" 2>/dev/null || base64 -i "$KEYSTORE" | tr -d '\n' > "$B64" ) |
| 68 | + |
| 69 | +echo |
| 70 | +echo "Uploading secrets to the '$REPO' prod environment..." |
| 71 | +gh secret set DASH_RELEASE_KEYSTORE_B64 --env prod --repo "$REPO" < "$B64" |
| 72 | +printf '%s' "$STORE_PW" | gh secret set DASH_KEYSTORE_PASSWORD --env prod --repo "$REPO" |
| 73 | +printf '%s' "$KEY_PW" | gh secret set DASH_KEY_PASSWORD --env prod --repo "$REPO" |
| 74 | +printf '%s' "$ALIAS" | gh secret set DASH_KEY_ALIAS --env prod --repo "$REPO" |
| 75 | +printf '%s' "$SIGNER" | gh secret set DASH_EXPECTED_SIGNER_SHA --env prod --repo "$REPO" |
| 76 | + |
| 77 | +echo |
| 78 | +echo "Done. Secrets now set (names only):" |
| 79 | +gh secret list --env prod --repo "$REPO" |
| 80 | +echo |
| 81 | +echo "Back up $KEYSTORE somewhere encrypted and off this machine before releasing." |
0 commit comments