65 lines
3.0 KiB
Bash
Executable File
65 lines
3.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Sync service variables from the local .env to the server — now and for every future deploy.
|
|
# make env-sync (or infra/deploy/env-sync.sh [path/to/.env])
|
|
# 1. Filters the local env: drops GITEA_*, empty values and server-managed keys (DB passwords, PSEUDO_KEY, URLs).
|
|
# 2. Stores the result as the Gitea Actions secret SERVICE_ENV → CD merges it into /srv/ptsr/.env on each deploy.
|
|
# 3. Applies it on the server right away and recreates app + dashboard if anything changed.
|
|
# Values are never printed; only key names.
|
|
set -euo pipefail
|
|
SRC=${1:-.env}
|
|
HOST=${DEPLOY_HOST:-vobot}
|
|
OPTS=${DEPLOY_SSH_OPTS:-}
|
|
DIR=/srv/ptsr
|
|
HERE=$(cd "$(dirname "$0")" && pwd)
|
|
[ -f "$SRC" ] || { echo "no $SRC"; exit 1; }
|
|
# Values without inline comments / trailing spaces ("KEY=value # коммент" → "value").
|
|
val() { grep -E "^$1=" "$SRC" | tail -1 | cut -d= -f2- | sed -E 's/[[:space:]]+#.*$//; s/[[:space:]]+$//' || true; }
|
|
GITEA_URL=$(val GITEA_URL)
|
|
GITEA_REPO=$(val GITEA_REPO)
|
|
GITEA_TOKEN=$(val GITEA_TOKEN)
|
|
export GITEA_URL GITEA_REPO GITEA_TOKEN
|
|
|
|
OUT=$(mktemp)
|
|
trap 'rm -f "$OUT"' EXIT
|
|
sed -E 's/[[:space:]]+#.*$//; s/[[:space:]]+$//' "$SRC" \
|
|
| grep -E '^[A-Z_][A-Z0-9_]*=.+' \
|
|
| grep -vE '^(GITEA_[A-Z_]*|POSTGRES_PASSWORD|IDENTITY_DB_PASSWORD|CLINICAL_DB_PASSWORD|PSEUDO_KEY|PUBLIC_URL|IDENTITY_DB_URL|CLINICAL_DB_URL|API_BASE_URL)=' \
|
|
> "$OUT" || true
|
|
echo "keys: $(cut -d= -f1 "$OUT" | tr '\n' ' ')"
|
|
[ -s "$OUT" ] || { echo "nothing to sync"; exit 0; }
|
|
|
|
if [ -n "$GITEA_TOKEN" ] && [ -n "$GITEA_URL" ] && [ -n "$GITEA_REPO" ]; then
|
|
python3 - "$OUT" <<'PY'
|
|
import json, os, sys, urllib.request
|
|
url = f"{os.environ['GITEA_URL']}/api/v1/repos/{os.environ['GITEA_REPO']}/actions/secrets/SERVICE_ENV"
|
|
body = json.dumps({"data": open(sys.argv[1]).read()}).encode()
|
|
req = urllib.request.Request(url, method="PUT", data=body,
|
|
headers={"Authorization": f"token {os.environ['GITEA_TOKEN']}",
|
|
"Content-Type": "application/json"})
|
|
print("gitea secret SERVICE_ENV:", urllib.request.urlopen(req).status)
|
|
PY
|
|
else
|
|
echo "GITEA_* not set in $SRC — skipping the CD secret (server-only sync)"
|
|
fi
|
|
|
|
retry() { local n=0; until "$@"; do n=$((n + 1)); [ $n -ge 5 ] && return 1; sleep $((n * 10)); done; }
|
|
# shellcheck disable=SC2086
|
|
retry scp -q $OPTS "$OUT" "$HOST:$DIR/service.env"
|
|
# shellcheck disable=SC2086
|
|
retry scp -q $OPTS "$HERE/env_merge.py" "$HOST:$DIR/env_merge.py"
|
|
# shellcheck disable=SC2086
|
|
retry ssh $OPTS "$HOST" "bash -s" <<SH
|
|
set -euo pipefail
|
|
cd $DIR
|
|
rc=0; python3 env_merge.py .env service.env || rc=\$?
|
|
rm -f service.env
|
|
if [ "\$rc" = 0 ]; then
|
|
cp .env app/.env
|
|
cd app && docker compose -p ptsr -f docker-compose.yml -f infra/deploy/docker-compose.server.yml up -d --force-recreate app dashboard </dev/null 2>&1 | tail -2
|
|
for i in \$(seq 1 30); do curl -sf 127.0.0.1:8010/health >/dev/null && break; sleep 2; done
|
|
curl -sf 127.0.0.1:8010/health >/dev/null && echo "api ok"
|
|
elif [ "\$rc" != 3 ]; then
|
|
exit "\$rc"
|
|
fi
|
|
SH
|