Skip to content

Commit d98cd21

Browse files
committed
crone: 깃허브 파이프라인 구축
1 parent af190d8 commit d98cd21

File tree

3 files changed

+392
-0
lines changed

3 files changed

+392
-0
lines changed

.github/workflows/dev-ci.yml

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
name: Development CI
2+
3+
on:
4+
pull_request:
5+
branches: [develop]
6+
paths-ignore:
7+
- '**.md'
8+
- 'docs/**'
9+
- 'scripts/**'
10+
11+
env:
12+
DOTNET_VERSION: '8.0.x'
13+
14+
jobs:
15+
build-and-test:
16+
name: Build and Test
17+
runs-on: ubuntu-latest
18+
19+
steps:
20+
- name: Checkout code
21+
uses: actions/checkout@v4
22+
23+
- name: Setup .NET
24+
uses: actions/setup-dotnet@v4
25+
with:
26+
dotnet-version: ${{ env.DOTNET_VERSION }}
27+
28+
- name: Cache NuGet packages
29+
uses: actions/cache@v4
30+
with:
31+
path: ~/.nuget/packages
32+
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}
33+
restore-keys: |
34+
${{ runner.os }}-nuget-
35+
36+
- name: Restore dependencies
37+
run: dotnet restore ProjectVG.sln
38+
39+
- name: Build solution
40+
run: dotnet build ProjectVG.sln --no-restore --configuration Release
41+
42+
- name: Run tests
43+
run: dotnet test ProjectVG.Tests/ProjectVG.Tests.csproj --no-build --configuration Release --verbosity normal --collect:"XPlat Code Coverage" --logger trx --results-directory coverage
44+
45+
- name: Code Coverage Report
46+
uses: irongut/CodeCoverageSummary@v1.3.0
47+
with:
48+
filename: coverage/**/coverage.cobertura.xml
49+
badge: true
50+
fail_below_min: false
51+
format: markdown
52+
hide_branch_rate: false
53+
hide_complexity: true
54+
indicators: true
55+
output: both
56+
thresholds: '60 80'
57+
58+
- name: Add Coverage PR Comment
59+
uses: marocchino/sticky-pull-request-comment@v2
60+
if: github.event_name == 'pull_request'
61+
with:
62+
recreate: true
63+
path: code-coverage-results.md
64+
65+
- name: Publish Test Results
66+
uses: dorny/test-reporter@v1
67+
if: success() || failure()
68+
with:
69+
name: Test Results
70+
path: coverage/*.trx
71+
reporter: dotnet-trx
72+
73+
- name: Build Status Check
74+
if: failure()
75+
run: |
76+
echo "❌ Build or tests failed"
77+
exit 1

.github/workflows/release-cicd.yml

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
name: Release CI/CD
2+
3+
on:
4+
pull_request:
5+
branches: [release]
6+
paths-ignore:
7+
- '**.md'
8+
- 'docs/**'
9+
- 'scripts/**'
10+
11+
env:
12+
DOTNET_VERSION: '8.0.x'
13+
DOCKER_IMAGE_NAME: projectvgapi
14+
15+
jobs:
16+
build-and-test:
17+
name: Build and Test
18+
runs-on: ubuntu-latest
19+
20+
steps:
21+
- name: Checkout code
22+
uses: actions/checkout@v4
23+
24+
- name: Setup .NET
25+
uses: actions/setup-dotnet@v4
26+
with:
27+
dotnet-version: ${{ env.DOTNET_VERSION }}
28+
29+
- name: Cache NuGet packages
30+
uses: actions/cache@v4
31+
with:
32+
path: ~/.nuget/packages
33+
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}
34+
restore-keys: |
35+
${{ runner.os }}-nuget-
36+
37+
- name: Restore dependencies
38+
run: dotnet restore ProjectVG.sln
39+
40+
- name: Build solution
41+
run: dotnet build ProjectVG.sln --no-restore --configuration Release
42+
43+
- name: Run tests
44+
run: dotnet test ProjectVG.Tests/ProjectVG.Tests.csproj --no-build --configuration Release --verbosity normal --collect:"XPlat Code Coverage" --logger trx --results-directory coverage
45+
46+
- name: Code Coverage Report
47+
uses: irongut/CodeCoverageSummary@v1.3.0
48+
with:
49+
filename: coverage/**/coverage.cobertura.xml
50+
badge: true
51+
fail_below_min: true
52+
format: markdown
53+
hide_branch_rate: false
54+
hide_complexity: true
55+
indicators: true
56+
output: both
57+
thresholds: '70 85'
58+
59+
- name: Publish Test Results
60+
uses: dorny/test-reporter@v1
61+
if: success() || failure()
62+
with:
63+
name: Release Test Results
64+
path: coverage/*.trx
65+
reporter: dotnet-trx
66+
67+
docker-build-push:
68+
name: Docker Build and Push
69+
runs-on: ubuntu-latest
70+
needs: build-and-test
71+
if: success()
72+
73+
steps:
74+
- name: Checkout code
75+
uses: actions/checkout@v4
76+
77+
- name: Set up Docker Buildx
78+
uses: docker/setup-buildx-action@v3
79+
80+
- name: Login to Docker Hub
81+
uses: docker/login-action@v3
82+
with:
83+
username: ${{ secrets.DOCKER_USERNAME }}
84+
password: ${{ secrets.DOCKER_PASSWORD }}
85+
86+
- name: Extract metadata
87+
id: meta
88+
uses: docker/metadata-action@v5
89+
with:
90+
images: ${{ secrets.DOCKER_USERNAME }}/${{ env.DOCKER_IMAGE_NAME }}
91+
tags: |
92+
type=ref,event=pr,prefix=pr-
93+
type=raw,value=latest,enable={{is_default_branch}}
94+
type=sha,prefix={{branch}}-
95+
96+
- name: Build and push Docker image
97+
uses: docker/build-push-action@v5
98+
with:
99+
context: .
100+
file: ./ProjectVG.Api/Dockerfile
101+
push: true
102+
tags: ${{ steps.meta.outputs.tags }}
103+
labels: ${{ steps.meta.outputs.labels }}
104+
cache-from: type=gha
105+
cache-to: type=gha,mode=max
106+
platforms: linux/amd64
107+
target: production
108+
109+
deploy-aws:
110+
name: Deploy to AWS
111+
runs-on: ubuntu-latest
112+
needs: [build-and-test, docker-build-push]
113+
if: success()
114+
115+
steps:
116+
- name: Checkout code
117+
uses: actions/checkout@v4
118+
119+
- name: Configure AWS credentials
120+
uses: aws-actions/configure-aws-credentials@v4
121+
with:
122+
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
123+
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
124+
aws-region: ${{ secrets.AWS_REGION }}
125+
126+
- name: Extract Docker image tag
127+
id: image-tag
128+
run: |
129+
echo "tag=${{ secrets.DOCKER_USERNAME }}/${{ env.DOCKER_IMAGE_NAME }}:pr-${{ github.event.number }}" >> $GITHUB_OUTPUT
130+
131+
# ECS 배포 예시 (필요시 수정)
132+
- name: Deploy to ECS
133+
run: |
134+
# ECS 서비스 업데이트 (실제 클러스터명, 서비스명으로 수정 필요)
135+
aws ecs update-service \
136+
--cluster projectvg-cluster \
137+
--service projectvg-api-service \
138+
--task-definition projectvg-api-task \
139+
--force-new-deployment
140+
141+
echo "✅ Deployment initiated to AWS ECS"
142+
echo "🐳 Docker Image: ${{ steps.image-tag.outputs.tag }}"
143+
144+
# 또는 EC2/EKS 배포 예시
145+
# - name: Deploy to EC2/EKS
146+
# run: |
147+
# # 여기에 실제 배포 스크립트 작성
148+
# echo "Deploying to EC2/EKS..."
149+
150+
- name: Deployment Status
151+
run: |
152+
echo "🚀 Release deployment completed successfully!"
153+
echo "📦 Image: ${{ steps.image-tag.outputs.tag }}"
154+
echo "🌍 Region: ${{ secrets.AWS_REGION }}"

docs/github-secrets-setup.md

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
# GitHub Secrets 설정 가이드
2+
3+
이 문서는 ProjectVG CI/CD 파이프라인을 위한 GitHub Secrets 설정 방법을 안내합니다.
4+
5+
## GitHub Secrets 설정 방법
6+
7+
1. GitHub 저장소로 이동
8+
2. `Settings` 탭 클릭
9+
3. 좌측 메뉴에서 `Secrets and variables``Actions` 선택
10+
4. `New repository secret` 버튼 클릭
11+
12+
## 필수 Secrets 목록
13+
14+
### 🐳 Docker Hub 관련
15+
```
16+
DOCKER_USERNAME
17+
- 설명: Docker Hub 사용자명
18+
- 예시: your-dockerhub-username
19+
20+
DOCKER_PASSWORD
21+
- 설명: Docker Hub 액세스 토큰 또는 비밀번호
22+
- 참고: Docker Hub → Account Settings → Security → New Access Token
23+
```
24+
25+
### ☁️ AWS 배포 관련
26+
```
27+
AWS_ACCESS_KEY_ID
28+
- 설명: AWS IAM 사용자의 액세스 키 ID
29+
- 예시: AKIA1234567890EXAMPLE
30+
31+
AWS_SECRET_ACCESS_KEY
32+
- 설명: AWS IAM 사용자의 시크릿 액세스 키
33+
- 예시: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
34+
35+
AWS_REGION
36+
- 설명: AWS 리전
37+
- 예시: ap-northeast-2
38+
```
39+
40+
### 🔐 애플리케이션 환경 변수 (선택사항)
41+
운영 환경에서 다른 값이 필요한 경우에만 설정:
42+
43+
```
44+
JWT_SECRET_KEY
45+
- 설명: JWT 토큰 서명용 시크릿 키 (최소 32자)
46+
- 예시: your-super-secret-jwt-key-here-minimum-32-characters
47+
48+
GOOGLE_OAUTH_CLIENT_ID
49+
- 설명: Google OAuth2 클라이언트 ID
50+
- 예시: 1234567890-abcdefghijklmnopqrstuvwxyz123456.apps.googleusercontent.com
51+
52+
GOOGLE_OAUTH_CLIENT_SECRET
53+
- 설명: Google OAuth2 클라이언트 시크릿
54+
- 예시: GOCSPX-abcdefghijklmnopqrstuvwxyz123456
55+
56+
DB_CONNECTION_STRING
57+
- 설명: 운영 데이터베이스 연결 문자열
58+
- 예시: Server=prod-db.amazonaws.com,1433;Database=ProjectVG;User Id=admin;Password=SecurePassword123!;TrustServerCertificate=true;
59+
60+
REDIS_CONNECTION_STRING
61+
- 설명: Redis 연결 문자열
62+
- 예시: prod-redis.amazonaws.com:6379
63+
64+
LLM_BASE_URL
65+
- 설명: LLM 서비스 기본 URL
66+
- 예시: https://api.llm-service.com
67+
68+
MEMORY_BASE_URL
69+
- 설명: Memory 서비스 기본 URL
70+
- 예시: https://api.memory-service.com
71+
72+
TTS_API_KEY
73+
- 설명: TTS 서비스 API 키
74+
- 예시: sk-1234567890abcdefghijklmnopqrstuvwxyz
75+
```
76+
77+
## AWS IAM 권한 설정
78+
79+
AWS 배포를 위한 IAM 사용자에게 다음 권한이 필요합니다:
80+
81+
### ECS 배포 시 필요 권한
82+
```json
83+
{
84+
"Version": "2012-10-17",
85+
"Statement": [
86+
{
87+
"Effect": "Allow",
88+
"Action": [
89+
"ecs:UpdateService",
90+
"ecs:DescribeServices",
91+
"ecs:DescribeTasks",
92+
"ecs:ListTasks",
93+
"ecs:RegisterTaskDefinition",
94+
"ecs:DescribeTaskDefinition"
95+
],
96+
"Resource": "*"
97+
},
98+
{
99+
"Effect": "Allow",
100+
"Action": [
101+
"iam:PassRole"
102+
],
103+
"Resource": "arn:aws:iam::*:role/ecsTaskExecutionRole"
104+
}
105+
]
106+
}
107+
```
108+
109+
### EC2/EKS 배포 시 필요 권한 (해당하는 경우)
110+
```json
111+
{
112+
"Version": "2012-10-17",
113+
"Statement": [
114+
{
115+
"Effect": "Allow",
116+
"Action": [
117+
"ec2:DescribeInstances",
118+
"eks:DescribeCluster",
119+
"eks:UpdateClusterConfig"
120+
],
121+
"Resource": "*"
122+
}
123+
]
124+
}
125+
```
126+
127+
## 보안 주의사항
128+
129+
1. **최소 권한 원칙**: 필요한 최소한의 권한만 부여
130+
2. **액세스 키 로테이션**: 정기적으로 AWS 액세스 키 교체
131+
3. **Docker 토큰**: Docker Hub 비밀번호 대신 액세스 토큰 사용 권장
132+
4. **환경별 분리**: 개발/스테이징/운영 환경별로 다른 값 사용
133+
134+
## 설정 확인 방법
135+
136+
1. Pull Request를 `develop` 브랜치로 생성하여 CI 동작 확인
137+
2. Pull Request를 `release` 브랜치로 생성하여 CI/CD 전체 과정 확인
138+
3. GitHub Actions 탭에서 워크플로우 실행 결과 확인
139+
140+
## 문제 해결
141+
142+
### 자주 발생하는 오류
143+
144+
1. **Docker login 실패**
145+
- `DOCKER_USERNAME`, `DOCKER_PASSWORD` 값 확인
146+
- Docker Hub 액세스 토큰 권한 확인
147+
148+
2. **AWS 배포 실패**
149+
- AWS 자격 증명 확인
150+
- IAM 권한 확인
151+
- 리소스명(클러스터, 서비스) 확인
152+
153+
3. **테스트 실패**
154+
- 테스트 코드 자체 문제일 수 있음
155+
- 로컬에서 `dotnet test` 실행하여 확인
156+
157+
## 추가 정보
158+
159+
- [GitHub Secrets 공식 문서](https://docs.github.com/en/actions/security-guides/encrypted-secrets)
160+
- [Docker Hub 액세스 토큰 생성](https://docs.docker.com/docker-hub/access-tokens/)
161+
- [AWS IAM 권한 설정](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html)

0 commit comments

Comments
 (0)