From 75addc03f21e372b0adea1a91091177ddbac9882 Mon Sep 17 00:00:00 2001 From: htlee Date: Sat, 14 Feb 2026 20:03:16 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20CI/CD=20=EC=9E=90=EB=8F=99=20=EB=B0=B0?= =?UTF-8?q?=ED=8F=AC=20=EC=9B=8C=ED=81=AC=ED=94=8C=EB=A1=9C=EC=9A=B0=20+?= =?UTF-8?q?=20=EA=B0=80=EC=9D=B4=EB=93=9C=20=ED=8E=98=EC=9D=B4=EC=A7=80=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - .gitea/workflows/deploy.yml: main 머지 시 자동 빌드+배포 - CiCdGuide.tsx: CI/CD 가이드 페이지 (워크플로우 작성법, 시크릿, 트러블슈팅) - navigation.ts, GuidePage.tsx: CI/CD 메뉴 항목 + 라우트 등록 Co-Authored-By: Claude Opus 4.6 --- .gitea/workflows/deploy.yml | 36 +++ src/content/CiCdGuide.tsx | 506 ++++++++++++++++++++++++++++++++++++ src/pages/GuidePage.tsx | 1 + src/utils/navigation.ts | 1 + 4 files changed, 544 insertions(+) create mode 100644 .gitea/workflows/deploy.yml create mode 100644 src/content/CiCdGuide.tsx diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml new file mode 100644 index 0000000..0fd405c --- /dev/null +++ b/.gitea/workflows/deploy.yml @@ -0,0 +1,36 @@ +name: Build and Deploy + +on: + push: + branches: + - main + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Configure npm registry + run: | + echo "registry=https://nexus.gc-si.dev/repository/npm-public/" > .npmrc + echo "//nexus.gc-si.dev/repository/npm-public/:_auth=${{ secrets.NEXUS_NPM_AUTH }}" >> .npmrc + + - name: Install dependencies + run: npm ci + + - name: Build + run: npm run build + + - name: Deploy to server + run: | + rm -rf /deploy/guide/* + cp -r dist/* /deploy/guide/ + echo "Deployed at $(date '+%Y-%m-%d %H:%M:%S')" + ls -la /deploy/guide/ diff --git a/src/content/CiCdGuide.tsx b/src/content/CiCdGuide.tsx new file mode 100644 index 0000000..0cb9c25 --- /dev/null +++ b/src/content/CiCdGuide.tsx @@ -0,0 +1,506 @@ +import { Alert } from '../components/common/Alert'; +import { CodeBlock } from '../components/common/CodeBlock'; +import { StepGuide } from '../components/common/StepGuide'; + +export default function CiCdGuide() { + return ( +
+

CI/CD 자동 배포

+

+ Gitea Actions를 이용한 자동 빌드 및 배포 파이프라인 구성 방법을 안내합니다. +

+ + {/* 개요 */} +

개요

+

+ Gitea Actions는 GitHub Actions와 호환되는 CI/CD 시스템입니다. + 리포지토리에 워크플로우 파일을 추가하면, 특정 이벤트(push, MR 등) 발생 시 + 자동으로 빌드와 배포가 실행됩니다. +

+
+
+
+ main 머지 + + Gitea Actions 트리거 + + act_runner + + 빌드 + 배포 + + 서비스 갱신 +
+
+
+ +
+

배포 흐름

+
+

개발자 → feature 브랜치 push → develop MR 머지

+

+

develop → main MR 생성 → 리뷰 승인 → main 머지

+

+

+ Gitea Actions 트리거 → act_runner (Docker 컨테이너) +

+

+

npm ci → npm run build → dist/ 생성

+

+

+ 배포 경로에 복사 → Nginx 서빙 +

+
+
+ + + GitHub Actions 워크플로우 파일과 동일한 문법을 사용합니다. + 기존 GitHub Actions 경험이 있다면 쉽게 적용할 수 있습니다. + + + {/* 워크플로우 파일 구조 */} +

워크플로우 파일 구조

+

