-
Notifications
You must be signed in to change notification settings - Fork 0
237 lines (199 loc) · 7.22 KB
/
ci.yml
File metadata and controls
237 lines (199 loc) · 7.22 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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# CI: PR에서 품질 체크(린트/타입/빌드/스토리북/보안)
name: CI
# 트리거: develop/main 대상으로 열리는 PR에서 실행
on:
pull_request:
branches:
- develop
- main
- sprint2
jobs:
# ESLint로 코드 스타일/버그 패턴 검사(경고를 실패로 취급)
# 실패 시: yarn lint:fix
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "yarn"
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Lint
run: yarn lint
# TypeScript 컴파일러로 타입 체크(빌드 없이 타입만 검증)
typecheck:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "yarn"
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Type Check
run: yarn typecheck
# Prettier로 코드 포맷 검사(형식 불일치 시 실패)
# 실패 시: yarn prettier:fix
prettier:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "yarn"
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Prettier Check
run: yarn prettier
# Next.js 프로덕션 빌드(정적 분석 및 페이지 최적화 포함)
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "yarn"
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Build
run: yarn build
# Storybook 정적 빌드(UI 카탈로그가 깨지지 않는지 확인)
storybook:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "yarn"
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Build Storybook
run: yarn build-storybook
# Playwright E2E:
# - non-@auth 테스트: CI 내 로컬 서버(localhost:3000) 대상 항상 실행 (스테이징 의존 없음)
# - @auth 테스트: 스테이징 접속 가능 시에만 실행, 불가 시 경고 후 스킵
# 갱신 절차: yarn e2e:save-auth → GitHub Secret E2E_AUTH_JSON 업데이트
e2e:
runs-on: ubuntu-latest
env:
E2E_AUTH_JSON: ${{ secrets.E2E_AUTH_JSON }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "yarn"
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Install Playwright browsers
run: npx playwright install --with-deps chromium
- name: Write auth session
if: env.E2E_AUTH_JSON != ''
run: |
mkdir -p e2e/fixtures
printf '%s' "$E2E_AUTH_JSON" > e2e/fixtures/auth.json
node -e "JSON.parse(require('fs').readFileSync('e2e/fixtures/auth.json','utf8'))" \
|| { echo "::error::E2E_AUTH_JSON is not valid JSON"; exit 1; }
- name: Check auth session expiry
if: env.E2E_AUTH_JSON != ''
run: |
node -e "
const fs = require('fs');
const a = JSON.parse(fs.readFileSync('e2e/fixtures/auth.json','utf8'));
const refreshTokens = (a.cookies || []).filter(
c => c.name === 'refresh_token' && c.domain.includes('zeroone.it.kr') && c.expires && c.expires > 0
);
if (refreshTokens.length === 0) {
console.log('::warning::No refresh_token cookie found for zeroone.it.kr — falling back to non-auth suite.');
fs.appendFileSync(process.env.GITHUB_ENV, 'AUTH_EXPIRED=true\n');
process.exit(0);
}
const minExp = Math.min(...refreshTokens.map(c => c.expires));
const now = Date.now();
if (minExp * 1000 < now) {
console.log('::warning::refresh_token is expired — falling back to non-auth suite. Re-run yarn e2e:save-auth and update E2E_AUTH_JSON secret.');
fs.appendFileSync(process.env.GITHUB_ENV, 'AUTH_EXPIRED=true\n');
process.exit(0);
}
const sevenDays = 7 * 86400 * 1000;
if (minExp * 1000 < now + sevenDays) {
console.log('::warning::refresh_token expires within 7 days. Re-run yarn e2e:save-auth and update E2E_AUTH_JSON secret.');
}
"
- name: Warn when auth secret missing
if: env.E2E_AUTH_JSON == ''
run: echo "::warning::E2E_AUTH_JSON not set — skipping @auth tests"
- name: Build Next.js app
run: yarn build
env:
NEXT_PUBLIC_API_BASE_URL: https://test-api.zeroone.it.kr
- name: Start local server
run: |
NEXT_PUBLIC_API_BASE_URL=https://test-api.zeroone.it.kr yarn start &
for i in $(seq 1 30); do
if curl -sf --max-time 5 http://localhost:3000/ > /dev/null 2>&1; then
echo "Local server ready"
break
fi
echo "Waiting for server... ($i/30)"
sleep 2
done
- name: Run E2E tests (non-auth, local server)
run: yarn e2e --grep-invert @auth
env:
E2E_BASE_URL: http://localhost:3000
- name: Check staging connectivity
run: |
STATUS=$(curl -s --max-time 10 -o /dev/null -w "%{http_code}" https://test.zeroone.it.kr/ 2>/dev/null || true)
if [[ "$STATUS" =~ ^[2-4][0-9][0-9]$ ]]; then
echo "Staging reachable (HTTP $STATUS)"
else
echo "::warning::Staging https://test.zeroone.it.kr unreachable — skipping @auth tests"
echo "STAGING_DOWN=true" >> "$GITHUB_ENV"
fi
- name: Run E2E tests (auth suite, staging)
if: env.E2E_AUTH_JSON != '' && env.AUTH_EXPIRED != 'true' && env.STAGING_DOWN != 'true'
run: yarn e2e --grep @auth
env:
E2E_BASE_URL: https://test.zeroone.it.kr
- name: Upload Playwright report
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: playwright-report
path: playwright-report/
retention-days: 7
# 보안 감사: 고위험 이상의 취약점 리포트(현재는 비차단)
# 실패로 처리하려면 '|| true'를 제거하세요.
security:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "yarn"
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Security Audit
run: yarn audit --level high || true