Skip to content

Commit 31bf99e

Browse files
dooohunff1451JeongWon-CHOGwak-Seungju
authored
release: 2026-03-24 프로덕션 배포 (#1214)
Co-authored-by: 이준영 <54898597+ff1451@users.noreply.github.com> Co-authored-by: 이준영 <ff1451@gmail.com> Co-authored-by: JeongWon-CHO <128157441+JeongWon-CHO@users.noreply.github.com> Co-authored-by: Gwak-Seungju <74342515+Gwak-Seungju@users.noreply.github.com>
1 parent 5cd22d1 commit 31bf99e

436 files changed

Lines changed: 14929 additions & 3328 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.coderabbit.yaml

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
language: ko
2+
early_access: true
3+
reviews:
4+
profile: chill
5+
request_changes_workflow: false
6+
high_level_summary: true
7+
high_level_summary_placeholder: '@coderabbitai summary'
8+
changed_files_summary: true
9+
sequence_diagrams: true
10+
poem: false
11+
review_status: true
12+
collapse_walkthrough: false
13+
path_filters:
14+
- '**'
15+
- '!.next/**'
16+
- '!yarn.lock'
17+
- '!.yarn/**'
18+
- '!.pnp.cjs'
19+
- '!.pnp.loader.mjs'
20+
- '!public/**'
21+
auto_review:
22+
enabled: true
23+
drafts: false
24+
base_branches:
25+
- develop
26+
- main
27+
tools:
28+
shellcheck:
29+
enabled: false
30+
ruff:
31+
enabled: false
32+
biome:
33+
enabled: false
34+
github-checks:
35+
enabled: true
36+
timeout_ms: 120000
37+
path_instructions:
38+
- path: src/pages/**
39+
instructions: |
40+
이 디렉토리는 Next.js Pages Router의 페이지 컴포넌트입니다.
41+
1. 페이지 컴포넌트에서 비즈니스 로직이 과도하게 포함되어 있지 않은지 확인해주세요.
42+
2. SEO 관련 메타 태그(Head 컴포넌트)가 적절히 설정되어 있는지 확인해주세요.
43+
3. getServerSideProps/getStaticProps 사용 시 에러 핸들링이 적절한지 확인해주세요.
44+
- path: src/components/**
45+
instructions: |
46+
1. 컴포넌트의 단일 책임 원칙(SRP)을 준수하고 있는지 확인해주세요.
47+
2. Props 타입이 명확하게 정의되어 있는지(interface 사용 권장) 확인해주세요.
48+
3. 불필요한 리렌더링을 유발하는 패턴(인라인 함수, 객체 리터럴 등)이 있는지 확인해주세요.
49+
4. 접근성(a11y) 관련 속성이 적절히 사용되고 있는지 확인해주세요.
50+
- path: src/api/**
51+
instructions: |
52+
1. API 호출 시 적절한 에러 핸들링이 되어 있는지 확인해주세요.
53+
2. 요청/응답 타입이 명확하게 정의되어 있는지 확인해주세요.
54+
3. API 엔드포인트 URL에 하드코딩된 값이 없는지 확인해주세요.
55+
4. 인증 토큰 등 민감 정보 처리가 안전한지 확인해주세요.
56+
- path: src/hooks/**
57+
instructions: |
58+
1. 커스텀 훅의 네이밍이 use 접두사를 따르고 있는지 확인해주세요.
59+
2. 의존성 배열이 정확하게 설정되어 있는지 확인해주세요.
60+
3. 메모리 누수 가능성이 있는 패턴(cleanup 미처리)이 없는지 확인해주세요.
61+
- path: src/utils/**
62+
instructions: |
63+
1. 유틸 함수가 순수 함수로 작성되어 있는지 확인해주세요.
64+
2. 엣지 케이스(null, undefined, 빈 배열 등) 처리가 되어 있는지 확인해주세요.
65+
- path: src/**
66+
instructions: |
67+
1. Next.js, React, TypeScript 팀 코드 컨벤션 및 공식 스타일 가이드(React/TS best practices)를 우선적으로 반영하여, 가독성·안정성(Null/에러 처리)·테스트/유지보수 용이성·브라우저/접근성 이슈 등을 검토해주세요.
68+
2. 최신 React/TypeScript 트렌드, 팀 스타일 통일성, 성능 최적화, 보안 취약점 등도 함께 고려해주세요.
69+
3. 각 리뷰 포인트별로 문제점과 대안, 장단점을 논리적으로 제시하고, 필요한 경우 예시 코드도 추가해주세요.
70+
4. 리뷰가 너무 많아서 피로감을 줄 수 있으니, 꼭 필요한 부분에 집중해주고, 나머지는 캡션으로 설명해주세요.
71+
5. 리뷰 남겨주는 부분은 해당 라인 범위의 코멘트에 작성해주세요.
72+
6. zustand 스토어 사용 시 selector 패턴을 권장해주세요.
73+
7. @tanstack/react-query 사용 시 queryKey 컨벤션과 에러/로딩 상태 처리를 확인해주세요.
74+
75+
chat:
76+
auto_reply: true
77+
78+
knowledge_base:
79+
web_search:
80+
enabled: true
81+
learnings:
82+
scope: local

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
@claude 리뷰 요청
2-
31
- Close #ISSUE_NUMBER
42

53
## What is this PR? 🔍

.github/workflows/AI_AUTO_REVIEW.yml

Lines changed: 0 additions & 36 deletions
This file was deleted.

.github/workflows/deploy.yml

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
name: Deploy
2+
3+
on:
4+
push:
5+
branches:
6+
- develop
7+
workflow_dispatch:
8+
9+
concurrency:
10+
group: ${{ github.workflow }}-${{ github.ref_name }}
11+
cancel-in-progress: ${{ github.ref_name != 'main' }}
12+
13+
jobs:
14+
lint:
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- name: Checkout
19+
uses: actions/checkout@v4
20+
21+
- name: Setup Node.js
22+
uses: actions/setup-node@v4
23+
with:
24+
node-version: '20.11.1'
25+
cache: 'yarn'
26+
27+
- name: Install dependencies
28+
run: yarn
29+
30+
- name: Run lint
31+
run: yarn lint
32+
33+
build-and-deploy:
34+
needs:
35+
- lint
36+
runs-on: ubuntu-latest
37+
timeout-minutes: 30
38+
environment: ${{ github.ref_name == 'main' && 'production' || 'stage' }}
39+
40+
steps:
41+
- name: Checkout
42+
uses: actions/checkout@v4
43+
44+
- name: Setup Node.js
45+
uses: actions/setup-node@v4
46+
with:
47+
node-version: '20.11.1'
48+
cache: 'yarn'
49+
50+
- name: Set deploy config
51+
run: |
52+
if [ "${{ github.ref_name }}" = "main" ]; then
53+
echo "ARCHIVE_NAME=dist-production.tar.gz" >> $GITHUB_ENV
54+
echo "SENTRY_PROJECT=koin-prod" >> $GITHUB_ENV
55+
echo "DEPLOY_SCRIPT=/usr/local/koin/production/deploy/deploy.sh" >> $GITHUB_ENV
56+
else
57+
echo "ARCHIVE_NAME=dist.tar.gz" >> $GITHUB_ENV
58+
echo "SENTRY_PROJECT=koin-stage" >> $GITHUB_ENV
59+
echo "DEPLOY_SCRIPT=/usr/local/koin/stage/deploy/deploy.sh" >> $GITHUB_ENV
60+
fi
61+
62+
- name: Create .env
63+
env:
64+
NEXT_PUBLIC_API_PATH: ${{ secrets.NEXT_PUBLIC_API_PATH }}
65+
NEXT_PUBLIC_NAVER_MAPS_CLIENT_ID: ${{ secrets.NEXT_PUBLIC_NAVER_MAPS_CLIENT_ID }}
66+
NEXT_PUBLIC_GOOGLE_ANALYTICS_ID: ${{ secrets.NEXT_PUBLIC_GOOGLE_ANALYTICS_ID }}
67+
NEXT_PUBLIC_GTM_ID: ${{ secrets.NEXT_PUBLIC_GTM_ID }}
68+
NEXT_PUBLIC_SENTRY_DSN: ${{ secrets.NEXT_PUBLIC_SENTRY_DSN }}
69+
NEXT_PUBLIC_SENTRY_ENVIRONMENT: ${{ vars.NEXT_PUBLIC_SENTRY_ENVIRONMENT }}
70+
run: |
71+
echo "NEXT_PUBLIC_API_PATH=$NEXT_PUBLIC_API_PATH" >> .env
72+
echo "NEXT_PUBLIC_NAVER_MAPS_CLIENT_ID=$NEXT_PUBLIC_NAVER_MAPS_CLIENT_ID" >> .env
73+
echo "NEXT_PUBLIC_GOOGLE_ANALYTICS_ID=$NEXT_PUBLIC_GOOGLE_ANALYTICS_ID" >> .env
74+
echo "NEXT_PUBLIC_GTM_ID=$NEXT_PUBLIC_GTM_ID" >> .env
75+
echo "NEXT_PUBLIC_SENTRY_DSN=$NEXT_PUBLIC_SENTRY_DSN" >> .env
76+
echo "NEXT_PUBLIC_SENTRY_ENVIRONMENT=$NEXT_PUBLIC_SENTRY_ENVIRONMENT" >> .env
77+
78+
- name: Install dependencies
79+
run: yarn
80+
81+
- name: Build
82+
run: yarn build
83+
env:
84+
NODE_OPTIONS: --max-old-space-size=6144
85+
SENTRY_ORG: bcsd
86+
SENTRY_PROJECT: ${{ env.SENTRY_PROJECT }}
87+
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
88+
NEXT_PUBLIC_SENTRY_RELEASE: ${{ github.sha }}
89+
90+
- name: Create deploy package
91+
run: |
92+
mkdir -p deploy-pkg
93+
cp -r .next deploy-pkg/
94+
cp -r public deploy-pkg/ 2>/dev/null || true
95+
cp package.json deploy-pkg/
96+
cp yarn.lock deploy-pkg/
97+
cp .env deploy-pkg/
98+
cp next.config.mjs deploy-pkg/
99+
cp -r .yarn deploy-pkg/ 2>/dev/null || true
100+
cp .pnp.* deploy-pkg/ 2>/dev/null || true
101+
cp .yarnrc.yml deploy-pkg/ 2>/dev/null || true
102+
tar -czf $ARCHIVE_NAME -C deploy-pkg .
103+
rm -rf deploy-pkg
104+
105+
- name: Setup SSH agent
106+
uses: webfactory/ssh-agent@v0.9.0
107+
with:
108+
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
109+
110+
- name: Add SSH known hosts
111+
run: |
112+
mkdir -p ~/.ssh
113+
ssh-keyscan -p 22222 ${{ secrets.DEPLOY_HOST }} >> ~/.ssh/known_hosts
114+
115+
- name: Deploy
116+
run: |
117+
scp -o ConnectTimeout=30 -P 22222 $ARCHIVE_NAME ${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}:/home/ubuntu/koin/web/
118+
ssh -o ConnectTimeout=30 -p 22222 ${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }} "bash -lc '$DEPLOY_SCRIPT'"
119+
120+
notify:
121+
needs: [build-and-deploy]
122+
if: always()
123+
runs-on: ubuntu-latest
124+
steps:
125+
- name: Checkout
126+
uses: actions/checkout@v4
127+
128+
- name: Resolve actor name
129+
id: resolve_actor
130+
uses: actions/github-script@v7
131+
with:
132+
script: |
133+
const fs = require('fs');
134+
const developers = JSON.parse(fs.readFileSync(`${{ github.workspace }}/.github/workflows/reviewer.json`));
135+
const matched = developers.reviewers.find(p => p.githubName === '${{ github.actor }}');
136+
core.setOutput('actorName', JSON.stringify(matched?.name ?? '${{ github.actor }}'));
137+
138+
- name: Send Slack Notification
139+
run: |
140+
STATUS="${{ needs.build-and-deploy.result }}"
141+
ENVIRONMENT=$([[ "${{ github.ref_name }}" == "main" ]] && echo "Production" || echo "Stage")
142+
COMMIT_MSG=$(echo "${{ github.event.head_commit.message }}" | head -1)
143+
RUN_URL="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
144+
ACTOR=${{ steps.resolve_actor.outputs.actorName }}
145+
146+
BODY=$(jq -n \
147+
--arg status "$STATUS" \
148+
--arg environment "$ENVIRONMENT" \
149+
--arg repository "${{ github.repository }}" \
150+
--arg branch "${{ github.ref_name }}" \
151+
--arg actor "$ACTOR" \
152+
--arg commitMessage "$COMMIT_MSG" \
153+
--arg runUrl "$RUN_URL" \
154+
'{status: $status, environment: $environment, repository: $repository, branch: $branch, actor: $actor, commitMessage: $commitMessage, runUrl: $runUrl}')
155+
156+
curl -X POST https://api-slack.internal.bcsdlab.com/api/deploy/frontend \
157+
-H 'Content-Type: application/json' \
158+
-d "$BODY"

.github/workflows/reviewer.json

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,8 @@
1717
"githubName": "ff1451"
1818
},
1919
{
20-
"name": "곽승주",
21-
"githubName": "Gwak-Seungju"
22-
},
23-
{
24-
"name": "서예진",
25-
"githubName": "Yejin0070"
20+
"name": "박성주",
21+
"githubName": "ParkSungju01"
2622
}
2723
]
2824
}

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,6 @@ tsconfig.tsbuildinfo
4141
.idea/*
4242
.next
4343

44-
tsconfig.tsbuildinfo
44+
tsconfig.tsbuildinfo
45+
# Sentry Config File
46+
.env.sentry-build-plugin

0 commit comments

Comments
 (0)