2026-05-17 11:50:39 +02:00
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
set -euo pipefail
|
2026-06-05 18:41:36 +02:00
|
|
|
[ "${CI:-}" = "true" ] || [ "$(id -u)" != "0" ] || { echo "ERROR: Do not run as root. See DEVELOPMENT.md."; exit 1; }
|
2026-05-17 11:50:39 +02:00
|
|
|
|
2026-06-02 11:10:29 +02:00
|
|
|
if [ -z "${SOPS_AGE_KEY:-}" ]; then
|
|
|
|
|
echo "Error: SOPS_AGE_KEY must be set."
|
|
|
|
|
exit 1
|
2026-05-20 15:48:38 +02:00
|
|
|
fi
|
2026-05-17 11:50:39 +02:00
|
|
|
|
2026-06-02 11:10:29 +02:00
|
|
|
echo "Decrypting secrets with SOPS..."
|
|
|
|
|
export SOPS_AGE_KEY="$SOPS_AGE_KEY"
|
|
|
|
|
SECRETS_JSON=$(mktemp)
|
|
|
|
|
trap "rm -f $SECRETS_JSON" EXIT
|
|
|
|
|
|
2026-06-02 12:45:34 +02:00
|
|
|
sops --decrypt --output-type json secrets.enc.yaml > "$SECRETS_JSON"
|
2026-05-17 11:50:39 +02:00
|
|
|
|
2026-06-02 11:10:29 +02:00
|
|
|
DAGGER_SSH_KEY=$(jq -r '.DAGGER_SSH_KEY' "$SECRETS_JSON")
|
|
|
|
|
DAGGER_ENGINE_HOST=$(jq -r '.DAGGER_ENGINE_HOST' "$SECRETS_JSON")
|
2026-05-17 11:50:39 +02:00
|
|
|
|
2026-06-06 05:38:47 +02:00
|
|
|
# Register inline secrets for log redaction. Multiline values (e.g. SSH keys)
|
|
|
|
|
# must be masked line-by-line because ::add-mask:: covers one line at a time.
|
|
|
|
|
printf '::add-mask::%s\n' "$DAGGER_ENGINE_HOST"
|
|
|
|
|
while IFS= read -r line; do
|
|
|
|
|
[ -n "$line" ] && printf '::add-mask::%s\n' "$line"
|
|
|
|
|
done <<< "$DAGGER_SSH_KEY"
|
|
|
|
|
|
2026-06-03 06:37:07 +02:00
|
|
|
# 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")
|
2026-06-06 05:38:47 +02:00
|
|
|
# Register each non-empty line for log redaction in the Actions runner.
|
|
|
|
|
if [ -n "$value" ] && [ -n "${GITHUB_ENV:-}" ]; then
|
|
|
|
|
while IFS= read -r line; do
|
|
|
|
|
[ -n "$line" ] && printf '::add-mask::%s\n' "$line"
|
|
|
|
|
done <<< "$value"
|
|
|
|
|
fi
|
2026-06-03 06:37:07 +02:00
|
|
|
if [ -n "${GITHUB_ENV:-}" ]; then
|
2026-06-03 21:23:13 +02:00
|
|
|
# Use heredoc syntax for multiline-safe export.
|
|
|
|
|
# Avoid adding a second trailing newline for values that already end with one
|
|
|
|
|
# (e.g. SSH private keys), which can corrupt PEM parsing.
|
2026-06-03 06:37:07 +02:00
|
|
|
{
|
|
|
|
|
printf '%s<<__EOF__\n' "$name"
|
2026-06-03 21:23:13 +02:00
|
|
|
printf '%s' "$value"
|
|
|
|
|
[ "${value%$'\n'}" = "$value" ] && printf '\n'
|
2026-06-03 06:37:07 +02:00
|
|
|
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"
|
|
|
|
|
|
2026-06-02 16:24:56 +02:00
|
|
|
# Setup SSH directory and keys
|
2026-06-02 11:10:29 +02:00
|
|
|
mkdir -p ~/.ssh
|
|
|
|
|
chmod 700 ~/.ssh
|
2026-06-05 18:41:36 +02:00
|
|
|
rm -f ~/.ssh/dagger_key
|
2026-06-02 11:10:29 +02:00
|
|
|
echo "$DAGGER_SSH_KEY" > ~/.ssh/dagger_key
|
|
|
|
|
chmod 600 ~/.ssh/dagger_key
|
2026-05-17 11:50:39 +02:00
|
|
|
|
2026-06-02 16:52:16 +02:00
|
|
|
# Add remote host to known_hosts
|
2026-06-05 11:49:30 +02:00
|
|
|
_t0=$SECONDS
|
|
|
|
|
timeout 30 ssh-keyscan -H "$DAGGER_ENGINE_HOST" >> ~/.ssh/known_hosts 2>/dev/null
|
|
|
|
|
_elapsed=$(( SECONDS - _t0 ))
|
|
|
|
|
if [ "$_elapsed" -gt 10 ]; then
|
|
|
|
|
echo "::warning::ssh-keyscan took ${_elapsed}s — Dagger engine host may be slow to respond"
|
|
|
|
|
fi
|
2026-06-02 16:21:49 +02:00
|
|
|
|
2026-06-02 16:52:16 +02:00
|
|
|
# Create a background SSH tunnel to the Dagger engine.
|
|
|
|
|
# We map local port 8080 to remote port 1774 (where our socat bridge is listening).
|
|
|
|
|
echo "Establishing SSH tunnel to $DAGGER_ENGINE_HOST..."
|
2026-06-05 11:49:30 +02:00
|
|
|
_t0=$SECONDS
|
|
|
|
|
timeout 30 ssh -i ~/.ssh/dagger_key -o StrictHostKeyChecking=no -f -N -L 8080:localhost:1774 "dagger@$DAGGER_ENGINE_HOST"
|
|
|
|
|
_elapsed=$(( SECONDS - _t0 ))
|
|
|
|
|
if [ "$_elapsed" -gt 10 ]; then
|
|
|
|
|
echo "::warning::SSH tunnel setup took ${_elapsed}s"
|
|
|
|
|
fi
|
2026-05-17 11:50:39 +02:00
|
|
|
|
2026-06-02 16:52:16 +02:00
|
|
|
# Export _EXPERIMENTAL_DAGGER_RUNNER_HOST to use the tunnel.
|
|
|
|
|
export _EXPERIMENTAL_DAGGER_RUNNER_HOST="tcp://localhost:8080"
|
2026-06-02 13:31:11 +02:00
|
|
|
if [ -n "${GITHUB_ENV:-}" ]; then
|
2026-06-02 16:52:16 +02:00
|
|
|
echo "_EXPERIMENTAL_DAGGER_RUNNER_HOST=tcp://localhost:8080" >> "$GITHUB_ENV"
|
2026-06-02 13:31:11 +02:00
|
|
|
fi
|
2026-06-02 11:10:29 +02:00
|
|
|
|
2026-06-02 16:52:16 +02:00
|
|
|
# Verify the connection
|
|
|
|
|
echo "Verifying connection to Dagger engine via SSH tunnel..."
|
2026-06-02 16:55:18 +02:00
|
|
|
# Use a simple command that doesn't require complex GraphQL operations.
|
|
|
|
|
if ! timeout 45 dagger core --help >/dev/null 2>&1 ; then
|
2026-06-02 16:52:16 +02:00
|
|
|
echo "Error: Dagger engine unreachable via tunnel at localhost:8080"
|
|
|
|
|
# Debug
|
|
|
|
|
ps aux | grep ssh
|
2026-06-02 11:10:29 +02:00
|
|
|
exit 1
|
2026-05-17 11:50:39 +02:00
|
|
|
fi
|
2026-06-02 16:24:56 +02:00
|
|
|
echo "Dagger connection verified successfully."
|