[Github Actions] PR 을 open하면 돌아가는 워크플로우는 PR 브랜치 기준이 아니다 !
Web/배포

[Github Actions] PR 을 open하면 돌아가는 워크플로우는 PR 브랜치 기준이 아니다 !

 

보통 많은 분들이 PR을 열어놓고 커밋이 추가될때마다 자동으로 테스트를 돌리거나 Sonar 를 돌리는 경우가 많습니다.

 

그리고 무의식중으로 아직 머지를 안했으니 내가 방금 업데이트한 브랜치 기준으로 워크플로우가 돌겠구나 생각하게 됩니다.

 

 

그런데 혹시 깃헙액션이 돌아갈때, PR을 날리는 브랜치 기준이 아니라 merge 된 브랜치를 가정하고 돌아가는 것을 알고 계셨나요?

이렇게 PR을 날리고 있다고 가정하면 main + feature branch 를 머지했다고 가정한 상태로 액션이 돌아갑니다.

 

 

다음과 같이 Checkout 액션을 돌리고,

# <https://github.com/actions/checkout>
- name: Checkout
  uses: actions/checkout@v4
  with:
		...

 

 

깃헙 액션이 돌아가는 스크립트를 살펴보면, Checkout 단계에서 /merge 가 붙은 브랜치로 switching 하는 것을 볼 수 있습니다.

(git switch vs git checkout 에 대한 설명은 아래 글 참고)

https://graphite.dev/guides/git-checkout-vs-switch

 

 

깃헙 문서의 워크플로우 트리거 이벤트 부분도 확인해 보면, pull_request 이벤트에서는 github_sha, github_ref 를 기본적으로 둘다 merge된 기준으로 제공하고 있습니다.

https://docs.github.com/ko/enterprise-cloud@latest/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#pull_request

 

actions 의 checkout 레포의 Readme 문서를 확인해보겠습니다.

체크아웃할 분기, 태그 또는 SHA입니다.
저장소를 확인할 때 워크플로를 트리거한 경우 기본값은 해당 이벤트에 대한 refence 또는 SHA입니다.
그렇지 않으면 기본 분기를 사용합니다.

해당 이벤트에 대한 refence(ref) 또는 sha 를 사용한다고 되어있습니다.

 

결론적으로 pull_request 이벤트 트리거를 사용했고, pull_request 트리거는 기본적으로 병합상태의 sha 혹은 ref를 제공하므로 병합상태를 기준으로 워크플로우가 동작하는 것을 확인하였습니다.

 

 

난 PR을 생성한 브랜치 기준으로 워크플로우를 실행하고 싶은데?

헤드 브랜치에 대한 커밋을 얻으려면 github.event.pull_request.head.sha 를 사용하라고 가이드합니다.

이 이벤트의 GITHUB_SHA는 풀 요청 병합 분기의 마지막 병합 커밋입니다. 풀 요청의 헤드 브랜치에 대한 마지막 커밋의 커밋 ID를 얻으려면 대신 github.event.pull_request.head.sha를 사용하세요.

https://github.com/actions/checkout

 

 

그런데 꼭 PR 브랜치 기준으로 워크플로우를 실행할 이유가 있을까?

이미 누군가가 깃헙에 이슈를 달았다.

싫어요가 2개나.. ㅠ
Github 개발자의 답변

https://github.com/actions/checkout/issues/504

 

번역)

질문: 이제 풀 요청 브랜치 헤드를 확인하는 것보다 이것이 기본값이라는 이점이 무엇인지 궁금합니다. 그렇게 바꾸면 되지 않을까요?

 

답변: 생성된 테스트 병합 커밋을 사용하면 기본 분기(마스터/메인)에 병합되는 컨텍스트에서 PR 변경 사항을 테스트하고 실제 병합 전에 해당 문제를 미리 포착할 수 있습니다.(기본 분기에 더 이상 업데이트가 없다고 가정).

 

납득.. PR을 날린다는건 병합할 예정이라는 뜻이고 병합 후의 발생할 이슈사항을 체크하는게 우선이 맞다고 생각이 든다.

 

만약 충돌이 있는 브랜치라면?

워크플로우가 돌아가지 않는다.

 

공식문서에서 병합충돌을 먼저 해결해야 워크플로우가 실행된다고 설명합니다.

번역) 풀 요청에 병합 충돌이 있는 경우 워크플로는 pull_request 활동에서 실행되지 않습니다. 병합 충돌을 먼저 해결해야 합니다.

 

이와 관련해 최근까지도 엄청 활발하게 토론중인 이슈 링크를 첨부합니다.. ㄷㄷ

‘오류이므로 개선해야한다’ VS ‘이게맞다’ 로 의견이 갈리네요

https://github.com/orgs/community/discussions/26304

 

 

번외로.. 해당 이슈를 만난 이유

팀 동료분이 로컬에서 테스트가 성공했지만, PR에서 돌아가는 CI는 자꾸 통과하지 않는다.. 라고 하셔서 같이 살펴봤습니다.

 

보통 KST, UTC 문제거나 gradle test가 달라서 실패하는 경우가 대부분인데 이번에는 둘다 아니었습니다.

혹시나 해서 로컬에서 머지후에 테스트를 돌렸더니 머지하면서 import 문이 하나 빠지고, 의존성이 없어 컴파일 자체가 실패하고 있었습니다.

 

원래 jacoco 테스트 실패 리포트가 만들어져야하는데 자꾸 안나오는 이유도 ‘컴파일 자체가 안되어서’ 였습니다.

이럴땐 컴파일 자체를 안된걸 의심해볼 필요가 있다는 걸 또 한번 깨달았습니다.

 

어쨌든, 머지 후에 테스트가 동일하게 실패하고 혹시 PR이 머지 기준으로 돌아가는것 아닐까? 하고 로그를 살펴보며 발견하게된 이슈였습니다.