diff --git a/deploy-home.sh b/deploy-home.sh index c1986aa..ac34c4a 100755 --- a/deploy-home.sh +++ b/deploy-home.sh @@ -214,11 +214,14 @@ if [ "$SYNC" = true ]; then echo -e "${YELLOW} 서버 전송 중...${NC}" $SCP_CMD "$TEMP_ARCHIVE" "${SSH_TARGET}:/tmp/gc-deploy.tar.gz" echo -e "${YELLOW} 서버 기존 소스 정리 후 압축 해제 중...${NC}" - remote_exec "rm -rf ${REMOTE_PROJECT_DIR} && \ + remote_exec "ENV_BAK=/tmp/gc-env-backup-\$\$; \ + if [ -f ${REMOTE_PROJECT_DIR}/.env ]; then cp ${REMOTE_PROJECT_DIR}/.env \"\$ENV_BAK\"; fi; \ + rm -rf ${REMOTE_PROJECT_DIR} && \ mkdir -p ${REMOTE_PROJECT_DIR} && \ cd ${REMOTE_PROJECT_DIR} && \ tar -xzf /tmp/gc-deploy.tar.gz && \ - rm -f /tmp/gc-deploy.tar.gz" + rm -f /tmp/gc-deploy.tar.gz && \ + if [ -f \"\$ENV_BAK\" ]; then mv \"\$ENV_BAK\" ${REMOTE_PROJECT_DIR}/.env && chmod 600 ${REMOTE_PROJECT_DIR}/.env; fi" rm -f "$TEMP_ARCHIVE" echo -e "${GREEN}✓ 파일 동기화 완료${NC}" else diff --git a/scripts/bootstrap-desktop-jenkins-env.sh b/scripts/bootstrap-desktop-jenkins-env.sh new file mode 100755 index 0000000..7629e8c --- /dev/null +++ b/scripts/bootstrap-desktop-jenkins-env.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env bash +# exdev 서버 — Jenkins API Token + backend .env 자동 생성 (비대화형) +# 사용: JENKINS_CI_PASSWORD=... ./scripts/bootstrap-desktop-jenkins-env.sh +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" +ENV_FILE="${ENV_FILE:-$REPO_ROOT/.env}" + +JENKINS_URL="${JENKINS_URL:-http://127.0.0.1:8090}" +JENKINS_USER="${JENKINS_CI_USER:-goldenchart-ci}" +JENKINS_PASS="${JENKINS_CI_PASSWORD:-}" +JENKINS_JOB="${GC_DESKTOP_JENKINS_JOB:-goldenChart-Desktop-Pipeline}" +JENKINS_TRIGGER_TOKEN="${GC_DESKTOP_JENKINS_TRIGGER_TOKEN:-goldenchart-desktop-build}" +WORK_TREE="${GC_WORK_TREE:-$REPO_ROOT}" +GIT_BARE="${GC_GIT_BARE_DIR:-/Volumes/ADATA/git/goldenChart.git}" + +log() { echo "[bootstrap-jenkins-env] $*"; } + +if [[ -f "$ENV_FILE" ]] && grep -q '^GC_DESKTOP_JENKINS_TOKEN=.\+' "$ENV_FILE" 2>/dev/null; then + log "이미 GC_DESKTOP_JENKINS_TOKEN 설정됨 — $ENV_FILE" + exit 0 +fi + +if [[ -z "$JENKINS_PASS" ]]; then + echo "ERROR: JENKINS_CI_PASSWORD 환경변수 필요 (Jenkins 사용자: $JENKINS_USER)" >&2 + exit 1 +fi + +if ! curl -sf -o /dev/null "${JENKINS_URL%/}/login"; then + echo "ERROR: Jenkins unreachable: $JENKINS_URL" >&2 + exit 1 +fi + +JAR="$(mktemp)" +trap 'rm -f "$JAR"' EXIT + +CRUMB_JSON="$(curl -sf -c "$JAR" -b "$JAR" -u "${JENKINS_USER}:${JENKINS_PASS}" "${JENKINS_URL%/}/crumbIssuer/api/json")" +CRUMB_FIELD="$(printf '%s' "$CRUMB_JSON" | python3 -c "import sys,json; print(json.load(sys.stdin)['crumbRequestField'])")" +CRUMB="$(printf '%s' "$CRUMB_JSON" | python3 -c "import sys,json; print(json.load(sys.stdin)['crumb'])")" + +TOKEN_JSON="$(curl -sf -c "$JAR" -b "$JAR" -u "${JENKINS_USER}:${JENKINS_PASS}" \ + -H "${CRUMB_FIELD}: ${CRUMB}" -X POST \ + "${JENKINS_URL%/}/user/${JENKINS_USER}/descriptorByName/jenkins.security.ApiTokenProperty/generateNewToken" \ + --data-urlencode "newTokenName=goldenchart-backend-$(date +%Y%m%d)")" + +API_TOKEN="$(printf '%s' "$TOKEN_JSON" | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['tokenValue'])")" + +mkdir -p "$(dirname "$ENV_FILE")" +touch "$ENV_FILE" + +upsert() { + local k="$1" v="$2" + if grep -q "^${k}=" "$ENV_FILE" 2>/dev/null; then + if [[ "$(uname)" == "Darwin" ]]; then sed -i '' "s|^${k}=.*|${k}=${v}|" "$ENV_FILE" + else sed -i "s|^${k}=.*|${k}=${v}|" "$ENV_FILE"; fi + else echo "${k}=${v}" >> "$ENV_FILE"; fi +} + +upsert GC_DESKTOP_JENKINS_ENABLED true +upsert GC_DESKTOP_JENKINS_URL "http://host.docker.internal:8090" +upsert GC_DESKTOP_JENKINS_JOB "$JENKINS_JOB" +upsert GC_DESKTOP_JENKINS_USER "$JENKINS_USER" +upsert GC_DESKTOP_JENKINS_TOKEN "$API_TOKEN" +upsert GC_DESKTOP_JENKINS_TRIGGER_TOKEN "$JENKINS_TRIGGER_TOKEN" +upsert GC_GIT_BARE_DIR "$GIT_BARE" +upsert GC_WORK_TREE "$WORK_TREE" +chmod 600 "$ENV_FILE" + +log "Wrote $ENV_FILE (user=$JENKINS_USER)" +log "backend 재시작: cd $REPO_ROOT && docker compose up -d backend"