Skip to content

ci: 테스트 샤딩·잡 병렬화·커버리지 리포트 재사용으로 CI 단축 - #494

Merged
chanwoo7 merged 8 commits into
developfrom
ci/parallel-shards
Oct 4, 2026
Merged

chanwoo7 merged 8 commits into
developfrom
ci/parallel-shards

Conversation

@chanwoo7

@chanwoo7 chanwoo7 commented Oct 4, 2026 •

Copy link
Copy Markdown
Member

배경

변경

  • pr-check.yml을 잡으로 나눠 나란히 돌립니다. 워크플로 이름 CI와 필수 체크 이름 4개는 그대로입니다.
    • static: codegen, tsc, lint, dto:check(경고만), docs:check, arch:check
    • scripts: test:scripts
    • build: 빌드 2회 + dist/main.js 확인(캐시 회귀 검출 유지)
    • test: jest 2샤드(fail-fast: false)
      • --coverage는 LanguageService 모드 선택 때문에 유지하고, 샤드별 임계는 '--coverageThreshold={}'로 끕니다.
      • --json 결과를 아티팩트(1일)로 올립니다. 로그가 길어지지 않게 샤드의 커버리지 리포터는 text-summary만 씁니다.
    • coverage-report: 샤드 결과를 scripts/merge-coverage.ts로 합칩니다.
      • 테스트 실패·샤드 누락·임계 미달이면 실패하고, 그때도 report.json은 먼저 써서 PR 댓글에 실패가 보입니다. 임계는 jest.config.js에서 읽습니다.
      • push 실행은 report.json을 기준 아티팩트(90일)로 올립니다. 실패해도 배포를 막지 않게 continue-on-error입니다.
      • PR 실행은 이 레포 base 브랜치의 성공한 push 실행에서만 기준을 받습니다(base 커밋 실행 → 브랜치 최근 실행 → 없으면 head 복사). 액션은 coverage-file·base-coverage-file로 테스트를 다시 돌리지 않고 댓글만 답니다.
      • Codecov에는 합친 lcov를 한 번 올립니다(backend-lcov 그대로). codecov-action이 업로드 토큰을 GITHUB_ENV로 뒤 단계에 남기므로 잡의 마지막 단계에 둡니다.
    • check: if: always()로 늘 돌고, needs 결과가 전부 success인지 직접 검사합니다. 건너뜀·취소도 실패입니다.
    • actions: read는 기준 아티팩트를 받는 coverage-report에만 줍니다.
  • node_modules를 캐시합니다. 키는 yarn.lock·package.json·.yarnrc.yml·yarn 릴리즈·OS·arch·node 버전입니다. 적중하면 설치 대신 prisma generate만 돌립니다(postinstall 대체).
  • 커버리지 임계를 96/86/92/96에서 97/92/97/98로 올렸습니다(statements/branches/functions/lines).
  • istanbul 패키지 3개와 그 타입을 lockfile에 있던 버전 그대로 devDependencies에 명시했습니다(지금까지는 간접 의존).
  • README·README.en CI 절, 가이드 §9, jest.config.js·jest.scripts.config.js 주석을 새 구조와 수치에 맞게 고쳤습니다.

