#!/usr/bin/env bash # deploy-env.sh — Fetch Gitea Actions variables and write .env files. # Called by the CI/CD deploy step on the self-hosted runner. # # Required env vars (injected by Gitea Actions): # GITEA_TOKEN — API token with repo read access # GITEA_OWNER — repo owner (e.g. Ichitux) # GITEA_REPO — repo name (e.g. FarmaFinder) # # Usage: # GITEA_TOKEN=xxx GITEA_OWNER=Ichitux GITEA_REPO=FarmaFinder ./scripts/deploy-env.sh set -euo pipefail GITEA_URL="${GITEA_URL:-https://git.hacecalor.net}" WORK_DIR="${WORK_DIR:-.}" # --------------------------------------------------------------------------- # Helper: fetch all repo variables from Gitea API (handles pagination) # Returns JSON array on stdout # --------------------------------------------------------------------------- fetch_variables() { local page=1 limit=50 all='[]' while true; do local resp resp=$(curl -sf \ -H "Authorization: token ${GITEA_TOKEN}" \ "${GITEA_URL}/api/v1/repos/${GITEA_OWNER}/${GITEA_REPO}/actions/variables?limit=${limit}&page=${page}") local count count=$(echo "$resp" | python3 -c "import sys,json; print(len(json.load(sys.stdin)))") all=$(python3 -c " import sys, json a = json.loads('''${all}''') b = json.loads(sys.stdin.read()) print(json.dumps(a + b)) " <<< "$resp") if [ "$count" -lt "$limit" ]; then break fi page=$((page + 1)) done echo "$all" } # --------------------------------------------------------------------------- # Helper: write a .env file from a JSON object of key-value pairs. # Keys are sorted alphabetically. Comments from .env.example are preserved. # --------------------------------------------------------------------------- write_env() { local env_path="$1" local json_obj="$2" local example_path="${env_path}.example" # If no example file exists, write a plain KEY=VALUE file if [ ! -f "$example_path" ]; then python3 -c " import json, sys obj = json.loads('''${json_obj}''') for k in sorted(obj): print(f'{k}={obj[k]}') " > "$env_path" echo "[env] Wrote $env_path (${#json_obj} bytes, no .example template)" return fi # If .example exists, produce a file that preserves comments/order # and fills in values from the JSON python3 -c " import json, sys, re example_path = '''${example_path}''' env_path = '''${env_path}''' values = json.loads('''${json_obj}''') with open(example_path) as f: lines = f.readlines() output = [] written_keys = set() for line in lines: stripped = line.rstrip('\n') # Pass through comments and blank lines if stripped.startswith('#') or stripped.strip() == '': output.append(stripped) continue # Parse KEY=VALUE lines m = re.match(r'^([A-Za-z_][A-Za-z0-9_]*)=(.*)', stripped) if m: key, _ = m.group(1), m.group(2) if key in values: output.append(f'{key}={values[key]}') written_keys.add(key) else: output.append(stripped) # keep example default else: output.append(stripped) # Append any keys from values that weren't in .example for k in sorted(values): if k not in written_keys: output.append(f'{k}={values[k]}') with open(env_path, 'w') as f: f.write('\n'.join(output) + '\n') print(f'[env] Wrote {env_path} ({len(values)} vars)') " 2>&1 } # --------------------------------------------------------------------------- # Main # --------------------------------------------------------------------------- echo "=== deploy-env.sh ===" echo "Fetching variables from Gitea: ${GITEA_OWNER}/${GITEA_REPO}" VARS_JSON=$(fetch_variables) VAR_COUNT=$(echo "$VARS_JSON" | python3 -c "import sys,json; print(len(json.load(sys.stdin)))") echo "Found ${VAR_COUNT} variables" # Group variables by prefix # ROOT_* → root .env (strip prefix) # BACKEND_* → apps/backend/.env (strip prefix) # FRONTEND_* → apps/frontend/.env (strip prefix) # PARAPHARMACY_* → apps/parapharmacy-api/.env (strip prefix) # No prefix → root .env (backward compat with original vars) ROOT_VARS=$(python3 -c " import json, sys vars = json.loads(sys.stdin.read()) # Keys that are CI-only and should NOT appear in application .env files skip = {'GITEA_TOKEN'} result = {} for v in vars: name = v['name'] value = v['data'] if name in skip: continue if name.startswith('ROOT_'): result[name[5:]] = value # strip ROOT_ prefix elif not any(name.startswith(p) for p in ['BACKEND_', 'FRONTEND_', 'PARAPHARMACY_']): result[name] = value # unprefixed → root print(json.dumps(result)) " <<< "$VARS_JSON") BACKEND_VARS=$(python3 -c " import json, sys vars = json.loads(sys.stdin.read()) result = {} for v in vars: name = v['name'] if name.startswith('BACKEND_'): result[name[8:]] = value = v['data'] print(json.dumps(result)) " <<< "$VARS_JSON") FRONTEND_VARS=$(python3 -c " import json, sys vars = json.loads(sys.stdin.read()) result = {} for v in vars: name = v['name'] if name.startswith('FRONTEND_'): result[name[9:]] = v['data'] print(json.dumps(result)) " <<< "$VARS_JSON") PARAPHARMACY_VARS=$(python3 -c " import json, sys vars = json.loads(sys.stdin.read()) result = {} for v in vars: name = v['name'] if name.startswith('PARAPHARMACY_'): result[name[13:]] = v['data'] print(json.dumps(result)) " <<< "$VARS_JSON") # Write each .env file echo "" write_env "${WORK_DIR}/.env" "$ROOT_VARS" write_env "${WORK_DIR}/apps/backend/.env" "$BACKEND_VARS" write_env "${WORK_DIR}/apps/frontend/.env" "$FRONTEND_VARS" write_env "${WORK_DIR}/apps/parapharmacy-api/.env" "$PARAPHARMACY_VARS" echo "" echo "=== All .env files written ==="