ci: 테스트 샤딩·잡 병렬화·커버리지 리포트 재사용으로 CI 단축 - #68
Conversation
- check 한 잡 직렬(lint → typecheck → knip → test:cov → build) + coverage-report가 테스트를 한 번 더 돌리던 구조를 잡 분리 - lint / static(codegen:check → knip → build) / test 3샤드 / coverage-report / check 집계 - typecheck 단계 제거: build가 같은 tsc -b를 돌림 - codegen:check를 CI에 추가: 문서는 CI가 신선도를 본다고 했지만 실제로는 로컬 validate만 검사했음 - test: vitest --shard=i/3 + blob 리포터(blob-report/, 기본 .vitest/는 숨김이라 업로드에서 빠짐), 샤드별 임계는 CLI로 0 - coverage-report: blob 병합(--merge-reports --coverage)으로 vitest.config.ts 임계를 합친 결과에 적용 - always()로 돌고 샤드 결과가 success가 아니면 실패: 건너뜀이 필수 체크 통과로 잡히지 않게 - blob 개수가 SHARD_COUNT와 다르면 실패(부분 커버리지 방지) - develop·main push는 coverage-summary 아티팩트(보존 90일, continue-on-error) 업로드 - PR은 base 브랜치의 성공한 push 실행(같은 레포, base 커밋 우선)에서 받아 json-summary-compare-path로 비교. 없으면 비교 생략 - check: if: always(), needs 결과가 전부 success인지 jq로 검사(skipped·cancelled도 실패) - .gitignore에 .vitest/·blob-report/, 가이드·README의 CI·validate 설명 갱신
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configuration
You can disable this status message by setting the Use the checkbox below for a quick retry:
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. Comment |
Coverage Report
File CoverageNo changed files found. |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f0cf86b2c8
ℹ️ 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".
| run_id=$(gh api "repos/$REPO/actions/workflows/pr-check.yml/runs?branch=$BASE_REF&event=push&status=success&per_page=50" \ | ||
| | jq -r --arg repo "$REPO" --arg ref "$BASE_REF" --arg sha "$BASE_SHA" ' | ||
| [.workflow_runs[] | select(.event == "push" and .head_branch == $ref and .head_repository.full_name == $repo)] | ||
| | (map(select(.head_sha == $sha)) + .)[0].id // empty') |
There was a problem hiding this comment.
Retry older runs when the selected coverage artifact is missing
When the exact-base or newest successful run has no coverage-summary artifact—for example because the upload is explicitly continue-on-error or the artifact expired—this selects that run before checking artifact availability. The subsequent single download failure merely disables comparison, even if another run among the 50 returned here has a usable artifact, so PR coverage deltas silently disappear; iterate candidate runs until an artifact downloads successfully.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
반영: 기준 후보를 base 커밋 실행 우선·최신 순으로 최대 5개, 아티팩트가 받아질 때까지 시도.
- statements 80→95, branches 70→88, functions 80→94, lines 80→96 - 근거: PR CI 37220367732의 샤드 합산 95.54/88.07/94.29/96.07 = 같은 트리 단일 실행(로컬 validate)과 일치 - 임계는 리터럴 유지(리포트 액션이 vitest.config.ts에서 정규식으로 읽음) - 결정 기록 D16 추가, D7 임계는 대체됨 표시
- CI(GITHUB_ACTIONS)에서만 실패하는 테스트 1건: 샤드 실패 시 coverage-report·check가 실패로 끝나는지(건너뜀·성공 아님) 확인용 - 로컬 pre-push는 통과(훅 우회 없이 push) - 확인 뒤 revert
- 22fbb0e 되돌림. CI 37220956009에서 test (1/3)·coverage-report·check 모두 failure 확인
- blob 업로드 overwrite: 실패한 샤드도 올리므로 재실행 때 같은 이름 충돌로 빨간불이 이어지던 것(main이면 배포 막힘), 보존 1일 → 7일
- 기준 조회·PR 댓글을 !cancelled() + 요약 파일 존재 조건으로: 임계 미달로 병합이 실패해도 댓글을 갱신(이전 초록 댓글이 남지 않게)
- 기준 아티팩트: base 커밋 실행 우선, 최신 순으로 최대 5개 실행을 다운로드될 때까지 시도(Codex P2)
- check(집계) permissions: {}, pre-push 훅 주석을 새 CI 구조에 맞게
배경
check한 잡이 lint → typecheck → knip → test:cov → build를 직렬로 돌렸고, test:cov가 그중 약 65%였습니다.coverage-report는 같은 테스트를 처음부터 한 번 더 돌렸습니다.codegen:check가 없었습니다(로컬 validate만 검사).jsonSummaryComparePath: null).변경
CI워크플로(pr-check.yml)를 잡 단위로 나눠 병렬로 돌립니다. 워크플로 이름CI와 필수 체크 이름(check·coverage-report·pr-title)은 그대로입니다.lintstatic:codegen:check(신규) →knip→build && test -f dist/index.html.build가tsc -b를 돌리므로 별도 typecheck 단계는 뺐습니다.test3샤드:vitest run --coverage --shard=i/3+ blob 리포터(blob-report/, 보존 1일). 샤드별 임계는 CLI로 0coverage-report: blob을--merge-reports --coverage로 합쳐vitest.config.ts임계를 합친 결과에 적용 → Codecov → PR 댓글check:if: always(), needs 결과가 전부success인지 검사(건너뜀·취소도 실패)coverage-report는always()로 돌고, 샤드 결과가success가 아니면 첫 단계에서 실패합니다. 필수 체크가 건너뜀(skipped)으로 통과 처리되지 않게 하기 위해서입니다.coverage-summary아티팩트(요약·final JSON, 보존 90일). 업로드 실패가 배포를 막지 않게continue-on-errorjson-summary-compare-path를 넘깁니다.actions: read는coverage-report잡에만actions/upload-artifactv7.0.1,actions/download-artifactv8.0.1.gitignore에.vitest/·blob-report/, 가이드 §7·§8과 README의 validate 설명 갱신검증
새 구조에서 CI가 통과했고, 필수 체크 완료까지 약 3분에서 1분 30초~1분 50초로 줄었습니다.
Analyze(65~78초)는 그보다 먼저 끝났습니다.합친 커버리지가 단일 실행과 같았습니다.
test:cov): 95.54 / 88.07 / 94.29 / 96.07부분 커버리지는 임계에서 걸립니다. CI 샤드 blob을 받아 로컬에서 합쳐 봤습니다.
vitest.config.ts임계를 적용하는 것도 확인했습니다.반증: CI에서만 실패하는 테스트를 잠깐 올렸다가(22fbb0e) 되돌렸습니다(8f1fa0a).
test (1/3)failure →coverage-reportfailure("test 샤드 결과: failure") →checkfailurePR 커버리지 댓글은 1개만 달리고, push마다 같은 댓글이 갱신됩니다.
base 비교의 대체 경로가 동작했습니다.
jsonSummaryComparePath: null)actionlint통과(pr-check.yml), 새 액션은 전부 40자리 SHA 고정리뷰 반영
overwrite: true를 추가했습니다. 실패한 샤드도 결과를 올리므로 재실행 때 같은 이름이 충돌해 빨간불이 이어졌습니다(main이면 배포가 막힘). 보존 기간도 1일에서 7일로 늘렸습니다.!cancelled()+ 요약 파일이 있을 때로 바꿨습니다. 임계 미달로 병합이 실패해도 댓글이 갱신되어, 이전의 초록 댓글이 남지 않습니다.check에permissions: {}를 두고, pre-push 훅 주석을 새 구조에 맞게 고쳤습니다.플랜 대조
.gitignore에.vitest/·blob-report/CI유지