검증

  • 새 구조의 CI가 이 PR에서 통과했습니다. 필수 체크 완료 시간은 다음과 같습니다.
    • run 37221170062(첫 실행, PR 범위 캐시 없음): +243초
    • run 37221796690(캐시 적중): +240초
    • run 37222851465(최종 head, 캐시 키 변경으로 다시 설치): +272초
    • 이전 373448초 대비 약 2.53분 줄었습니다. 대기 경로는 test 샤드(약 3분 10초3분 40초) → coverage-report(3040초) → check(2초)입니다.
    • 샤드 하나는 컨테이너 기동 약 30초, 테스트 95130초, 미적재 파일 커버리지·리포트 1317초입니다. 같은 spec도 러너에 따라 25~40% 차이가 납니다.
  • 합친 커버리지가 단일 실행과 개수까지 같습니다.
  • 일부러 실패시켜 집계가 막는지 확인하고 되돌렸습니다.
    • adadfc9에 CI에서만 실패하는 spec 1건을 넣었습니다(run 37222298720).
    • check-run 결론: test (1) failure, test (2) success, coverage-report failure(merge-coverage가 "테스트 실패 — 실패 1건"으로 exit 1), check failure(needs: test=failure, coverage-report=failure)
    • 커버리지 댓글은 실패 내역으로 갱신됐습니다. e8499c1에서 되돌린 뒤 최종 head 4d05aa0은 다시 통과했습니다.
  • 커버리지 댓글은 PR 전체에서 1개만 달리고, 실행마다 같은 댓글이 갱신됩니다.
  • develop에는 아직 기준 아티팩트가 없어, 기준 받기가 최근 push 실행 5건에서 아티팩트를 찾지 못하고 head로 폴백했습니다(차이 0, notice 표시). 머지 뒤 첫 develop push가 기준을 만듭니다.
  • spec(test:scripts)
    • merge-coverage.spec(신규)
      • 두 조각을 합치면 단일 실행 수치와 같습니다.
      • 반증: 조각 하나·샤드 누락·테스트 실패(report.json은 남음)·coverageMap 없음·지원하지 않는 임계 형식은 실패합니다.
      • CLI 종료 코드 0/1/2를 확인합니다.
    • deploy-workflow.spec
      • check 집계 스크립트를 실제 bash로 돌려 success·failure·skipped·cancelled·빈 needs를 전수 확인합니다.
      • coverage-report의 needs·if, 샤드 수 일치, 캐시 키와 적중 경로, actions 권한 범위, Codecov 단계 위치를 고정합니다.
      • 기준 받기 스크립트를 gh 대역으로 돌려 순서·중복 제거·head 폴백을 확인합니다.
    • 반증: 샤드 수 검사, 테스트 실패 검사, pct 비교 방향, jq success 조건, 중복 제거, coverage-report if, head 폴백을 하나씩 지우면 spec이 실패합니다.
  • 실제 coverage-final.json(500파일)을 파일 단위로 두 조각 내 CLI로 합쳤습니다.
    • 원본과 같은 수치이고 새 임계를 통과합니다(exit 0).
    • 한 조각만 넣으면 네 지표 모두 미달로 exit 1입니다.

리뷰 반영

  • 적대적 리뷰(별도 에이전트)와 Codex 지적을 반영했습니다.
    • 샤드 아티팩트 보존 1일 → 7일
    • 집계 잡 check는 토큰을 쓰지 않아 permissions: {}
    • 가이드 §9·pre-push-test-plan 주석의 "CI check가 돌린다"를 새 잡 기준으로 정리
    • node_modules 캐시 키에 .yarnrc.yml·yarn 릴리즈 포함(Codex P2)
  • 미반영: fork PR의 읽기 전용 토큰으로 댓글 단계가 실패하는 문제(Codex P1)는 이 PR 이전에도 같았습니다. Dependabot PR은 잡 단위 권한이 적용돼 성공합니다(run 37133178668).

플랜 대조

플랜 1절(BE) 불릿 상태
static 잡(설치 → codegen → tsc → lint → dto·docs → arch) 한 것
scripts 잡(test:scripts) 한 것
build 잡(빌드 2회 + dist/main.js 확인 유지) 한 것
test 샤드 2개, fail-fast: false, --coverage 유지, '--coverageThreshold={}', --json·--testLocationInResults, 아티팩트 1일 한 것 — 리뷰 반영으로 7일(하루 뒤 coverage-report만 재실행해도 샤드가 남게)
coverage-report: needs: test, PR·push 모두 실행 한 것
merge-coverage.ts: 테스트 실패·샤드 누락·임계 미달이면 실패, 임계는 jest.config.js, report.json을 먼저 씀 한 것
Codecov에 합친 lcov 1회(backend-lcov) 한 것
develop·main push면 기준 아티팩트 90일, continue-on-error 한 것 — push 트리거 전체(develop-msa 포함)
PR이면 base 브랜치의 성공한 push 실행 아티팩트(base 커밋 우선 → 브랜치 최신 → head 복사) + 액션 coverage-file·base-coverage-file 한 것
check 집계: if: always(), 결과가 전부 success인지 직접 검사 한 것
image·pr-title 그대로 한 것
node_modules 캐시(yarn.lock·package.json·OS·node), 적중 시 prisma generate만 한 것 — 리뷰 반영으로 .yarnrc.yml·yarn 릴리즈도 키에 추가
워크플로 이름 CI·파일 pr-check.yml 유지 한 것
모든 uses SHA 고정, run: 안 ${{ }} 금지, 모든 잡에 steps 한 것
필수 체크 4개·terraform 불변 한 것
concurrency 그대로 한 것
coverage-report에 actions: read 한 것
merge-coverage.spec(병합 = 단일 실행, 조각 하나 실패, 샤드 누락 실패, 테스트 실패 시에도 report.json) 한 것
deploy-workflow.spec에 집계 잡 규칙 한 것
PR 위에서 반증 후 되돌림 한 것
합친 커버리지 = 단일 실행 값 확인 한 것
istanbul 패키지 3개 devDependencies 명시 한 것 — 타입 3개도 함께
README CI 절·가이드 §9 갱신 한 것
CLAUDE.md의 같은 문장 갱신 안 한 것 — CLAUDE.md는 gitignore 대상이라 이 PR에 들어갈 수 없습니다. 문구 반영은 따로 진행합니다
v8 미적용·lint 캐시 미적용(조사로 바뀐 전제) 한 것(적용하지 않음)
임계 상향 97/92/97/98, 합친 샤드 수치로 확인 후 확정 한 것

