Feature: 무기 합성 시스템 기초 로직 #44
Workflow file for this run
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
| name: CI | |
| on: | |
| pull_request: | |
| types: [opened, synchronize, reopened] | |
| branches: [main, develop] | |
| pull_request_review: | |
| types: [submitted, dismissed] | |
| concurrency: | |
| group: ci-${{ github.event.pull_request.number }} | |
| cancel-in-progress: true | |
| jobs: | |
| # ───────────────────────────────────────────── | |
| # 0. 리뷰 승인 여부 게이트 | |
| # ───────────────────────────────────────────── | |
| review-gate: | |
| name: Review Gate (승인 필요) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: 리뷰 승인 수 확인 | |
| uses: actions/github-script@v7 | |
| with: | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| script: | | |
| const { data: reviews } = await github.rest.pulls.listReviews({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| pull_number: context.payload.pull_request?.number ?? context.payload.review?.pull_request_url?.split('/').pop(), | |
| }); | |
| const latest = {}; | |
| for (const r of reviews) { | |
| if (r.state === 'APPROVED' || r.state === 'CHANGES_REQUESTED') { | |
| latest[r.user.login] = r.state; | |
| } | |
| } | |
| const approved = Object.values(latest).filter(s => s === 'APPROVED').length; | |
| const required = 1; | |
| console.log(`승인 수: ${approved} / 필요: ${required}`); | |
| if (approved < required) { | |
| core.setFailed(`❌ 리뷰 승인이 ${required}개 필요합니다. (현재 ${approved}개)`); | |
| } | |
| # ───────────────────────────────────────────── | |
| # 1. 메타파일 누락 검사 | |
| # ───────────────────────────────────────────── | |
| meta-check: | |
| name: Meta File Check | |
| runs-on: ubuntu-latest | |
| needs: [review-gate] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: .meta 파일 누락 확인 | |
| run: | | |
| MISSING=$(find Fantasy-Grower/Assets -type f ! -name "*.meta" | while read f; do | |
| if [ ! -f "${f}.meta" ]; then echo "$f"; fi | |
| done) | |
| if [ -n "$MISSING" ]; then | |
| echo "❌ .meta 파일이 누락된 항목:" | |
| echo "$MISSING" | |
| exit 1 | |
| fi | |
| echo "✅ 모든 .meta 파일 정상" | |
| - name: 고아 .meta 파일 확인 | |
| run: | | |
| ORPHAN=$(find Fantasy-Grower/Assets -name "*.meta" | while read m; do | |
| original="${m%.meta}" | |
| if [ ! -e "$original" ]; then echo "$m"; fi | |
| done) | |
| if [ -n "$ORPHAN" ]; then | |
| echo "⚠️ 원본 없는 고아 .meta 파일:" | |
| echo "$ORPHAN" | |
| exit 1 | |
| fi | |
| echo "✅ 고아 .meta 파일 없음" | |
| # ───────────────────────────────────────────── | |
| # 2. C# 정적 분석 | |
| # ───────────────────────────────────────────── | |
| static-analysis: | |
| name: C# Static Analysis | |
| runs-on: ubuntu-latest | |
| needs: [review-gate] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: .NET SDK 설치 | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: '8.0.x' | |
| # 수정 | |
| - name: dotnet-csharpier 설치 | |
| run: dotnet tool install --tool-path ./tools csharpier | |
| - name: C# 포맷 검사 | |
| run: ./tools/csharpier check Fantasy-Grower/Assets/Scripts | |
| # ───────────────────────────────────────────── | |
| # 4. Discord 실패 알림 | |
| # ───────────────────────────────────────────── | |
| discord-ci-failure: | |
| name: Discord CI 실패 알림 | |
| runs-on: ubuntu-latest | |
| needs: [review-gate, meta-check, static-analysis] | |
| if: failure() | |
| steps: | |
| - name: Discord 알림 전송 | |
| uses: sarisia/actions-status-discord@v1 | |
| with: | |
| webhook: ${{ secrets.DISCORD_WEBHOOK }} | |
| status: failure | |
| title: "CI 검사 실패" | |
| description: | | |
| PR: ${{ github.event.pull_request.title }} | |
| 작성자: @${{ github.event.pull_request.user.login }} | |
| 베이스: `${{ github.event.pull_request.base.ref }}` ← `${{ github.event.pull_request.head.ref }}` | |
| url: ${{ github.event.pull_request.html_url }} | |
| username: "Flooding Client Bot" | |
| avatar_url: ${{ secrets.DISCORD_AVATAR_URL }} | |
| color: "0xFF0000" | |
| nofail: true | |
| nocontext: true | |
| noprefix: true | |
| notimestamp: false | |
| ack_no_webhook: true |