GitHub CI는 성공했는데 커버리지 보고서가 없다면
테스트 결과 파일도 생기고 업로드 단계도 초록색인데 PR에는 커버리지 보고서가 없다. 성공 표시까지 떴다면 보고서는 어디로 간 걸까?

- GitHub Code Quality의 업로드 단계는 PR이 없는 새 브랜치에서 성공으로 끝나도 보고서를 보내지 않는다.
- PR을 열자마자 실행하려면 pull_request 이벤트가 필요하며, push 전용이면 다음 push를 기다린다.
- 업로드 단계의 notice와 요약을 읽어 생략인지 실제 업로드인지 구별해야 한다.
업로드 단계의 성공은 보고서 전송 완료와 다를 수 있다
기본 브랜치가 아닌 곳에 push했고 아직 열린 PR이 없다면, 커버리지 업로드 생략이 정상 동작일 수 있다. GitHub는 10월 1일 변경으로 이 상황에서 upload-code-coverage가 CI를 실패시키지 않도록 했다. 대신 Actions notice와 단계 요약에 생략 이유를 남긴다.
대상은 GitHub Code Quality의 커버리지 업로드다. 워크플로에 actions/upload-code-coverage가 있는지부터 확인한다. Codecov나 Coveralls를 쓰는 작업에 이 변경을 그대로 적용할 수는 없다.
테스트 실행과 결과 전송도 나눠 읽어야 한다. 같은 job에서 먼저 테스트를 돌렸다면 테스트 결과 파일은 만들어졌어도 이후 업로드만 생략될 수 있다. 따라서 보고서가 없다는 사실만으로 테스트가 실행되지 않았다고 판단하면 안 된다.
push만 감지한다면 PR을 여는 것으로는 부족하다
PR 생성은 push와 다른 이벤트다. 공식 워크플로 안내에 따르면 push 전용 구성은 PR을 연 뒤 해당 브랜치에 다시 push해야 커버리지를 올린다. 앞서 생략된 실행이 PR 생성 순간 자동으로 되살아나는 구조가 아니다.
| push 전용 워크플로의 상황 | 업로드 동작 |
|---|---|
| 새 브랜치에 push, 열린 PR 없음 | 성공으로 끝내며 업로드를 생략한다. |
| 그 브랜치로 PR만 생성 | push 이벤트가 없어 새 실행이 시작되지 않는다. |
| 열린 PR이 있는 브랜치에 다음 push | 연결할 PR을 찾고 업로드한다. |
| 기본 브랜치에 push | 기본 브랜치용 업로드를 수행한다. |
실제 업로드에는 필요한 토큰 권한과 Cobertura XML 보고서도 갖춰야 한다.
PR 생성부터 필요하다면 이벤트를 나눠 잡는다
PR을 열 때 커버리지를 받고 싶다면 pull_request를 사용한다. 공식 문서는 PR 이벤트와 기본 브랜치 push를 함께 쓰는 구성을 제시한다. 다음은 완전한 워크플로가 아니라 기존 파일의 이벤트 부분 예시다.
on:
pull_request:
push:
branches: [main] main은 실제 기본 브랜치 이름으로 바꾼다. Code Quality 설정 문서는 기본 브랜치의 커버리지를 PR 비교의 기준으로 사용하므로 두 경로의 보고서가 필요하다고 설명한다. 기존 테스트 생성·업로드 단계까지 이 네 줄로 대체해서는 안 된다.
모든 브랜치의 push와 PR 이벤트를 동시에 켜면 같은 PR 커밋으로 두 번 실행될 수 있다. 새 브랜치에서도 테스트를 매번 돌려야 하는 팀은 테스트 실행 조건과 업로드 조건을 따로 결정하는 편이 맞다. 업로드를 줄이려고 job 전체를 생략하면 그 안의 테스트도 함께 빠진다.
열린 PR이 있다면 권한과 다른 생략 사유를 확인한다
action 문서에 따르면 업로드에는 code-quality: write가 필요하다. push 이벤트에서 PR을 찾는 경로에는 pull-requests: read와 GitHub CLI인 gh도 필요하다. 자체 runner에서는 도구가 설치돼 있는지 살펴야 한다.
fork에서 온 PR이나 merge queue 실행도 생략 대상이다. 같은 브랜치에 PR이 여러 개라면 기본 브랜치를 대상으로 하는 PR을 우선하며, 그 대상을 하나로 정하지 못하면 경고와 함께 생략한다. fail-on-error: false를 설정한 경우에는 업로드 오류가 있어도 단계가 성공으로 끝날 수 있다.
이 기능의 적용 대상은 GitHub Team과 Enterprise Cloud이며, 이번 변경은 Enterprise Server에 적용되지 않는다. 보고서가 없다면 action 이름 → 실행 이벤트 → 열린 PR → notice·오류 메시지 순서로 좁혀 보는 것이 좋다. 초록 체크만 보고 커버리지 데이터까지 저장됐다고 판단하지 않는 것이 출발점이다.