check 한 잡이 설치→정적 검사→인프라 spec→전체 jest→빌드를 차례로 돌고, coverage-report가 jest를 한 번 더 돌림.
coverage-report의 기준 비교는 base에서 npm install이 실패해 head 결과를 기준으로 읽어 차이가 늘 0이었음(PR마다 약 70초 낭비).

- pr-check.yml을 static·scripts·build·test(2샤드, fail-fast 끔)·coverage-report·check로 분리
  - test: --coverage 유지(LanguageService 모드 선택), 샤드별 임계는 '--coverageThreshold={}'로 끔, --json 결과를 아티팩트(1일)로
  - coverage-report: 샤드 결과를 scripts/merge-coverage.ts로 병합 → 테스트 실패·샤드 누락·임계 미달이면 실패(report.json은 먼저 씀), 임계는 jest.config.js
    - Codecov는 합친 lcov 1회(backend-lcov 그대로)
    - push면 report.json을 기준 아티팩트(90일, continue-on-error)로, PR이면 이 레포 base 브랜치의 성공한 push 실행에서만 기준을 받음(base 커밋 우선 → 브랜치 최근 → 없으면 head 복사)
    - 액션은 coverage-file·base-coverage-file로 테스트 재실행 없이 댓글만, 기준 경로 고정(댓글 중복 방지)
  - check: if: always() + needs 결과가 전부 success인지 jq로 직접 검사(skipped·cancelled도 실패)
  - actions: read는 coverage-report에만
  - node_modules 캐시(yarn.lock·package.json·OS·arch·node 버전 키), 적중이면 설치 대신 prisma generate
  - image·pr-title·concurrency·워크플로 이름 CI는 그대로
- istanbul-lib-coverage·-report·istanbul-reports(+@types)를 lockfile의 기존 버전 그대로 devDependencies에 명시
- README CI 절·가이드 §9·jest.config.js 주석을 새 구조로

테스트
- merge-coverage.spec(신규): 두 조각 병합 = 단일 실행 수치, 반증으로 조각 하나·샤드 누락·테스트 실패(report.json은 남음)·coverageMap 없음·지원 안 하는 임계 형식, CLI 종료 코드 0/1/2
- deploy-workflow.spec: check 집계 스크립트를 실제 bash로 돌려 success/failure/skipped/cancelled/빈 needs 전수, coverage-report needs·if, 샤드 수 일치, 캐시 키·적중 경로, actions 권한 범위, 기준 받기 스크립트를 gh 대역으로 돌려 순서·중복 제거·head 폴백
- 반증: 샤드 수 검사·테스트 실패 검사 제거, pct 비교 방향, jq success 조건, 중복 제거, coverage-report if, head 폴백을 각각 지우면 실패 확인
- 실제 coverage-final.json(500파일)을 파일 단위 두 조각으로 나눠 병합 → 10050/10267·3773/4087·2019/2075·9143/9283으로 원본과 일치, 한 조각만이면 임계 미달 exit 1
@coderabbitai

coderabbitai Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Repository: CaQuick/caquick-be/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 142e6798-d5fa-4019-93fd-bf89dc34cb06

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Oct 4, 2026

Copy link
Copy Markdown

🧹 knip — dead-code 리포트

Unused exported types (1)
전체 리포트
Unused exported types (1)
RateLimitPolicy  type  src/global/rate-limit/index.ts:4:8

청소 후보(오탐 가능) · 기준 docs/guide/architecture-conventions.md

@github-actions

github-actions Bot commented Oct 4, 2026

Copy link
Copy Markdown

🩺 NestJS Doctor — 90/100 (Excellent)

