Github Action으로 CI 파이프라인 구성하기

dev_qorh·2022년 9월 7일
2

CatchCatch

목록 보기
11/18

대충 프로젝트의 뼈대가 구성된 것 같다. 이제 개발의 프로세스를 확립하여 기존 코드 작성에서는 ci가 수행되도록 하고, 어느 정도의 개발 이후 cd를 추후에 고려해야 할 것이다.

그래서, 오늘은 github action으로 ci 파이프라인을 고려해보고자 한다. 프로젝트에 ci 파이프라인을 적용하기 위해서 ci에 대한 정확한 뜻과 구성요소 및 주의점, 원칙 등을 참고하여 적용하기로 했다. 이곳을 참고 하였다.

사전 준비

기본 원칙 4가지

  1. 모든 소스 코드가 살아있고(현재 실행되고) 어느 누구든 현재의 소스를 접근할 수 있는 단일 지점을 유지할 것

    • '현재 실행되는' 시점은 배포환경이라고 생각할 수 있겠다. 하지만 배포 환경은 안정적인 버전 상태의 코드만을 유지하기 때문에, 테스트용 환경을 구성하여 개발 시점에서의 소스 코드를 공유할 수 있도록 구성해야 할 것이다.
    • 이는 upstream 저장소에서 develop/main 브런치들을 관리하는 것으로 달성할 수 있을 것으로 생각된다. 가령 각 파트의 개발자는 upstream의 features 이라는 단일 지점에 대해 pull로 최신 버전을 유지하고 본인의 featrues/features-01 브런치를 개발 후 push 하여 github action이라는 ci 툴을 사용하여 features 브런치에 대한 테스팅을 완료하여 버전을 유지할 수 있을 것이다.
  2. 빌드 프로세스를 자동화시켜서 어느 누구든 소스로부터 시스템을 빌드하는 단일 명령어를 사용할 수 있게 할 것

    • 소스코드는 깃허브를 통해 최신으로 유지할 수 있지만, 배포를 위한 빌드 과정이 다를 경우 발생할 수 있는 문제가 있다. 간단하게는 배포 명령어의 옵션이 다를 수 있고, 환경 세팅이 다를 수 있다. ci를 통해 배포를 위한 스크립트 등을 관리하는 것을 포함하는 내용인 것 같다.
    • 우리 프로젝트의 경우 바이너리 실행파일을 만드는 빌드과정이 없다. 그리고 github action을 통해 cd 과정까지 수월하게 이행할 수 있기에 해당 부분은 고려하지 않아도 될 것 같다.
  3. 테스팅을 자동화시켜서 단일 명령어를 통해서 언제든지 시스템에 대한 건전한 테스트 수트를 실행할 수 있게 할 것

    • ci 툴에서는 테스트 패키지를 실행할 수 있는 런타임 환경을 구성할 수 있게 해준다. github action 환경에서, 새로이 작성한 test 스크립트를 실행하여 테스트 한 후 이를 배포하는 과정을 담으면 문제 없을 것으로 보인다.
  4. 누구나 현재 실행 파일을 얻으면 지금까지 최고의 실행파일을 얻었다는 확신을 하게 만들 것

    • 위 내용을 모두 포함해서 신뢰도 높은 ci 환경을 구성하라는 의미인 것 같다. 확실히 ci 런타임 환경에서 테스트 하는 것이 정확하게 수행되어야 하고, 각 동작이 확실히 이행되어 배포로의 과정이 무리없게 진행되도록 신경쓰도록 하자.

그리고 글에서는 형상 항목과 배포 항목을 잘 구분하여 관리될 수 있도록 해야한다는 점과, 테스트 자동화를 위해 테스트 ci 프로세스를 따로 두는 등의 대안을 고려하라는 것, sw 품질 관리 체계를 구축하는 것에 ci의 역할 등을 중요하게 짚어주었다.

Github Action 사용해보기

ci의 의미와 원칙에 따른 적용 시나리오 등을 고려해보았으니 구현해가면서 항목들을 적용할 수 있도록 해보자. 여기서는 github action을 빠르게 시작해볼 수 있는 튜토리얼을 제공해준다.1. 사용하던 origin 저장소에서 다음 파일을 만든다음 새 브런치로 pull request를 작성한다. 2. 커밋하게 되면 push 이벤트로 workflow가 실행되게 된다. 3. 결과 내용을 저장소의 action 탭으로 가서 확인할 수 있다.

테스트 실행해보기

다른 글에서 단위테스트를 작성해보았다.

CI 시나리오 구성하기

