feat: migrate CI secrets from Forgejo to SOPS, remove all fallbacks
- Add 6 secrets to secrets.enc.yaml: WEBSITE_SSH_HOST, PLAY_STORE_CONFIG_JSON, ANDROID_KEYSTORE_BASE64, ANDROID_KEYSTORE_PASSWORD, FIREBASE_TEST_LAB_SERVICE_ACCOUNT_KEY, RENOVATE_FORGEJO_TOKEN - Extend setup_dagger_remote.sh to export all CI secrets from SOPS to GITHUB_ENV so subsequent steps receive them without Forgejo secret refs - Remove all silent-skip fallbacks (if: secrets.X != '') from deploy.yml, website.yml, firebase-tests.yml — jobs now fail hard if secrets are missing - Remove direct Forgejo secret references from all workflow env: blocks - Delete temporary dump-secrets workflow SSH_PRIVATE_KEY, SSH_KNOWN_HOSTS, SSH_USER, SSH_HOST are not yet in Forgejo and therefore not in SOPS — deploy/website tasks will fail with a clear Taskfile precondition error until those secrets are provided. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
ef4448e8b6
commit
1cd1e49430
@@ -113,11 +113,7 @@ jobs:
|
||||
run: scripts/setup_dagger_remote.sh
|
||||
|
||||
- name: Publish Android to Play Store
|
||||
if: ${{ secrets.PLAY_STORE_CONFIG_JSON != '' }}
|
||||
env:
|
||||
ANDROID_KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
|
||||
ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
|
||||
PLAY_STORE_CONFIG_JSON: ${{ secrets.PLAY_STORE_CONFIG_JSON }}
|
||||
DAGGER_NO_NAG: "1"
|
||||
run: task publish-android
|
||||
|
||||
@@ -145,14 +141,7 @@ jobs:
|
||||
run: scripts/setup_dagger_remote.sh
|
||||
|
||||
- name: Build & Deploy APK to server
|
||||
if: ${{ secrets.SSH_PRIVATE_KEY != '' }}
|
||||
env:
|
||||
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
|
||||
SSH_KNOWN_HOSTS: ${{ secrets.SSH_KNOWN_HOSTS }}
|
||||
SSH_USER: ${{ secrets.SSH_USER }}
|
||||
SSH_HOST: ${{ secrets.SSH_HOST }}
|
||||
ANDROID_KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
|
||||
ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
|
||||
DAGGER_NO_NAG: "1"
|
||||
run: task deploy-apk
|
||||
|
||||
@@ -180,12 +169,7 @@ jobs:
|
||||
run: scripts/setup_dagger_remote.sh
|
||||
|
||||
- name: Build & Deploy Linux to server
|
||||
if: ${{ secrets.SSH_PRIVATE_KEY != '' }}
|
||||
env:
|
||||
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
|
||||
SSH_KNOWN_HOSTS: ${{ secrets.SSH_KNOWN_HOSTS }}
|
||||
SSH_USER: ${{ secrets.SSH_USER }}
|
||||
SSH_HOST: ${{ secrets.SSH_HOST }}
|
||||
DAGGER_NO_NAG: "1"
|
||||
run: task deploy-linux
|
||||
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
name: Dump Secrets (TEMP - delete after use)
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [sops-migrate]
|
||||
|
||||
jobs:
|
||||
dump:
|
||||
name: Encrypt secrets with age pubkey
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Install age
|
||||
run: |
|
||||
AGE_VERSION="1.2.0"
|
||||
curl -fsSL "https://github.com/FiloSottile/age/releases/download/v${AGE_VERSION}/age-v${AGE_VERSION}-linux-amd64.tar.gz" \
|
||||
| tar xz -C /usr/local/bin --strip-components=1 age/age age/age-keygen
|
||||
age --version
|
||||
|
||||
- name: Encrypt secrets and post as PR comment
|
||||
env:
|
||||
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
|
||||
SSH_KNOWN_HOSTS: ${{ secrets.SSH_KNOWN_HOSTS }}
|
||||
SSH_USER: ${{ secrets.SSH_USER }}
|
||||
SSH_HOST: ${{ secrets.SSH_HOST }}
|
||||
WEBSITE_SSH_HOST: ${{ secrets.WEBSITE_SSH_HOST }}
|
||||
PLAY_STORE_CONFIG_JSON: ${{ secrets.PLAY_STORE_CONFIG_JSON }}
|
||||
ANDROID_KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
|
||||
ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
|
||||
FIREBASE_TEST_LAB_SERVICE_ACCOUNT_KEY: ${{ secrets.FIREBASE_TEST_LAB_SERVICE_ACCOUNT_KEY }}
|
||||
RENOVATE_FORGEJO_TOKEN: ${{ secrets.RENOVATE_FORGEJO_TOKEN }}
|
||||
FORGEJO_TOKEN: ${{ github.token }}
|
||||
FORGEJO_URL: ${{ github.server_url }}
|
||||
GITHUB_REPOSITORY: ${{ github.repository }}
|
||||
run: |
|
||||
AGE_PUBKEY="age1r0k34dkgzppaew7etm3ka7p0dgxcd365gxe66kuuqsnw6hqax9qswda0sh"
|
||||
OUT_FILE="/tmp/secrets_encrypted.txt"
|
||||
|
||||
encrypt_secret() {
|
||||
local name="$1"
|
||||
local value="$2"
|
||||
printf '=== %s ===\n' "$name"
|
||||
if [ -z "$value" ]; then
|
||||
printf '(empty)\n\n'
|
||||
else
|
||||
printf '%s' "$value" | age -r "$AGE_PUBKEY" | base64 -w0
|
||||
printf '\n\n'
|
||||
fi
|
||||
}
|
||||
|
||||
{
|
||||
encrypt_secret "SSH_PRIVATE_KEY" "$SSH_PRIVATE_KEY"
|
||||
encrypt_secret "SSH_KNOWN_HOSTS" "$SSH_KNOWN_HOSTS"
|
||||
encrypt_secret "SSH_USER" "$SSH_USER"
|
||||
encrypt_secret "SSH_HOST" "$SSH_HOST"
|
||||
encrypt_secret "WEBSITE_SSH_HOST" "$WEBSITE_SSH_HOST"
|
||||
encrypt_secret "PLAY_STORE_CONFIG_JSON" "$PLAY_STORE_CONFIG_JSON"
|
||||
encrypt_secret "ANDROID_KEYSTORE_BASE64" "$ANDROID_KEYSTORE_BASE64"
|
||||
encrypt_secret "ANDROID_KEYSTORE_PASSWORD" "$ANDROID_KEYSTORE_PASSWORD"
|
||||
encrypt_secret "FIREBASE_TEST_LAB_SERVICE_ACCOUNT_KEY" "$FIREBASE_TEST_LAB_SERVICE_ACCOUNT_KEY"
|
||||
encrypt_secret "RENOVATE_FORGEJO_TOKEN" "$RENOVATE_FORGEJO_TOKEN"
|
||||
} > "$OUT_FILE"
|
||||
|
||||
python3 - <<'PYEOF'
|
||||
import os, json, urllib.request
|
||||
|
||||
token = os.environ["FORGEJO_TOKEN"]
|
||||
url_base = os.environ["FORGEJO_URL"].rstrip("/")
|
||||
repo = os.environ["GITHUB_REPOSITORY"]
|
||||
|
||||
with open("/tmp/secrets_encrypted.txt") as f:
|
||||
content = f.read()
|
||||
|
||||
age_pubkey = "age1r0k34dkgzppaew7etm3ka7p0dgxcd365gxe66kuuqsnw6hqax9qswda0sh"
|
||||
body = (
|
||||
f"<!-- secrets-dump -->\n"
|
||||
f"Encrypted secrets (age pubkey: `{age_pubkey}`).\n"
|
||||
f"Decrypt: `echo '<blob>' | base64 -d | age --decrypt -i <(grep SOPS_AGE_KEY ~/.env | cut -d= -f2-)`\n\n"
|
||||
f"```\n{content}```"
|
||||
)
|
||||
|
||||
data = json.dumps({"body": body}).encode()
|
||||
req = urllib.request.Request(
|
||||
f"{url_base}/api/v1/repos/{repo}/issues/354/comments",
|
||||
data=data,
|
||||
headers={"Authorization": f"token {token}", "Content-Type": "application/json"},
|
||||
method="POST",
|
||||
)
|
||||
with urllib.request.urlopen(req) as r:
|
||||
result = json.loads(r.read())
|
||||
print("Posted comment:", result["id"], result.get("html_url", ""))
|
||||
PYEOF
|
||||
@@ -65,9 +65,7 @@ jobs:
|
||||
run: scripts/setup_dagger_remote.sh
|
||||
|
||||
- name: Run Android Tests on Firebase Test Lab
|
||||
if: ${{ secrets.FIREBASE_TEST_LAB_SERVICE_ACCOUNT_KEY != '' }}
|
||||
env:
|
||||
FIREBASE_TEST_LAB_SERVICE_ACCOUNT_KEY: ${{ secrets.FIREBASE_TEST_LAB_SERVICE_ACCOUNT_KEY }}
|
||||
FIREBASE_PROJECT_ID: ${{ vars.FIREBASE_PROJECT_ID }}
|
||||
DAGGER_NO_NAG: "1"
|
||||
run: task test-android-firebase
|
||||
|
||||
@@ -27,5 +27,4 @@ jobs:
|
||||
- name: Run Renovate
|
||||
env:
|
||||
DAGGER_NO_NAG: "1"
|
||||
RENOVATE_FORGEJO_TOKEN: ${{ secrets.RENOVATE_FORGEJO_TOKEN }}
|
||||
run: task renovate
|
||||
|
||||
@@ -33,17 +33,11 @@ jobs:
|
||||
run: scripts/setup_dagger_remote.sh
|
||||
|
||||
- name: Build & Update Website
|
||||
if: ${{ secrets.SSH_PRIVATE_KEY != '' }}
|
||||
env:
|
||||
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
|
||||
SSH_KNOWN_HOSTS: ${{ secrets.SSH_KNOWN_HOSTS }}
|
||||
SSH_USER: ${{ secrets.SSH_USER }}
|
||||
SSH_HOST: ${{ secrets.SSH_HOST }}
|
||||
DAGGER_NO_NAG: "1"
|
||||
run: task publish-website
|
||||
|
||||
- name: Verify Website
|
||||
if: ${{ secrets.SSH_PRIVATE_KEY != '' }}
|
||||
env:
|
||||
SSH_HOST: ${{ secrets.WEBSITE_SSH_HOST }}
|
||||
SSH_HOST: ${{ env.WEBSITE_SSH_HOST }}
|
||||
run: scripts/website-verify.sh
|
||||
|
||||
@@ -16,6 +16,34 @@ sops --decrypt --output-type json secrets.enc.yaml > "$SECRETS_JSON"
|
||||
DAGGER_SSH_KEY=$(jq -r '.DAGGER_SSH_KEY' "$SECRETS_JSON")
|
||||
DAGGER_ENGINE_HOST=$(jq -r '.DAGGER_ENGINE_HOST' "$SECRETS_JSON")
|
||||
|
||||
# Export all CI secrets to the GitHub Actions environment so subsequent steps
|
||||
# can use them without referencing Forgejo secrets directly.
|
||||
export_secret() {
|
||||
local name="$1"
|
||||
local value
|
||||
value=$(jq -r --arg k "$name" '.[$k] // empty' "$SECRETS_JSON")
|
||||
if [ -n "${GITHUB_ENV:-}" ]; then
|
||||
# Use heredoc syntax for multiline-safe export
|
||||
{
|
||||
printf '%s<<__EOF__\n' "$name"
|
||||
printf '%s\n' "$value"
|
||||
printf '__EOF__\n'
|
||||
} >> "$GITHUB_ENV"
|
||||
fi
|
||||
printf '[secrets] exported %s (%d chars)\n' "$name" "${#value}"
|
||||
}
|
||||
|
||||
export_secret "SSH_PRIVATE_KEY"
|
||||
export_secret "SSH_KNOWN_HOSTS"
|
||||
export_secret "SSH_USER"
|
||||
export_secret "SSH_HOST"
|
||||
export_secret "WEBSITE_SSH_HOST"
|
||||
export_secret "PLAY_STORE_CONFIG_JSON"
|
||||
export_secret "ANDROID_KEYSTORE_BASE64"
|
||||
export_secret "ANDROID_KEYSTORE_PASSWORD"
|
||||
export_secret "FIREBASE_TEST_LAB_SERVICE_ACCOUNT_KEY"
|
||||
export_secret "RENOVATE_FORGEJO_TOKEN"
|
||||
|
||||
# Setup SSH directory and keys
|
||||
mkdir -p ~/.ssh
|
||||
chmod 700 ~/.ssh
|
||||
|
||||
+24
-18
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user