forked from UMC-DearE/BackEnd
-
Notifications
You must be signed in to change notification settings - Fork 0
123 lines (103 loc) · 4.11 KB
/
Copy pathcd.yml
File metadata and controls
123 lines (103 loc) · 4.11 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
name: CD - build/push image & deploy to EC2 on main push
on:
push:
branches: ["main"]
# workflow_dispatch: -> main 머지 전 테스팅 - 실 배포 시 각주 처리할 것
env:
IMAGE_NAME: deare-backend
permissions:
id-token: write
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up JDK 17 (Temurin) + Gradle cache
uses: actions/setup-java@v4
with:
distribution: "temurin"
java-version: "17"
cache: "gradle"
- name: Grant execute permission for gradlew
run: chmod +x gradlew
# 1) JAR 빌드
- name: Build JAR (skip tests)
run: ./gradlew clean bootJar -x test
- name: Prepare app.jar for Docker build context
run: |
rm -f app.jar
cp build/libs/*.jar app.jar
# 2) Docker Hub 로그인
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
# 3) 이미지 build & push (latest + commit sha)
- name: Build and push Docker image
uses: docker/build-push-action@v6
with:
context: .
file: Dockerfile
push: true
tags: |
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}:latest
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
# 4) OIDC로 AWS 임시 자격증명 획득
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_DEPLOY_ROLE_ARN }}
aws-region: ap-northeast-2
# 5) SSM으로 EC2에 배포 (pull + up -d, fallback to down)
- name: Deploy on EC2 via SSM
run: |
COMMAND_ID=$(aws ssm send-command \
--instance-ids "${{ secrets.EC2_INSTANCE_ID }}" \
--document-name "AWS-RunShellScript" \
--timeout-seconds 600 \
--parameters 'commands=[
"set -e",
"cd /home/ubuntu/deare",
"ENV_FILE=/home/ubuntu/deare/.env.prod",
"COMPOSE_FILE=/home/ubuntu/deare/docker-compose-dev.yml",
"docker-compose --env-file $ENV_FILE -f $COMPOSE_FILE pull app",
"if docker-compose --env-file $ENV_FILE -f $COMPOSE_FILE up -d; then echo compose up succeeded without down; else docker-compose --env-file $ENV_FILE -f $COMPOSE_FILE down && docker-compose --env-file $ENV_FILE -f $COMPOSE_FILE up -d; fi",
"docker-compose --env-file $ENV_FILE -f $COMPOSE_FILE ps",
"docker image prune -f"
]' \
--query "Command.CommandId" \
--output text)
# waiter 대신 직접 폴링 (10초 간격, 최대 60회 = 600초)
for i in $(seq 1 60); do
STATUS=$(aws ssm get-command-invocation \
--command-id "$COMMAND_ID" \
--instance-id "${{ secrets.EC2_INSTANCE_ID }}" \
--query "Status" \
--output text 2>/dev/null || echo "Pending")
echo "[$i/60] Status: $STATUS"
if [[ "$STATUS" == "Success" || "$STATUS" == "Failed" || "$STATUS" == "Cancelled" || "$STATUS" == "TimedOut" ]]; then
break
fi
sleep 10
done
# 성공/실패 무관하게 stdout, stderr 항상 출력
echo "=== stdout ==="
aws ssm get-command-invocation \
--command-id "$COMMAND_ID" \
--instance-id "${{ secrets.EC2_INSTANCE_ID }}" \
--query "StandardOutputContent" \
--output text
echo "=== stderr ==="
aws ssm get-command-invocation \
--command-id "$COMMAND_ID" \
--instance-id "${{ secrets.EC2_INSTANCE_ID }}" \
--query "StandardErrorContent" \
--output text
# 상태 기반 종료 코드 결정
if [[ "$STATUS" != "Success" ]]; then
echo "Deploy failed with status: $STATUS"
exit 1
fi