117 lines
3.2 KiB
Bash
Executable file
117 lines
3.2 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
TEAM_ID="${APPSOK_TEAM_ID:-AWA82DP9WD}"
|
|
DEFAULT_PROFILE="${APPSOK_NOTARY_PROFILE:-appsok-notary}"
|
|
AGE_KEY="${APPSOK_SOPS_AGE_KEY_FILE:-$HOME/.config/sops/age/appsok-ci-key.txt}"
|
|
SECRET_FILE="${APPSOK_CI_SECRET_FILE:-secrets/appsok.ci.sops.json}"
|
|
|
|
cd "$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
|
|
|
|
need() {
|
|
if ! command -v "$1" >/dev/null 2>&1; then
|
|
echo "missing command: $1" >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
need age-keygen
|
|
need python3
|
|
need security
|
|
need sops
|
|
need xcrun
|
|
|
|
if [ ! -t 0 ]; then
|
|
echo "run this script from an interactive terminal" >&2
|
|
exit 1
|
|
fi
|
|
|
|
prompt_plain() {
|
|
local label="$1"
|
|
local var="$2"
|
|
local value
|
|
printf "%s: " "$label" > /dev/tty
|
|
IFS= read -r value < /dev/tty
|
|
printf -v "$var" '%s' "$value"
|
|
}
|
|
|
|
mkdir -p "$(dirname "$AGE_KEY")" "$(dirname "$SECRET_FILE")"
|
|
|
|
if [ ! -f "$AGE_KEY" ]; then
|
|
age-keygen -o "$AGE_KEY" >/dev/null
|
|
chmod 600 "$AGE_KEY"
|
|
fi
|
|
|
|
AGE_RECIPIENT="$(awk '/^# public key: / {print $4}' "$AGE_KEY")"
|
|
if [ -z "$AGE_RECIPIENT" ]; then
|
|
echo "failed to read age public key from $AGE_KEY" >&2
|
|
exit 1
|
|
fi
|
|
|
|
SOPS_PATH_REGEX="$(SECRET_FILE="$SECRET_FILE" python3 - <<'PY'
|
|
import os
|
|
import re
|
|
|
|
print(re.escape(os.environ["SECRET_FILE"]) + "$")
|
|
PY
|
|
)"
|
|
|
|
cat > .sops.yaml <<YAML
|
|
creation_rules:
|
|
- path_regex: $SOPS_PATH_REGEX
|
|
age: "$AGE_RECIPIENT"
|
|
YAML
|
|
|
|
prompt_plain "Mac login/keychain password" KEYCHAIN_PASSWORD
|
|
prompt_plain "Apple ID email" APPLE_ID
|
|
prompt_plain "App-specific password" APP_SPECIFIC_PASSWORD
|
|
prompt_plain "Notary profile [$DEFAULT_PROFILE]" NOTARY_PROFILE
|
|
NOTARY_PROFILE="${NOTARY_PROFILE:-$DEFAULT_PROFILE}"
|
|
prompt_plain "Jenkins URL" JENKINS_URL
|
|
prompt_plain "Jenkins username" JENKINS_USERNAME
|
|
prompt_plain "Jenkins API token" JENKINS_API_TOKEN
|
|
|
|
tmp="$(mktemp)"
|
|
trap 'rm -f "$tmp"' EXIT
|
|
chmod 600 "$tmp"
|
|
|
|
export KEYCHAIN_PASSWORD APPLE_ID APP_SPECIFIC_PASSWORD NOTARY_PROFILE TEAM_ID JENKINS_URL JENKINS_USERNAME JENKINS_API_TOKEN
|
|
python3 - <<'PY' > "$tmp"
|
|
import json
|
|
import os
|
|
|
|
payload = {
|
|
"keychain_password": os.environ["KEYCHAIN_PASSWORD"],
|
|
"apple_id": os.environ["APPLE_ID"],
|
|
"app_specific_password": os.environ["APP_SPECIFIC_PASSWORD"],
|
|
"notary_profile": os.environ["NOTARY_PROFILE"],
|
|
"team_id": os.environ["TEAM_ID"],
|
|
"jenkins_url": os.environ["JENKINS_URL"],
|
|
"jenkins_username": os.environ["JENKINS_USERNAME"],
|
|
"jenkins_api_token": os.environ["JENKINS_API_TOKEN"],
|
|
}
|
|
print(json.dumps(payload, indent=2))
|
|
PY
|
|
|
|
SOPS_AGE_KEY_FILE="$AGE_KEY" \
|
|
sops --filename-override "$SECRET_FILE" -e "$tmp" > "$SECRET_FILE"
|
|
SOPS_AGE_KEY_FILE="$AGE_KEY" sops -d "$SECRET_FILE" >/dev/null
|
|
|
|
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$HOME/Library/Keychains/login.keychain-db"
|
|
security set-keychain-settings -lut 21600 "$HOME/Library/Keychains/login.keychain-db"
|
|
security set-key-partition-list \
|
|
-S apple-tool:,apple:,codesign: \
|
|
-s \
|
|
-k "$KEYCHAIN_PASSWORD" \
|
|
"$HOME/Library/Keychains/login.keychain-db"
|
|
|
|
xcrun notarytool store-credentials "$NOTARY_PROFILE" \
|
|
--apple-id "$APPLE_ID" \
|
|
--team-id "$TEAM_ID" \
|
|
--password "$APP_SPECIFIC_PASSWORD"
|
|
|
|
xcrun notarytool history --keychain-profile "$NOTARY_PROFILE" >/dev/null
|
|
|
|
echo "saved encrypted secret: $SECRET_FILE"
|
|
echo "saved age key: $AGE_KEY"
|
|
echo "saved notary profile: $NOTARY_PROFILE"
|