혼자서 구상해보기

이제는 branch 구분하여 ci를 위해 어떤 전략을 가져갈지 고민해야 한다. 우선 확실한 것은, release와 같은 테스트 환경 배포 용도 단계 이전의 branch에선 단위 테스트를 어느정도 실행시키는 것이 좋을 것 같다는 점이다. 여러 명의 개발자가 개발을 한다고 가정해보자.

  1. A라는 사람이 작업하고 있었을 때 B라는 사람이 다른 작업을 시작하기로 한다.
  2. B는 원본 저장소 upstream/develop branch를 pull 해준다.
  3. B가 작업을 진행할 때 A의 작업이 완료되어 upstream/develop에 커밋이 병합되었다.
  4. B의 작업이 완료되어 git fetch 후, upstream/develop를 가져와 conflict를 해결한다.
  5. 본인의 origin/develop 에 코드를 push 하고 upstream/develop에 PR을 넣는다.
  6. 이 때, .github/workflow의 유닛 테스트, 코드 스타일 체크가 통과되어야 하며 테스트 결과를 PR에서 확인할 수 있어야 한다.
  7. B의 PR이 관리자에 의해 upstream/develop에 push 된다.
  8. 어느정도 개발된 시점에서 관리자는 upstrem/release branch에 upstream/develop을 push/PR 시켜 새로운 테스트 환경 배포를 준비한다.
  9. upstream/release에 push/PR이 들어오면, 전체 통합테스트를 수행한다. PR이라면 체크 후 push를 진행한다.
  10. 통합테스트가 수행된 push 이후 테스트 환경으로의 배포를 진행한다. (github action으로)
  11. 테스트 환경에서 QA를 진행한다.
  12. QA 통과 시, 관리자는 upstream/main 으로 push하여 서비스 환경으로 배포를 진행한다.

피드백 수용하기

이렇게 시나리오를 구상하고 오픈채팅에 지혜를 구걸하러 갔다. 시나리오에 대한 피드백을 요청하였더니

아주 큰 착각.. 여러가지 피드백을 받을 수 있었다. 역시 재야의 무림고수 선배님들은 위대하다.
  1. ci 프로세스가 있을 때 저장소를 분리할 이유가 없다는 것이었다.
  2. release branch에 tag를 다는 것으로 main으로 병합 없이 github action을 수행할 수 있다고 한다.
  3. aws 환경에서는 codepipeline+codecommit도 좋은 선택이라고 한다.
  4. 명칭은, dev=>stage=>prod 라고 한다.
  5. 실제 환경에서는 여러 개의 릴리즈가 존재할 수 있다고 한다. (우리 프로젝트의 경우 버전업만을 해갈 예정이라 상관없을 수도)
  6. unit test는 모든 환경에서 수행해야 한다. 직전에 통과했던 테스트가 이후 불통할 수 있다.

그래도 branch를 나누어 사용하는 매커니즘은 얼추 맞아들어서 다행이었다. pr과 push를 사용하는 부분 말이다! 다시금 시나리오를 구상하기 위해 검색을 더 해보고 내용을 정리해보았다.

다시 구상하기

  1. gitflow와 github flow는 다르다. gitflow는 git만으로도 수행 가능하지만, github flow는 pr 기반의 github를 적극적으로 활용하고 있었다. 검색해보니, github flow는 branch를 두개만 갖는 형태로, master가 항상 최신의 버전을 유지한다고 한다.github flow 도식화, 출처
  2. 예전 자문으로 들었던 것처럼 ci/cd(delivery)까지는 자동, cd(deploy)는 수동으로 진행하고 싶었다.
  3. release 및 실제 환경까지의 ci는 개발을 마무리할 때 다시 고려해보기로 한다.

프로세스를 대충 다시 구상해보았다. stage 환경까지는 아직 개발이 멀었으니, dev만 아래와 같이 운용하도록 하자.

  1. 개발자는 리모트에서 dev의 최신 개발 내용을 pull
  2. 개발하려는 티켓의 branch를 dev에서 생성하여 개발 수행
  3. 완료 후 티켓의 branch를 forked 저장소에 push
  4. forked 저장소에서 리모트의 dev로 pr 요청
  5. 단위테스트, 코드 스타일 테스트 진행 (action)z
  6. 관리자의 검토 후 push 진행

Github Action으로 CI 코드 작성

workflow 작성

카카오웹툰 프론트 팀에서 소개한 '카카오웹툰은 GitHub Actions를 어떻게 사용하고 있을까?' 는 참고하기 너무 좋은 내용이어서 가져와봤다.

