Files
PTSRaiAgent/infra/deploy/env-sync.sh

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