From 9381de4cd7a7abcdfa447852a3e9e7040641b109 Mon Sep 17 00:00:00 2001 From: Andy Hong Date: Sun, 18 Jan 2026 18:53:29 +0900 Subject: [PATCH 1/2] =?UTF-8?q?chore:=20Firebase=20=EB=B0=B0=ED=8F=AC=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20=EA=B0=9C=EC=84=A0=20(#53)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - GitHub Actions: Node 버전 지정, npm 캐싱, 환경변수 주입 - firebase.json: 정적 에셋 캐싱, 보안 헤더 추가 - 환경변수 템플릿 업데이트 Co-Authored-By: Claude Haiku 4.5 --- .env.development | 3 + .env.example | 18 +++++- .env.production | 3 + .github/workflows/firebase-hosting-merge.yml | 25 +++++++-- .../firebase-hosting-pull-request.yml | 26 +++++++-- firebase.json | 56 +++++++++++++++++-- 6 files changed, 114 insertions(+), 17 deletions(-) create mode 100644 .env.development create mode 100644 .env.production diff --git a/.env.development b/.env.development new file mode 100644 index 00000000..68407dbb --- /dev/null +++ b/.env.development @@ -0,0 +1,3 @@ +# 개발 서버 (배포된 개발 환경) +VITE_API_URL=https://dev-api.ttorang.com +VITE_APP_TITLE=또랑 (개발) diff --git a/.env.example b/.env.example index 22c43d51..9d17a9c6 100644 --- a/.env.example +++ b/.env.example @@ -1,6 +1,20 @@ +# =========================================== +# 환경변수 템플릿 +# 이 파일을 복사해서 .env.local 파일을 만드세요 +# =========================================== -# API +# API 서버 URL +# - 개발: https://dev-api.ttorang.com +# - 프로덕션: https://api.ttorang.com VITE_API_URL= -# App +# 앱 타이틀 VITE_APP_TITLE=또랑 + +# =========================================== +# 시크릿 키 (반드시 .env.local에만 설정하세요) +# =========================================== + +# 카카오 JavaScript 키 (공유 기능용) +# https://developers.kakao.com 에서 발급 +VITE_KAKAO_JS_KEY= diff --git a/.env.production b/.env.production new file mode 100644 index 00000000..488bfc41 --- /dev/null +++ b/.env.production @@ -0,0 +1,3 @@ +# 프로덕션 서버 +VITE_API_URL=https://api.ttorang.com +VITE_APP_TITLE=또랑 diff --git a/.github/workflows/firebase-hosting-merge.yml b/.github/workflows/firebase-hosting-merge.yml index a7b71f91..0f88e3cb 100644 --- a/.github/workflows/firebase-hosting-merge.yml +++ b/.github/workflows/firebase-hosting-merge.yml @@ -1,18 +1,33 @@ -# This file was auto-generated by the Firebase CLI -# https://github.com/firebase/firebase-tools - name: Deploy to Firebase Hosting on merge + on: push: branches: - main + jobs: build_and_deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - run: npm ci && npm run build - - uses: FirebaseExtended/action-hosting-deploy@v0 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: Build + run: npm run build + env: + VITE_API_URL: ${{ secrets.VITE_API_URL }} + VITE_KAKAO_JS_KEY: ${{ secrets.VITE_KAKAO_JS_KEY }} + + - name: Deploy to Firebase + uses: FirebaseExtended/action-hosting-deploy@v0 with: repoToken: ${{ secrets.GITHUB_TOKEN }} firebaseServiceAccount: ${{ secrets.FIREBASE_SERVICE_ACCOUNT_TTORANG }} diff --git a/.github/workflows/firebase-hosting-pull-request.yml b/.github/workflows/firebase-hosting-pull-request.yml index 2df385a0..b2aac072 100644 --- a/.github/workflows/firebase-hosting-pull-request.yml +++ b/.github/workflows/firebase-hosting-pull-request.yml @@ -1,20 +1,36 @@ -# This file was auto-generated by the Firebase CLI -# https://github.com/firebase/firebase-tools - name: Deploy to Firebase Hosting on PR + on: pull_request + permissions: checks: write contents: read pull-requests: write + jobs: build_and_preview: if: ${{ github.event.pull_request.head.repo.full_name == github.repository }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - run: npm ci && npm run build - - uses: FirebaseExtended/action-hosting-deploy@v0 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: Build + run: npm run build + env: + VITE_API_URL: ${{ secrets.VITE_API_URL }} + VITE_KAKAO_JS_KEY: ${{ secrets.VITE_KAKAO_JS_KEY }} + + - name: Deploy Preview to Firebase + uses: FirebaseExtended/action-hosting-deploy@v0 with: repoToken: ${{ secrets.GITHUB_TOKEN }} firebaseServiceAccount: ${{ secrets.FIREBASE_SERVICE_ACCOUNT_TTORANG }} diff --git a/firebase.json b/firebase.json index 2c33c295..fca1292d 100644 --- a/firebase.json +++ b/firebase.json @@ -1,16 +1,62 @@ { "hosting": { "public": "dist", - "ignore": [ - "firebase.json", - "**/.*", - "**/node_modules/**" - ], + "ignore": ["firebase.json", "**/.*", "**/node_modules/**"], "rewrites": [ { "source": "**", "destination": "/index.html" } + ], + "headers": [ + { + "source": "**/*.@(js|css)", + "headers": [ + { + "key": "Cache-Control", + "value": "public, max-age=31536000, immutable" + } + ] + }, + { + "source": "**/*.@(jpg|jpeg|png|gif|webp|svg|ico|woff|woff2)", + "headers": [ + { + "key": "Cache-Control", + "value": "public, max-age=31536000, immutable" + } + ] + }, + { + "source": "index.html", + "headers": [ + { + "key": "Cache-Control", + "value": "no-cache, no-store, must-revalidate" + } + ] + }, + { + "source": "**", + "headers": [ + { + "key": "X-Frame-Options", + "value": "DENY" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-XSS-Protection", + "value": "1; mode=block" + }, + { + "key": "Referrer-Policy", + "value": "strict-origin-when-cross-origin" + } + ] + } ] } } From 55f6606e285788c84466db0707978fb8db7c1a6b Mon Sep 17 00:00:00 2001 From: Andy Hong Date: Sun, 18 Jan 2026 19:00:04 +0900 Subject: [PATCH 2/2] =?UTF-8?q?fix:=20=EC=BD=94=EB=93=9C=20=EB=A6=AC?= =?UTF-8?q?=EB=B7=B0=20=EB=B0=98=EC=98=81=20-=20=EB=B3=B4=EC=95=88=20?= =?UTF-8?q?=ED=97=A4=EB=8D=94=20=EA=B0=9C=EC=84=A0=20(#53)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - X-XSS-Protection 제거 (deprecated) - Content-Security-Policy 추가 - 캐싱 규칙 병합 (JS/CSS + 이미지/폰트) Co-Authored-By: Claude Haiku 4.5 --- firebase.json | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/firebase.json b/firebase.json index fca1292d..fdd45898 100644 --- a/firebase.json +++ b/firebase.json @@ -10,16 +10,7 @@ ], "headers": [ { - "source": "**/*.@(js|css)", - "headers": [ - { - "key": "Cache-Control", - "value": "public, max-age=31536000, immutable" - } - ] - }, - { - "source": "**/*.@(jpg|jpeg|png|gif|webp|svg|ico|woff|woff2)", + "source": "**/*.@(js|css|jpg|jpeg|png|gif|webp|svg|ico|woff|woff2)", "headers": [ { "key": "Cache-Control", @@ -39,6 +30,10 @@ { "source": "**", "headers": [ + { + "key": "Content-Security-Policy", + "value": "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' https://dev-api.ttorang.com https://api.ttorang.com https://developers.kakao.com; frame-ancestors 'none'" + }, { "key": "X-Frame-Options", "value": "DENY" @@ -47,10 +42,6 @@ "key": "X-Content-Type-Options", "value": "nosniff" }, - { - "key": "X-XSS-Protection", - "value": "1; mode=block" - }, { "key": "Referrer-Policy", "value": "strict-origin-when-cross-origin"