위 과정 중 4번이 수행될 때 실행될 workflow를 작성하도록 하자. .github/workflows 아래에 yml형태의 이름으로 파일을 작성한다.파일을 작성하고, dev branch에 저장될 수 있도록 커밋을 최신화 해주었다. 그리고 다음과 같이 테스트를 진행했는데..ㅋㅋ,, 문법 틀렸다고 실패를 띄웠다. 확인해보니 맨 윗 줄에 탭이 한칸 띄워져 있었다.ㅋㅋ,, 제대로 수행하면 아래와 같이 pull request에서 수행된 action의 결과도 확인할 수 있다.

slack으로 메세지 받기

테스트 결과를 slack으로 확인할 수 있다. 협업 과정이라면, 새로운 pr을 확인하기 전 테스트 결과에 대한 간략한 내용을 짧게 확인할 수도 있을 것이다. slack을 연결함으로써 프로젝트에 대한 간단한 알림 및 제어가 가능할 것으로 보인다.

우선 slack app을 등록한 다음, 간단하게 app의 기본 설정으로 가서 왼쪽의 incoming webhooks 탭으로 이동하여 새 webhook url을 생성한다.
생성한 webhook url을 github action의 secret으로 등록한다. 추후에 aws secret도 여기서 활용하면 좋다. (배포를 위해서..)

그 다음 위 카카오의 예제를 참고하여 ./github/actions/slack-notify/action.yml을 작성한다. 내용은 다를게 없으니 언급하지 않는다. 작성된 내용을 포함한 브런치를 생성 후 아까와 같은 과정을 진행해본다. 중간에 저 폴더 규칙대로 작성을 안해서 5번이나 새로 pr 넣고 close 한건 안비밀..

아, action 탭에서 실패한 job을 re-run 할 수 있는 기능이 있다

급작스런 에러 발생

이라고 할 뻔 했지만 시행착오가 몇 십번을 넘어가기에 알게 된 것들이 많아 정리를 한번 해보겠다. 특히, pr시 action에서 secret을 쓸 수 없는 상황이 발생한 것을 탐구해보았다.


1. 현재 문제는 public repo를 fork 해서 pr을 넣고 있다는 것인데, 이 상황이 정확하게도 오픈 소스 개발 상황과 동일해서 github secret을 github action workflow에서 사용할 수 없는 문제에 당면했다.
2. 이 문제가 꽤나 커서 여러가지를 찾아보았다. 하지만 명확하게 해결할 수 있는 방법을 그리 많이 제시되지 않은 듯 했다. pull-request-target 과 같은 동작을 사용하면 모든 pr에 대해 secret 접근 권한이 부여되지만(?) 보안이 취약해 진다고도 하더라.
3. 조금 더 생각을 해보니, 그냥 upstream에 branch를 push 하고 pr을 upstream에서 진행하면 되는 것이었다.
4. 난 바본가

성공..

이 정도의 의미 없는 삽질을 오랜만에 해본 듯 하지만... 뭐 나중에 오픈 소스 개발 참여할 때가 있다면 도움될 수도 있을 정보이다. collaborator로 등록을 하면 secret 쓸 수 있으려나. 아무튼,upstream을 바로 사용하게 된다면, 적어도 public이기 때문에 모든 branch가 push에 대한 방어가 되는 지 확인할 수 있어야 했다. 물론 상식적으로... 코드를 가져와 사용만 가능하다는 public의 의미이지 그 변조를 할 수 있다는 의미는 아닐테니, 그리고 clone 등으로 코드를 가져와도 collaborator 등의 권한이 없는 유저는 repo의 어느 변조 동작도 할 수 없을 것이다.

repo의 설정 중 찾은 건데, 맨 아래는 contributor가 등록된 workflow를 실행할 수 있는지에 대한 내용이다. 만약 우리 repo를 fork해서 누군가가 develop에 pr을 던진다면, 방금 내가 위에서 경험한 상황을 그대로 겪을 것이다. 테스트도 당하는 것이 싫으니 맨 아래 옵션으로 넣어두었다. 아, 참고로 맨 위의 옵션도 잠깐 바꿨다가 모든 action을 허용하도록 했다.. ㅎㅎ,,
드디어 나는 잘 수 있게 되었다.
그래도 나름 값진 삽질이었다. 이를 통해 repo를 fork 할 이유가 전 ㅡ 혀 없다는 것을 깨달았으니 말이다.

profile
기술로써 가치를 만들고 싶은 사람입니다.

0개의 댓글