+ 워크플로우 파일은 리포지토리의{' '} + .gitea/workflows/ 디렉토리에 YAML 형식으로 작성합니다. +

+ + +

기본 구조

+ + + {/* 트리거 조건 */} +

트리거 조건

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
이벤트설명예시
push브랜치에 push 시branches: [main]
pull_requestMR 생성/업데이트 시branches: [main], types: [opened, synchronize]
scheduleCron 스케줄cron: '0 2 * * *'
workflow_dispatch수동 실행Gitea UI에서 수동 트리거
+
+ + + MR을 통해 main에 머지하면 push 이벤트가 발생합니다. + 배포 워크플로우는 on: push: branches: [main]으로 설정하는 것이 일반적입니다. + + + {/* 시크릿 관리 */} +

시크릿 관리

+

+ 비밀번호, 인증 토큰 등 민감한 정보는 리포지토리 시크릿으로 관리합니다. + 워크플로우에서{' '} + {'${{ secrets.시크릿_이름 }}'}으로 참조합니다. +

+ + 대상 리포지토리 → SettingsActions →{' '} + Secrets로 이동합니다. +

+ ), + }, + { + title: '시크릿 추가', + content: ( +

+ Add Secret 클릭 후 이름과 값을 입력합니다. + 시크릿 이름은 UPPER_SNAKE_CASE로 작성합니다. +

+ ), + }, + { + title: '워크플로우에서 사용', + content: ( + > .npmrc`} + /> + ), + }, + ]} + /> + +
+ + + + + + + + + + + + + + + +
시크릿 이름용도설정된 리포
NEXUS_NPM_AUTHNexus npm 레지스트리 인증 (Base64)gc-guide
+
+ + {/* gc-guide 워크플로우 예시 */} +

gc-guide 워크플로우 (React)

+

+ gc-guide 프로젝트의 실제 배포 워크플로우입니다. + main 브랜치에 머지되면 자동으로 빌드하고 서버에 배포합니다. +

+ .npmrc + echo "//nexus.gc-si.dev/repository/npm-public/:_auth=\${{ secrets.NEXUS_NPM_AUTH }}" >> .npmrc + + - name: Install dependencies + run: npm ci + + - name: Build + run: npm run build + + - name: Deploy to server + run: | + rm -rf /deploy/guide/* + cp -r dist/* /deploy/guide/ + echo "Deployed at $(date '+%Y-%m-%d %H:%M:%S')" + ls -la /deploy/guide/`} + /> + + + /deploy/guide/는 act_runner 컨테이너 설정에서 + 호스트의 /devdata/services/guide/dist/에 + 마운트되어 있습니다. 빌드 결과물을 복사하면 Nginx가 즉시 서빙합니다. + + + {/* gc-guide-api 워크플로우 예시 (향후) */} +

gc-guide-api 워크플로우 (Spring Boot, 예정)

+

+ Java/Spring Boot 프로젝트의 워크플로우 예시입니다. 향후 gc-guide-api에 적용 예정입니다. +

+ ~/.m2/settings.xml << 'EOF' + + + + nexus + * + https://nexus.gc-si.dev/repository/maven-public/ + + + + + nexus + \${{ secrets.NEXUS_USERNAME }} + \${{ secrets.NEXUS_PASSWORD }} + + + + EOF + + - name: Build + run: mvn clean package -DskipTests + + - name: Deploy + run: | + cp target/*.jar /deploy/api/app.jar + # 서비스 재시작은 별도 스크립트로 처리`} + /> + + {/* Actions 확인 */} +

빌드 결과 확인

+ + + https://gitea.gc-si.dev/gc/gc-guide + + 에 접속합니다. +

+ ), + }, + { + title: 'Actions 탭 확인', + content: ( +

+ 리포지토리 상단의 Actions 탭을 클릭하면 워크플로우 실행 이력을 확인할 수 있습니다. + 각 실행 항목을 클릭하면 상세 로그를 볼 수 있습니다. +

+ ), + }, + { + title: '배포 결과 확인', + content: ( +

+ 빌드 성공 후{' '} + + https://guide.gc-si.dev + + 에서 배포 결과를 확인합니다. 변경 사항이 반영되지 않으면 브라우저 캐시를 삭제하세요 (Ctrl+Shift+R). +

+ ), + }, + ]} + /> + + {/* 워크플로우 작성 팁 */} +

