-
Notifications
You must be signed in to change notification settings - Fork 1
131 lines (112 loc) · 4.27 KB
/
deploy.yml
File metadata and controls
131 lines (112 loc) · 4.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
name: CD to EC2 (RightMark)
on:
push:
branches: [ develop ]
jobs:
build-and-deploy:
# PR이 'closed' 되어도 merge가 아니면 스킵
if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.merged == true)
runs-on: ubuntu-latest
env:
TARGET_DIR: ${{ secrets.TARGET_DIR }}
SERVICE_NAME: ${{ secrets.SERVICE_NAME }}
EC2_HOST: ${{ secrets.EC2_HOST }}
EC2_USER: ${{ secrets.EC2_USER }}
EC2_PORT: ${{ secrets.EC2_PORT }}
HEALTH_URL: ${{ secrets.HEALTH_URL }}
REL_NAME: rightmark-${{ github.sha }}
JAR_PATH: build/libs/*.jar
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: "17"
- name: Cache Gradle
uses: actions/cache@v4
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*','**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Build with Gradle
run: |
chmod +x ./gradlew
./gradlew clean build -x test
ls -al build/libs
- name: Prepare SSH key
run: |
mkdir -p ~/.ssh
echo "${{ secrets.EC2_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan -H "${{ secrets.EC2_HOST }}" >> ~/.ssh/known_hosts
- name: Create release dir on EC2
env:
PORT: ${{ env.EC2_PORT }}
run: |
ssh -p "${PORT:-22}" "${EC2_USER}@${EC2_HOST}" \
"mkdir -p '${TARGET_DIR}/releases/${REL_NAME}' '${TARGET_DIR}/logs'"
- name: Upload JAR to EC2
env:
PORT: ${{ env.EC2_PORT }}
run: |
# 가장 일반적인 부트 JAR 한 개만 선택
JAR_FILE=$(ls build/libs/*-SNAPSHOT.jar 2>/dev/null || ls build/libs/*.jar | head -n1)
echo "Uploading: $JAR_FILE"
scp -P "${PORT:-22}" "$JAR_FILE" "${EC2_USER}@${EC2_HOST}":"${TARGET_DIR}/releases/${REL_NAME}/app.jar"
- name: Switch symlink (atomic) & restart service
env:
PORT: ${{ env.EC2_PORT }}
run: |
ssh -p "${PORT:-22}" "${EC2_USER}@${EC2_HOST}" /bin/bash <<EOF
set -euo pipefail
TARGET_DIR="${TARGET_DIR}"
REL_NAME="${REL_NAME}"
SERVICE="${SERVICE_NAME}"
# 이전 릴리스 경로 (symlink였을 때만 기록)
if [ -L "\$TARGET_DIR/current" ]; then
readlink -f "\$TARGET_DIR/current" > "\$TARGET_DIR/previous_release.path" || true
fi
# current가 디렉터리면 제거(첫 배포에서 흔함)
if [ -d "\$TARGET_DIR/current" ] && [ ! -L "\$TARGET_DIR/current" ]; then
rm -rf "\$TARGET_DIR/current"
fi
# 새 릴리스로 current 링크 생성/갱신
ln -sfn "\$TARGET_DIR/releases/\$REL_NAME" "\$TARGET_DIR/current"
# 서비스 재시작
sudo systemctl restart "\$SERVICE"
sudo systemctl is-active "\$SERVICE"
EOF
- name: Health check over SSH (optional)
if: env.HEALTH_URL != ''
env:
PORT: ${{ env.EC2_PORT }}
run: |
# EC2 내부에서 localhost로 헬스체크
ssh -p "${PORT:-22}" "${EC2_USER}@${EC2_HOST}" "for i in {1..10}; do curl -fsS '${HEALTH_URL}' && exit 0; sleep 3; done; exit 1"
- name: Rollback on failure
if: failure()
env:
PORT: ${{ env.EC2_PORT }}
run: |
ssh -p "${PORT:-22}" "${EC2_USER}@${EC2_HOST}" /bin/bash <<EOF
set -euo pipefail
TARGET_DIR="${TARGET_DIR}"
SERVICE="${SERVICE_NAME}"
if [ -f "\$TARGET_DIR/previous_release.path" ]; then
PREV=\$(cat "\$TARGET_DIR/previous_release.path")
echo "Rolling back to: \$PREV"
ln -sfn "\$PREV" "\$TARGET_DIR/current"
sudo systemctl restart "\$SERVICE"
sudo systemctl is-active "\$SERVICE" || true
else
echo "No previous release info; cannot rollback."
exit 1
fi
EOF
- name: Done
run: echo "✅ Deployment finished"