da11a9c29f
- Git 저장소/배포 work-tree를 /Users/aidev/apps/goldenChart로 통일 - 레거시 dev 경로는 심볼릭 링크로 흡수, deploy.sh에 소스 검증·no-cache 옵션 - server-rebuild-exdev.sh, verify-source-sync.sh 추가 Co-authored-by: Cursor <cursoragent@cursor.com>
173 lines
7.3 KiB
Bash
Executable File
173 lines
7.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# ==============================================================================
|
|
# exdev.co.kr — Git bare + work-tree + Jenkins 완전 재구축
|
|
# 실행 위치: 서버 (aidev@exdev.co.kr) 또는 로컬에서 ssh로 원격 실행
|
|
#
|
|
# 유지 경로 (현재 운영과 동일):
|
|
# GIT_DIR = /Volumes/ADATA/git/goldenChart.git
|
|
# WORK_TREE = /Users/aidev/apps/goldenChart
|
|
# DEPLOY_SCRIPT= /Volumes/ADATA/git/deploy.sh
|
|
# DEPLOY_LOG = /Volumes/ADATA/logs/deploy/deploy.log
|
|
# Jenkins = http://127.0.0.1:8090 job: goldenChart-Pipeline
|
|
# ==============================================================================
|
|
set -euo pipefail
|
|
|
|
export PATH="/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:${PATH:-/usr/bin:/bin}"
|
|
|
|
GIT_DIR="/Volumes/ADATA/git/goldenChart.git"
|
|
WORK_TREE="/Users/aidev/apps/goldenChart"
|
|
DEPLOY_SCRIPT="/Volumes/ADATA/git/deploy.sh"
|
|
DEPLOY_LOG="/Volumes/ADATA/logs/deploy/deploy.log"
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
JENKINS_HOME="${JENKINS_HOME:-$HOME/.jenkins}"
|
|
JENKINS_JOB="goldenChart-Pipeline"
|
|
STAMP="$(date +%Y%m%d-%H%M%S)"
|
|
BACKUP_ROOT="/Volumes/ADATA/backup/goldenChart-rebuild-${STAMP}"
|
|
|
|
log() { echo "[rebuild $(date '+%H:%M:%S')] $*"; }
|
|
|
|
log "백업 디렉터리: $BACKUP_ROOT"
|
|
mkdir -p "$BACKUP_ROOT" "$(dirname "$DEPLOY_LOG")" /Volumes/ADATA/logs/deploy/push-summaries
|
|
|
|
# ── 1. Jenkins Job 제거 (데이터는 유지, job만 초기화) ─────────────────────
|
|
log "Jenkins job 제거: $JENKINS_JOB"
|
|
rm -rf "${JENKINS_HOME}/jobs/${JENKINS_JOB}"
|
|
rm -f "${JENKINS_HOME}/jobs/${JENKINS_JOB}.xml" 2>/dev/null || true
|
|
|
|
# ── 2. work-tree 백업 (.env·데이터 보존) ───────────────────────────────────
|
|
if [ -d "$WORK_TREE" ]; then
|
|
log "work-tree 백업 → $BACKUP_ROOT/work-tree-snapshot"
|
|
mkdir -p "$BACKUP_ROOT/work-tree-snapshot"
|
|
[ -f "$WORK_TREE/.env" ] && cp -a "$WORK_TREE/.env" "$BACKUP_ROOT/.env"
|
|
# embedded .git 제거 대상 — 백업만
|
|
if [ -d "$WORK_TREE/.git" ]; then
|
|
log "work-tree 내 중첩 .git 백업 (배포 혼선 원인)"
|
|
cp -a "$WORK_TREE/.git" "$BACKUP_ROOT/work-tree-snapshot/dot-git-nested"
|
|
fi
|
|
fi
|
|
|
|
# ── 3. bare 저장소 제거 후 재생성 ───────────────────────────────────────────
|
|
if [ -d "$GIT_DIR" ]; then
|
|
log "bare 저장소 백업 → $BACKUP_ROOT/goldenChart.git.tgz"
|
|
tar -czf "$BACKUP_ROOT/goldenChart.git.tgz" -C "$(dirname "$GIT_DIR")" "$(basename "$GIT_DIR")" 2>/dev/null || true
|
|
log "bare 저장소 제거: $GIT_DIR"
|
|
rm -rf "$GIT_DIR"
|
|
fi
|
|
|
|
log "bare 저장소 초기화"
|
|
git init --bare "$GIT_DIR"
|
|
git --git-dir="$GIT_DIR" symbolic-ref HEAD refs/heads/main
|
|
|
|
# ── 4. 레거시 work-tree 제거·단일 경로 고정 ─────────────────────────────────
|
|
LEGACY_WORK_TREE="/Users/aidev/dev/goldenChart"
|
|
if [ -e "$LEGACY_WORK_TREE" ] || [ -L "$LEGACY_WORK_TREE" ]; then
|
|
log "레거시 경로 백업·이동: $LEGACY_WORK_TREE"
|
|
if [ -d "$LEGACY_WORK_TREE" ] && [ ! -L "$LEGACY_WORK_TREE" ]; then
|
|
tar -czf "$BACKUP_ROOT/legacy-dev-goldenChart.tgz" -C "$(dirname "$LEGACY_WORK_TREE")" "$(basename "$LEGACY_WORK_TREE")" 2>/dev/null || true
|
|
mv "$LEGACY_WORK_TREE" "$BACKUP_ROOT/legacy-dev-goldenChart-dir" 2>/dev/null || true
|
|
else
|
|
rm -f "$LEGACY_WORK_TREE" 2>/dev/null || true
|
|
fi
|
|
fi
|
|
ln -sfn "$WORK_TREE" "$LEGACY_WORK_TREE"
|
|
log " → $LEGACY_WORK_TREE → $WORK_TREE (심볼릭 링크)"
|
|
|
|
# ── 5. work-tree 정리 (중첩 .git 제거, 소스만 비움) ───────────────────────
|
|
log "work-tree 정리: $WORK_TREE"
|
|
mkdir -p "$WORK_TREE"
|
|
if [ -d "$WORK_TREE/.git" ]; then
|
|
rm -rf "$WORK_TREE/.git"
|
|
log " → 중첩 .git 제거 완료"
|
|
fi
|
|
# 소스 파일만 삭제 (.env·data·docker 볼륨 경로 유지)
|
|
find "$WORK_TREE" -mindepth 1 -maxdepth 1 \
|
|
! -name '.env' \
|
|
! -name '.env.*' \
|
|
! -name 'data' \
|
|
-exec rm -rf {} + 2>/dev/null || true
|
|
|
|
[ -f "$BACKUP_ROOT/.env" ] && cp -a "$BACKUP_ROOT/.env" "$WORK_TREE/.env" && log " → .env 복원"
|
|
|
|
# ── 6. deploy.sh · post-receive 설치 ───────────────────────────────────────
|
|
log "deploy.sh 설치"
|
|
cp -f "$REPO_ROOT/scripts/deploy.sh" "$DEPLOY_SCRIPT"
|
|
chmod +x "$DEPLOY_SCRIPT"
|
|
|
|
log "post-receive 훅 설치"
|
|
cp -f "$REPO_ROOT/scripts/post-receive" "$GIT_DIR/hooks/post-receive"
|
|
chmod +x "$GIT_DIR/hooks/post-receive"
|
|
|
|
if [ -x /Volumes/ADATA/git/git-push-summary.sh ]; then
|
|
log "git-push-summary.sh 유지"
|
|
else
|
|
log "[WARN] /Volumes/ADATA/git/git-push-summary.sh 없음 — push 요약 생략"
|
|
fi
|
|
|
|
# ── 7. Jenkins Job 재생성 ──────────────────────────────────────────────────
|
|
log "Jenkins job 생성: $JENKINS_JOB"
|
|
mkdir -p "${JENKINS_HOME}/jobs/${JENKINS_JOB}"
|
|
cat > "${JENKINS_HOME}/jobs/${JENKINS_JOB}/config.xml" << 'JENKINS_XML'
|
|
<?xml version='1.1' encoding='UTF-8'?>
|
|
<project>
|
|
<description>GoldenChart — Track B (deploy.sh, file:// bare repo)</description>
|
|
<keepDependencies>false</keepDependencies>
|
|
<properties/>
|
|
<scm class="hudson.plugins.git.GitSCM" plugin="git@5.0.0">
|
|
<configVersion>2</configVersion>
|
|
<userRemoteConfigs>
|
|
<hudson.plugins.git.UserRemoteConfig>
|
|
<url>file:///Volumes/ADATA/git/goldenChart.git</url>
|
|
</hudson.plugins.git.UserRemoteConfig>
|
|
</userRemoteConfigs>
|
|
<branches>
|
|
<hudson.plugins.git.BranchSpec>
|
|
<name>*/main</name>
|
|
</hudson.plugins.git.BranchSpec>
|
|
</branches>
|
|
<doGenerateSubmoduleConfigurations>false</doGenerateSubmoduleConfigurations>
|
|
<submoduleCfg class="empty-list"/>
|
|
<extensions/>
|
|
</scm>
|
|
<canRoam>true</canRoam>
|
|
<disabled>false</disabled>
|
|
<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
|
|
<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
|
|
<triggers/>
|
|
<concurrentBuild>false</concurrentBuild>
|
|
<builders>
|
|
<hudson.tasks.Shell>
|
|
<command>#!/bin/bash
|
|
set -euo pipefail
|
|
export PATH="/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:$PATH"
|
|
echo "=== goldenChart Jenkins Build #${BUILD_NUMBER} ==="
|
|
echo "시각: $(date)"
|
|
SERVICE_NAME="${SERVICE_NAME:-all}" /Volumes/ADATA/git/deploy.sh
|
|
</command>
|
|
</hudson.tasks.Shell>
|
|
</builders>
|
|
<publishers/>
|
|
<buildWrappers/>
|
|
</project>
|
|
JENKINS_XML
|
|
|
|
# Jenkins 설정 리로드 (실패해도 job 파일은 생성됨)
|
|
if command -v jenkins-cli >/dev/null 2>&1; then
|
|
jenkins-cli reload-configuration 2>/dev/null || true
|
|
fi
|
|
if curl -sf -o /dev/null "http://127.0.0.1:8090/login" 2>/dev/null; then
|
|
curl -sf -X POST "http://127.0.0.1:8090/reload" 2>/dev/null || true
|
|
fi
|
|
|
|
rm -f /tmp/goldenchart_deploy.lock 2>/dev/null || true
|
|
|
|
log "============================================================"
|
|
log "서버 Git/Jenkins 재구축 완료 (소스는 아직 비어 있음)"
|
|
log " GIT_DIR : $GIT_DIR"
|
|
log " WORK_TREE : $WORK_TREE (중첩 .git 없음)"
|
|
log " Jenkins : $JENKINS_JOB → file://$GIT_DIR"
|
|
log ""
|
|
log "다음: 로컬에서 실행"
|
|
log " cd <goldenChart> && git push origin main"
|
|
log "============================================================"
|