워크플로우 작성 팁

+ +

자주 사용하는 액션

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
액션용도
actions/checkout@v4리포지토리 소스코드 체크아웃
actions/setup-node@v4Node.js 설정
actions/setup-java@v4JDK 설정
actions/cache@v4의존성 캐시 (빌드 시간 단축)
+
+ +

환경변수와 시크릿

+ + + {/* Runner 관리 (관리자) */} +

Runner 관리 (관리자)

+

+ Gitea Actions는 act_runner라는 실행기가 빌드를 처리합니다. + Docker 컨테이너로 동작하며, 각 빌드 job을 별도 Docker 컨테이너에서 격리 실행합니다. +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
항목
Runner 이름gc-runner-01
컨테이너act-runner (gitea/act_runner:latest)
라벨ubuntu-latest, ubuntu-22.04
빌드 이미지node:20 (Docker)
네트워크devnet (Gitea/Nexus와 동일)
+
+ +

관리 명령어

+ + + {/* 트러블슈팅 */} +

트러블슈팅

+ +
+
+

빌드가 시작되지 않음

+
    +
  • 리포지토리 Settings → Actions가 활성화되어 있는지 확인
  • +
  • 워크플로우 파일 경로 확인: .gitea/workflows/*.yml
  • +
  • Runner가 Online 상태인지 확인: Gitea 관리자 → Runners
  • +
  • runs-on 라벨이 Runner 라벨과 일치하는지 확인
  • +
+
+ +
+

npm ci 실패

+
    +
  • NEXUS_NPM_AUTH 시크릿이 올바르게 설정되어 있는지 확인
  • +
  • Nexus 서버가 접근 가능한지 확인 (act_runner가 devnet 네트워크에 있어야 함)
  • +
  • package-lock.json이 커밋되어 있는지 확인 (npm ci 필수)
  • +
+
+ +
+

배포 후 변경 사항이 안 보임

+
    +
  • 브라우저 캐시 강제 새로고침: Ctrl+Shift+R
  • +
  • Actions 탭에서 Deploy 단계 로그 확인
  • +
  • 서버에서 파일 확인: ls -la /devdata/services/guide/dist/
  • +
+
+ +
+

Runner가 Offline으로 표시됨

+
    +
  • 컨테이너 상태 확인: docker ps | grep act-runner
  • +
  • 로그 확인: docker logs act-runner --tail 30
  • +
  • 컨테이너 재시작: docker compose restart act-runner
  • +
+
+
+
+ ); +} diff --git a/src/pages/GuidePage.tsx b/src/pages/GuidePage.tsx index e3cff3a..5ba3bf9 100644 --- a/src/pages/GuidePage.tsx +++ b/src/pages/GuidePage.tsx @@ -10,6 +10,7 @@ const CONTENT_MAP: Record 'chat-bot': lazy(() => import('../content/ChatBotIntegration')), 'starting-project': lazy(() => import('../content/StartingProject')), 'design-system': lazy(() => import('../content/DesignSystem')), + 'ci-cd': lazy(() => import('../content/CiCdGuide')), }; export function GuidePage() { diff --git a/src/utils/navigation.ts b/src/utils/navigation.ts index eaf201a..6139a68 100644 --- a/src/utils/navigation.ts +++ b/src/utils/navigation.ts @@ -9,6 +9,7 @@ export const DEV_NAV: NavItem[] = [ { path: '/dev/chat-bot', label: 'Chat 봇 연동' }, { path: '/dev/starting-project', label: '프로젝트 시작하기' }, { path: '/dev/design-system', label: '디자인 시스템' }, + { path: '/dev/ci-cd', label: 'CI/CD 자동 배포' }, ]; export const ADMIN_NAV: NavItem[] = [ -- 2.45.2