[feat] 아이콘 리뉴얼 공컴 구현 #937
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Chromatic 스토리북 자동 배포 워크플로우 | |
| # 이 워크플로우는 스토리북을 빌드하고 Chromatic에 배포하여 시각적 회귀 테스트를 수행합니다. | |
| # Chromatic은 스토리북의 모든 컴포넌트를 스크린샷으로 캡처하고 변경사항을 추적합니다. | |
| name: '🟣 Chromatic' | |
| # 워크플로우 트리거 조건 | |
| on: | |
| # develop, main 브랜치에 push될 때 실행 | |
| # - develop: 개발 환경의 베이스라인 업데이트 | |
| # - main: 프로덕션 환경의 베이스라인 업데이트 | |
| push: | |
| branches: [develop, main] | |
| # PR이 생성, 업데이트, 재오픈될 때 실행 | |
| # - opened: 새로운 PR 생성 시 | |
| # - synchronize: PR에 새로운 커밋 추가 시 | |
| # - reopened: 닫혔던 PR을 다시 열 때 | |
| pull_request: | |
| types: [opened, synchronize, reopened] | |
| # GitHub 토큰 권한 설정 (최소 권한 원칙) | |
| # - contents: read → 저장소 읽기 전용 | |
| # - pull-requests: write → PR 코멘트/상태 업데이트용 | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| # 중복 실행 방지(concurrency) | |
| # 동일 브랜치(또는 PR)에서 이전 잡이 실행 중이면 취소하고 최신 잡만 유지하여 CI 자원 절약 | |
| concurrency: | |
| group: chromatic-${{ github.head_ref || github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| chromatic: | |
| # Ubuntu 최신 버전 환경에서 실행 | |
| runs-on: ubuntu-latest | |
| # 잡 전체 타임아웃 (분) | |
| timeout-minutes: 20 | |
| # 조건부 실행: Draft PR인 경우 워크플로우 스킵 | |
| # push 이벤트에는 pull_request 객체가 없으므로 조건 분기 | |
| if: ${{ github.event_name != 'pull_request' || !github.event.pull_request.draft }} | |
| steps: | |
| # 1. 저장소 체크아웃 | |
| # 코드를 GitHub Actions 러너에 복사합니다. | |
| - name: Checkout Repository | |
| uses: actions/checkout@v4 | |
| with: | |
| # fetch-depth: 0 - 전체 Git 히스토리를 가져옴 | |
| # Chromatic이 변경사항을 정확히 추적하기 위해 필요 | |
| fetch-depth: 0 | |
| # 2. PNPM 패키지 매니저 설정 | |
| # package.json의 packageManager 필드를 읽어 올바른 버전 자동 설치 | |
| - uses: pnpm/action-setup@v4 | |
| # 3. Node.js 환경 설정 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| # Node.js 22.x 버전 사용 (프로젝트 요구사항과 일치) | |
| node-version: '22.x' | |
| # pnpm 캐시 활성화로 의존성 설치 속도 향상 | |
| cache: 'pnpm' | |
| # 4. 의존성 캐싱 | |
| # node_modules를 캐시하여 반복적인 설치 시간을 단축합니다. | |
| - name: Cache node modules | |
| id: cache-node | |
| uses: actions/cache@v3 | |
| with: | |
| # 캐시할 경로들 | |
| path: | | |
| **/node_modules # 모든 node_modules 디렉토리 | |
| ~/.cache/Cypress # Cypress 바이너리 캐시 (있을 경우) | |
| # 캐시 키: OS + pnpm-lock.yaml 해시값 | |
| # pnpm-lock.yaml이 변경되면 새로운 캐시 생성 | |
| key: ${{ runner.os }}-node-${{ hashFiles('**/pnpm-lock.yaml') }} | |
| # 정확한 키가 없을 때 사용할 대체 키 (부분 매칭) | |
| restore-keys: | | |
| ${{ runner.os }}-node- | |
| # pnpm store 캐시 | |
| # pnpm은 node_modules 외에 전역 저장소(~/.pnpm-store)에 패키지를 보관하므로 | |
| # 해당 디렉토리를 캐싱하면 의존성 설치 시간을 대폭 단축할 수 있음 | |
| - name: Cache pnpm store | |
| id: cache-pnpm-store | |
| uses: actions/cache@v3 | |
| with: | |
| path: ~/.pnpm-store | |
| key: ${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-pnpm- | |
| # 5. 의존성 설치 | |
| # 캐시가 없거나 오래된 경우에만 설치 실행 | |
| - name: Install Dependencies | |
| # 캐시 히트가 없을 때만 실행 (cache-hit != 'true') | |
| if: steps.cache-node.outputs.cache-hit != 'true' | |
| # --frozen-lockfile: lock 파일과 정확히 일치하는 버전만 설치 | |
| # CI 환경에서 예상치 못한 업데이트 방지 | |
| run: pnpm install --frozen-lockfile | |
| # 6. 스토리북 빌드 | |
| # 모든 스토리를 정적 파일로 빌드하여 storybook-static 폴더에 저장 | |
| - name: Build Storybook | |
| run: pnpm build-storybook | |
| # 7. Chromatic 배포 | |
| # Chromatic 공식 GitHub Action 사용 | |
| - name: Publish to Chromatic | |
| id: chromatic | |
| uses: chromaui/action@latest | |
| with: | |
| # Chromatic 프로젝트 토큰 | |
| projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} | |
| # 이미 빌드된 스토리북 디렉토리 지정 (빌드 시간 절약) | |
| storybookBuildDir: storybook-static | |
| # PR에서만 변경된 스토리만 테스트 | |
| onlyChanged: ${{ github.event_name == 'pull_request' }} | |
| # develop 브랜치에서는 변경사항 자동 승인 | |
| autoAcceptChanges: ${{ github.ref == 'refs/heads/develop' }} | |
| # 시각적 변경이 있어도 CI 실패 방지 | |
| exitZeroOnChanges: true | |
| # Chromatic CLI 옵션 설명: | |
| # --project-token: Chromatic 프로젝트 인증 토큰 (필수) | |
| # --storybook-build-dir: 이미 빌드된 스토리북 디렉토리 지정 (빌드 시간 절약) | |
| # --only-changed: PR에서만 true - 변경된 컴포넌트만 테스트하여 속도 향상 | |
| # --auto-accept-changes: develop 브랜치에서만 true - 자동으로 변경사항 승인 | |
| # --exit-zero-on-changes: 시각적 변경이 있어도 성공으로 처리 (CI 실패 방지) | |
| # 8. 커버리지 리포트 | |
| # GitHub Actions 요약 페이지에 스토리북 상태 정보 출력 | |
| - name: Create Coverage Report | |
| id: coverage | |
| # always(): 이전 단계 실패 여부와 관계없이 항상 실행 | |
| if: always() | |
| run: | | |
| # GITHUB_STEP_SUMMARY: GitHub Actions 요약 페이지에 표시될 내용 | |
| echo "## 📊 Storybook Coverage Report" >> $GITHUB_STEP_SUMMARY | |
| # 스토리 파일 개수 계산 | |
| echo "- **Total Components**: $(find src -name "*.stories.tsx" | wc -l)" >> $GITHUB_STEP_SUMMARY | |
| # Chromatic 단계의 실행 결과 (success/failure) | |
| echo "- **Build Status**: ${{ steps.chromatic.outcome }}" >> $GITHUB_STEP_SUMMARY | |
| # 배포된 스토리북 URL (없으면 N/A 표시) | |
| echo "- **Storybook URL**: ${{ steps.chromatic.outputs.storybookUrl || 'N/A' }}" >> $GITHUB_STEP_SUMMARY | |
| # Chromatic 빌드 URL | |
| echo "- **Chromatic Build**: ${{ steps.chromatic.outputs.buildUrl || 'N/A' }}" >> $GITHUB_STEP_SUMMARY | |
| # 빌드 시간 기록 | |
| echo "- **Build Time**: $(date)" >> $GITHUB_STEP_SUMMARY | |
| # 9. PR 코멘트 | |
| # PR에 스토리북 링크와 빌드 정보를 자동으로 댓글로 추가 | |
| - name: Comment PR | |
| # PR 이벤트일 때만 실행 | |
| if: github.event_name == 'pull_request' | |
| uses: thollander/actions-comment-pull-request@v2 | |
| with: | |
| # comment_tag: 동일한 태그의 기존 코멘트를 업데이트 (중복 방지) | |
| comment_tag: chromatic-build | |
| # 코멘트 내용 | |
| message: | | |
| ## 🎨 Storybook 빌드 완료! | |
| 📚 **Storybook**: ${{ steps.chromatic.outputs.storybookUrl }} | |
| 🔍 **Chromatic**: ${{ steps.chromatic.outputs.buildUrl }} | |
| ### 📊 빌드 정보 | |
| - **빌드 상태**: ${{ steps.chromatic.outcome }} | |
| - **테스트된 스토리**: ${{ steps.chromatic.outputs.actualTestCount || '0' }}개 | |
| - **변경된 컴포넌트**: ${{ steps.chromatic.outputs.actualCaptureCount || '0' }}개 | |
| ${{ steps.chromatic.outputs.changeCount && format('> 🔍 **시각적 변경사항**: {0}개 발견', steps.chromatic.outputs.changeCount) || '' }} | |
| # 10. Discord 알림 | |
| # 팀 Discord 채널에 빌드 결과 알림 전송 | |
| - name: Discord Notification | |
| # always(): 성공/실패 여부와 관계없이 항상 알림 | |
| if: always() | |
| uses: sarisia/actions-status-discord@v1 | |
| with: | |
| # Discord 웹훅 URL (GitHub Secrets에 저장) | |
| webhook: ${{ secrets.DISCORD_WEBHOOK }} | |
| # 알림 제목: 성공/실패에 따라 다른 이모지 표시 | |
| title: "Chromatic 빌드 ${{ job.status == 'success' && '성공 ✅' || '실패 ❌' }}" | |
| # 알림 본문: 프로젝트 정보 | |
| description: | | |
| **프로젝트**: ${{ github.repository }} | |
| **브랜치**: ${{ github.ref_name }} | |
| **커밋**: ${{ github.sha }} | |
| **실행자**: ${{ github.actor }} | |
| # 임베드 색상: 성공=초록색(0x00ff00), 실패=빨간색(0xff0000) | |
| color: ${{ job.status == 'success' && 0x00ff00 || 0xff0000 }} | |
| # GitHub Actions 실행 페이지 링크 | |
| url: '${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}' | |
| # Discord에 표시될 봇 이름 | |
| username: HOUME Bot | |
| # Discord에 표시될 봇 아바타 | |
| avatar_url: 'https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png' |