들어가며
테스트 코드를 작성하며 커버리지 분석 결과를 시각화하기 위해 Codecov를 도입하였다.
Github Repository와 사이트를 연동하여 사이트 내에서 결과를 확인하는 것은 쉽게 했지만, 다른 프로젝트들처럼 PR에 Codecov가 Comment를 달아주는 것은 동작하지 않았다.
삽질 과정을 통해 현재 사용 중인 Github Actions 스크립트는 push 이벤트일 때만 trigger되고 있고, PR에 Comment가 달리기 위해서는 pull_request 이벤트를 추가해야 함을 알 수 있었다.
기존 Github Actions 스크립트는 CI와 CD가 하나의 파일에 있기 때문에 CI와 CD 스크립트를 분리해야 한다.
하지만 CI 스크립트에서 pull_request 이벤트일 때 Secrets 정보를 읽어오지 못해 Actions가 실패하게 되었다.
Actions에서 Secrets 정보를 가져오지 못하는 이유
공식 Docs에 따르면 Forked Repository로부터 trigger된 workflow는 secrets에 접근할 권한이 없다고 한다.
Secrets are not passed to workflows that are triggered by a pull request from a fork.
현재 진행 중인 프로젝트에서는 아래 사진처럼 Fork를 활용한 방식으로 협업을 진행하고 있기 때문에 pull_request 이벤트가 trigger될 때 secrets을 읽지 못해 workflow를 실행시킬 수 없다.
해결법 1) pull_request_target 이벤트를 사용한다.
구글링을 통해 같은 사례를 겪은 사람들의 질문글들을 정독하며, pull_request_target이라는 이벤트가 있다는 것을 알게 되었다.
pull_request_target은 fork pull request의 제안을 해결하기 위해 2020년 8월 추가된 이벤트이다.
pull_request vs pull_request_target
pull_request 이벤트는 PR로 올라온 커밋에서 실행되는 반면, pull_request_target은 풀 리퀘스트가 머지 대상으로 지정한 base를 기준으로 실행된다.
그렇기 때문에 Collaborator가 아닌 외부인이 PR을 날리더라도 저장소에 쓰기 권한과 시크릿 접근 권한을 가지게 된다.
정확한 동작 방식의 이해 없이 사용하면 보안에 매우 취약하기 때문에 조심해서 사용해야 한다.
on:
pull_request_target:
types: [labeled]
jobs:
build:
name: Build and test
runs-on: ubuntu-latest
if: contains(github.event.pull_request.labels.*.name, 'safe to test')
위와 같은 스크립트를 추가하여 특정 라벨이 추가되었을 때만 코드를 실행하는 것도 가능하지만, 코드 리뷰가 필수적이며 악의적인 코드를 실수로 보지 못하고 실행할 가능성도 있으므로 완전무결한 방식이 아니다.
나도 처음에는 pull_request_target으로 스크립트를 수정할까 했지만 아직 그 원리에 대해 100% 파악했다고 확신할 수 없고😅 pull_request_target으로 완전히 안전한 방법을 구축하는 것은 어렵다고 하는 것 같아 다른 방법을 찾아보기로 했다.
해결법 2) 협업 방식을 바꾼다
이제까지는 항상 원본 Repository를 Fork를 활용하는 방식으로 진행했기 때문에 이것이 정답이라고 생각했다.
하지만 나의 제 0의 멘토님(^^)과의 토론을 통해 Fork를 활용한 방식이 정석적이긴 하지만, '오픈소스 프로젝트가 아니라면 꼭 Fork를 활용한 방식으로 안해도 되지 않는가?'라고 결론을 낼 수 있었다.
실무에서도 오픈소스 프로젝트가 아니라면 원본 Repository에 바로 push(그 대신 브랜치는 feature로)하고 그 안에서 브랜치 간 PR을 올리는 방식을 활용하고 있다고 했다.
그렇기 때문에 우리 프로젝트에서도 Git 협업 방식을 Fork 없이 원본 repository의 branch에 push 후 PR로 머지 방식으로 진행하기로 결정하였다 !!!
이제 PR Comment도 잘 달린다 ^ㅅ^
추가적인 Secrets 보안
하지만 우리 프로젝트는 public repository이고, 그렇기 때문에 외부인이 우리의 repository에 PR을 업로드하는 것이 가능하다. 만약의 상황을 대비하기 위해 branch protection rule을 통해 프로젝트 참여 인원만 push가 가능하도록 설정하였다.
마치며
- Github Actions 스크립트를 프로젝트에서 활용하는 것은 이번이 두번째인데 이제까지는 Secrets의 보안에 대해 생각해본 적이 없었다. Github에 key값들을 파일로 올리는 것 외에도 Actions도 보안 취약점 대상이 될 수 있음에 경각심을 가질 수 있었다.
- 처음에는 'forked repository에서도 secrets에 접근 가능하도록 하겠노라...😠'에 집중했었다. 하지만 우리의 본질적인 목표는 그것이 아닌, CI 스크립트에서 secrets에 접근 가능하도록 하는 것이다. 모든 문제를 기술적으로 해결하려고 집착할 필요가 없다, 개발 외적인 방법으로도 개발 상 이슈를 해결할 수 있다는 것을 배울 수 있었다.