진단 475건 (error 12).

Category error warning info
architecture 1 1 42
correctness 0 260 0
performance 0 36 28
schema 0 0 75
security 11 21 0
architecture / security 상위 항목
  • error architecture/architecture/no-manual-instantiation: Manual instantiation of 'OutboxRepository' detected. Use dependency injection instead.
  • info architecture/architecture/no-barrel-export-internals: Barrel file re-exports internal type 'IAuditLogRepository'.
  • warning security/security/no-exposed-env-vars: Direct 'process.env.NODE_ENV' access in 'AuthController'. Use ConfigService instead.
  • warning security/security/require-guards-on-endpoints: Endpoint 'start' has no @UseGuards() at class or method level.
  • warning security/security/require-guards-on-endpoints: Endpoint 'callback' has no @UseGuards() at class or method level.
  • warning security/security/require-guards-on-endpoints: Endpoint 'refresh' has no @UseGuards() at class or method level.
  • warning security/security/require-guards-on-endpoints: Endpoint 'logout' has no @UseGuards() at class or method level.
  • warning security/security/require-guards-on-endpoints: Endpoint 'sellerLogin' has no @UseGuards() at class or method level.
  • warning security/security/require-guards-on-endpoints: Endpoint 'sellerRefresh' has no @UseGuards() at class or method level.
  • warning security/security/require-guards-on-endpoints: Endpoint 'sellerLogout' has no @UseGuards() at class or method level.
  • warning security/security/require-guards-on-endpoints: Endpoint 'devIssueToken' has no @UseGuards() at class or method level.
  • warning security/security/require-guards-on-endpoints: Endpoint 'adminLogin' has no @UseGuards() at class or method level.
  • warning security/security/require-guards-on-endpoints: Endpoint 'adminRefresh' has no @UseGuards() at class or method level.
  • warning security/security/require-guards-on-endpoints: Endpoint 'adminLogout' has no @UseGuards() at class or method level.
  • warning security/security/require-guards-on-endpoints: Endpoint 'getJwks' has no @UseGuards() at class or method level.

오탐 포함 가능 · 기준 docs/guide/architecture-conventions.md

@github-actions

github-actions Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

Coverage report

St.❔
Category Percentage Covered / Total
🟢 Statements 97.91% 10063/10278
🟢 Branches 92.43% 3797/4108
🟢 Functions 97.45% 2026/2079
🟢 Lines 98.51% 9154/9292

Test suite run success

3782 tests passing in 357 suites.

Report generated by 🧪jest coverage report action from 2b150c1

@codecov

codecov Bot commented Oct 4, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 570e8cbe05

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .github/workflows/pr-check.yml Outdated
path: |
node_modules
.yarn/install-state.gz
key: node-modules-${{ runner.os }}-${{ runner.arch }}-node${{ steps.node.outputs.node-version }}-${{ hashFiles('yarn.lock', 'package.json') }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Include Yarn configuration in the cache key

When a PR changes .yarnrc.yml or the repository’s Yarn release without modifying package.json or yarn.lock, this key remains unchanged, so CI restores the old node_modules tree and skips yarn install --immutable. Since .yarnrc.yml currently controls both nodeLinker and yarnPath, such a change can be tested against a stale installation or fail solely because the new layout was never installed; hash the Yarn configuration and release files into the key as well.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

반영: 4d05aa0 — 캐시 키 hashFiles에 .yarnrc.yml·.yarn/releases/** 추가(5개 잡), deploy-workflow.spec이 키 구성 고정. .yarn/patches는 lockfile의 patch 해시로 이미 반영.

- 첫 실행 로그에서 codecov-action이 CC_TOKEN 등을 GITHUB_ENV로 내보내 뒤 단계(기준 받기 gh 스크립트·서드파티 댓글 액션) env에 남는 것 확인
  - 예전엔 Codecov(check)와 댓글 액션(coverage-report)이 다른 잡이라 같은 env에 없었음 → Codecov를 coverage-report 마지막으로 옮겨 그대로 분리
- deploy-workflow.spec의 run 블록 실행 셸을 bash -eo pipefail → bash -e로(shell 미지정 run의 실제 셸, 로그의 "/usr/bin/bash -e {0}")
  - 집계·기준 받기 스크립트는 pipefail 유무와 무관하게 같은 결과(마지막 명령의 종료 코드로 판정)

테스트
- deploy-workflow.spec: Codecov 단계가 기준 받기·댓글 액션보다 뒤인지 고정
- 한국어 README와 같게: pr-check.yml 역할 문구, CI 잡 구성 절 추가, 전체 회귀·임계 담당 문장
- 96/86/92/96 → 97/92/97/98(실측 정수 내림, 사용자 결정)
- 근거: 이 PR 첫 CI(run 37221170062)의 샤드 병합 수치 97.90/92.42/97.45/98.51
  - 10063/10278·3797/4108·2026/2079·9154/9292 — 같은 트리를 단일 실행한 #492 리포트와 개수까지 일치
- 임계는 jest.config.js 한 곳(로컬 test:cov는 jest가, CI는 coverage-report의 merge-coverage가 같은 값으로 검사)
- README·README.en·가이드 §9·jest.scripts.config.js 주석의 수치 갱신
- CI(GITHUB_ACTIONS=true)에서만 실패하는 spec 1건 — test 샤드 실패 시 coverage-report·check가 failure로 끝나는지 PR CI에서 확인하고 바로 되돌린다

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: adadfc972d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/common/ci-falsification.spec.ts Outdated
// 반증: 집계 잡 확인용 — 되돌림. CI(GITHUB_ACTIONS=true)에서만 실패해 test 샤드·coverage-report·check가 빨간색이 되는지 본다
describe('반증: 집계 잡 확인용 — 되돌림', () => {
it('CI에서는 일부러 실패한다', () => {
expect(process.env.GITHUB_ACTIONS).toBeUndefined();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Remove the CI-only failing falsification test

When the test shards run in GitHub Actions, GITHUB_ACTIONS is always set to true, so the shard containing this spec necessarily fails. The workflow then propagates that failure through coverage-report and the required check job, preventing every PR and push from receiving a successful CI result; revert this temporary falsification spec before merging.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

반영(의도된 임시 커밋): e8499c1에서 되돌림 — 집계 잡 반증용(run 37222298720에서 test (1)·coverage-report·check failure 확인). 최종 head 4d05aa0에는 없음.

This reverts commit adadfc9.

- 반증 실행(run 37222298720) 결과: test (1) failure → coverage-report failure(merge-coverage가 테스트 실패로 exit 1, 댓글은 실패 내역으로 갱신) → check failure(skipped 아님)
- 리뷰 지적(Codex): .yarnrc.yml(nodeLinker·yarnPath)이나 .yarn/releases만 바뀌면 키가 같아 낡은 node_modules를 복원하고 설치를 건너뜀
- hashFiles에 '.yarnrc.yml', '.yarn/releases/**' 추가(5개 잡 동일), README·README.en 문구 갱신
- .yarn/patches는 lockfile의 patch 해시로 이미 키에 반영

테스트
- deploy-workflow.spec: 캐시 키에 yarn 설정·릴리즈가 들어가는지 고정

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4d05aa0d8a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

# 통과시킨다 — 그래서 if: always()로 늘 돌고 선행 결과가 전부 success인지 직접 본다. 건너뜀·취소도 실패다.
check:
if: always()
needs: [static, scripts, build, test, coverage-report]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Exclude read-only PR reporting failures from the required check

For fork-originated and Dependabot PRs, GitHub supplies a read-only GITHUB_TOKEN, and the coverage action documents that attempting to publish its comment then fails with Resource not accessible by integration (GitHub permissions, action documentation). Because check now requires coverage-report and rejects every result other than success, an otherwise valid external or Dependabot PR cannot satisfy the required check; conditionally omit the write-dependent reporting step for read-only PRs or keep that publishing failure outside the aggregate gate.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

미반영(기록): fork PR의 읽기 전용 토큰으로 댓글 단계가 실패하는 것은 이 PR 이전에도 같았음(coverage-report가 이미 필수 체크). Dependabot은 잡 단위 permissions가 적용돼 성공(run 37133178668, #478) — 해당 부분은 성립하지 않음.

- 샤드 아티팩트 보존 1일 → 7일: 하루 뒤 coverage-report만 재실행하면 샤드 0개로 실패하던 것
- check(집계)는 토큰을 쓰지 않아 permissions: {}
- 가이드 §9·pre-push-test-plan 주석의 "CI check가 돌린다"를 static·scripts·test 잡 기준으로
@chanwoo7
chanwoo7 merged commit cb22b65 into develop Oct 4, 2026
16 checks passed
@chanwoo7
chanwoo7 deleted the ci/parallel-shards branch October 4, 2026 18:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant