GitHub Actions 로 풀리퀘스트 test 검증하기

adam2·2020년 1월 31일
12
post-thumbnail

이번엔 전에 배웠던 기초적인 actions의 문법으로 간단한 workflow를 만들어보겠습니다.
특정 브랜치에 pr을 보낼 경우 test를 돌리는 action을 작성해보도록 하겠습니다!


workflow를 만들때는 말 그대로 흐름을 미리 생각해두고 코드로 구현하면 더 쉬운것 같다.
순서대로 흐름을 나열해보면

  1. pr을 감지한다.
  2. pr을 보낸 브랜치를 판별한다.
  3. jest로 코드를 test한다.
  4. test가 성공할 경우 pr을 그대로 open.
  5. test가 실패할 경우 pr을 close하고 comment를 남긴다.

이런 흐름이 될 것이다.
이제 이걸 코드로만 바꿔주면 여러분도 Actions 마스터~~

걱정 마세요 이전 포스팅 처럼 workflow, event, job, step 이 네가지만 생각하면 됩니다.!!

위의 순서도에서 어떤 부분을 어떤 개념에 넣어서 표현하면 될지를 생각해보면

  1. pr을 감지한다. => event
  2. pr을 보낸 브랜치를 판별한다. => event
  3. jest로 코드를 test한다. => step
  4. test가 성공할 경우 pr을 그대로 open. => step
  5. test가 실패할 경우 pr을 close하고 comment를 남긴다. => step

1 ~ 5 전체 흐름 => workflow
3 ~ 5 => job

이런 식으로 구성이 잡히게 된다. 이제 정말 다왔다. 이대로 workflow작성만 해주면 된다.

🔏 workflow 정의

우선 workflow를 정의해보자.
풀리퀘스트를 테스트하는 workflow이니까 'PR Test'라는 이름으로 작성해보자.

// PR_Test.yml
name: PR Test

🎺 event 정의

그리고 나서 event를 정의해준다.
우리의 조건은 test 브랜치에 pr이벤트가 일어났을 경우 해당 액션을 트리거 하는 것이다.

// PR_Test.yml
name: PR Test
on: 
	pull_request:   #pr이벤트를 감지
    	branches:
        	- test  #test라는 브랜치에 한해서

jobs 정의

그다음은 job과 그안의 steps를 정의해준다.
job id를 'Run Jest'로 설정하고 가상환경 인스턴스를 ubuntu-latest로 설정해 최신 우분투 환경에서 테스트를 돌리도록 하였다.
가상환경 인스턴스는 ubuntu 뿐만 아니라 windows, macos등도 사용이 가능하다.

그리고 npm을 사용하기 위해서 노드 환경도 설정해주어야 한다.
jobs.<job_id>.strategy.matrix 키워드를 사용하여 다양한 노드 버전을 설정해줄 수 있다.
(Node.js workflow 템플릿을 사용하면 조금 더 편하게 사용할 수 있다. )

// PR_Test.yml
name: PR Test
on: 
	pull_request:   #pr이벤트를 감지
    	branches:
        	- test  #test라는 브랜치에 한해서

jobs: 
	Run Jest:
    	runs-on: [ubuntu-latest] # 우분투 가상환경 사용
        strategy:
          matrix:
            node-version: [8.x, 10.x, 12.x] # ".x" 로 최신 버전도 사용하고 직접 버전 지정도 가능하다
           

🍦steps 정의

이제 가상환경, 노드 환경까지 지정해주었으니 어떤 일을 하는 지만 정의해주면 된다.
steps라는 키워드 아래에 step을 단계적으로 작성해나간다.

name으로 각 step의 이름을 적어주고, run혹은 uses로 어떤 일을 할지를 지정해준다. run은 사용자가 직접 스크립트로 구현할 때 사용하고 uses는 마켓플레이스에 올라온 action을 가져다 쓸 때 사용한다.
여기서는 모두 간단한 코드여서 run을 사용해 직접 스크립트를 작성할 것이다. 이때 쉘스크립트를 사용한다.

3~5단계를 차례대로 적어보도록 하자.

  1. jest로 코드를 test한다. => step
- name: test code
  run: 
  	npm install
      npm test
  1. test가 실패할 경우 pr을 close하고 comment를 남긴다. => step

github-script

여기에서는 github-script라는 액션을 사용한다. 이 액션은 간편하게 github API를 사용할수 있어서 자주 사용하게 된다.
이 액션에선 githubcontext라는 변수를 사용할 수 있게 된다.
githuboctokit객체이고, context는 현재 실행중인 워크플로우에 대한 컨텍스트 객체로 sha, action, workflow등의 정보를 알아낼 수 있다.
(context객체 자세히 보기)

이제 코드를 보자.

      - name: if fail
        uses: actions/github-script@0.2.0  // github-script 액션을 사용한다.
        with:
          github-token: ${{github.token}}  // github token을 선언해준다
          script: |                        // script에 원하는 스크립트를 작성
            const ref = "${{github.ref}}"
            const pull_number = Number(ref.split("/")[2])
            await github.pulls.createReview({
              ...context.repo,
              pull_number,
              body:"테스트코드를 다시 확인해주세요. ",
              event: "REQUEST_CHANGES"
            })
            await github.pulls.update({
              ...context.repo,
              pull_number,
              state: "closed"
            })
        if: failure()                     // 이전 step이 실패했을 경우에만 이 step을 실행한다

마켓플레이스에 있는 액션을 가져다 쓰기 때문에 uses를 사용해 github-script를 선언하였고, 기본적으로 깃허브 토큰이 필수적으로 있어야 하기 때문에 토큰을 선언해주었다.
script부분에 내가 원하는 스크립트를 작성하면 된다.
풀리퀘스트 번호를 조회한 후 이를 이용해 원하는 코멘트를 달아주고 풀리퀘스트의 상태를 closed로 바꿔주는 스크립트이다.

그리고 마지막에 if: failure()라는 구문이 중요하다.
우리가 아는 if문과 같은 역할을 한다. 이전의 step이 fail일 경우에만 이 "if fail" step이 실행되는 것이다! failure외에도 success, alwayse 등등의 옵션들이 있으니 링크 참고.

자 이제 나만의 워크플로우가 완성되었다!!👏👏👏
이제 원하는 브랜치(예제에서는 test브랜치)의 /.github/workflows/디렉토리에 작성하면 끝이다.

// PR_Test.yml
// 완성된 코드
name: PR Test
on: 
	pull_request:   #pr이벤트를 감지
    	branches:
        	- test  #test라는 브랜치에 한해서

jobs: 
	Run Jest:
    	runs-on: [ubuntu-latest] # 우분투 가상환경 사용
        strategy:
          matrix:
            node-version: [8.x, 10.x, 12.x] # ".x" 로 최신 버전도 사용하고 직접 버전 지정도 가능하다
        steps: 
         - uses: actions/checkout@v2
         - name: npm install
           run: npm install
         - name: run test code
           run: npm test
		 - name: if fail
           uses: actions/github-script@0.2.0  // github-script 액션을 사용한다.
           with:
              github-token: ${{github.token}}  // github token을 선언해준다
              script: |                        // script에 원하는 스크립트를 작성
                const ref = "${{github.ref}}"
                const pull_number = Number(ref.split("/")[2])
                await github.pulls.createReview({
                  ...context.repo,
                  pull_number,
                  body:"테스트코드를 다시 확인해주세요. ",
                  event: "REQUEST_CHANGES"
                })
                await github.pulls.update({
                  ...context.repo,
                  pull_number,
                  state: "closed"
                })
          if: failure()                     // 이전 step이 실패했을 경우에만 이 step을 실행한다	

test 브랜치에 pr을 날리고 Actions탭에 가면 아래와 같이 워크플로우가 실행되는 것을 볼 수 있다.

그리고 만약 테스트에 통과하지 못하면 아래와 같이 pr에 코맨트가 달리고 자동으로 Closed된다. (머지된건 무시해주세요)
다시 테스트코드를 수정하고 pr을 날려야 하는 것이다.

🍽더 나아가기

아래 링크는 이 코드에서 더 나아가 몇가지 설정을 추가해서 실제로 프로젝트에서 사용한 코드이다.

https://github.com/connect-foundation/2019-16/blob/service%2Fsearch/.github/workflows/pr_to_service_test.yml

${{github.base_ref}}를 이용해 pr을 보내는 브랜치?에 따라서 다른 폴더에있는 테스트코드를 테스트했다. 예를들어 search 브랜치에서 test브랜치로 pr을 보내는 경우라면, base_ref는 search가 되는 것이고 이 브랜치에서 만든 테스트코드가 들어있는 폴더만 테스트를 돌리게 되는 것이다. (github 객체 살펴보기)

그리고 env:콘텍스트를 사용해 env 환경변수를 가상 인스턴스에 주입시켜줄 수 있다. 중요한 정보들은 github secret에 저장해서 사용할 수 있다.

글을 마치며

Actions는 장점이 많다. 일단 깃허브 내에서 많은 관리들이 한번에 가능하다는 점이 생각보다 편리하다. 그리고 github api를 사용하는 것도 편리하게 잘 되어있어서 깃허브의 코멘트, 이슈생성과 같은 기능들을 엮어서 스크립트를 작성할 수 있다.
그리고 actions공식문서가 정리도 잘 되어있고 설명도 잘 되어있어서 나조차도 아무 도움 없이 이렇게 스크립트를 작성할 수 있었다. 개인적으로 travis는 다큐먼트가 좀 부실해서 그것만 보고는 잘 못따라했었다..
이렇게 직접 스크립트를 작성하는게 어렵다면 마켓플레이스의 다양한 액션들을 활용하는 것도 큰 장점이다. 자동머지 액션, 슬랙봇 알림 액션, 자동 배포 액션 등등 이미 많은 개발자들이 만들어 놓은 액션들이 많아서 정말 간편하게 사용이 가능하다. 물론 세세하게까지 설정을 할 수 없어 결국 내가 만들어버리는 경우도 있지만 왠만하면 마켓플레이스에 있는것만 써도 다 될 것 같다.

2개의 댓글

comment-user-thumbnail
2020년 9월 7일

안녕하세요, Jest로 단위테스트를 하다 github Action으로 CI 구축을 할 수는 없을까 찾는 도중 읽게 되었습니다.
혹시 steps 에

- name: Git clone
        uses: actions/checkout@v2

이 과정이 빠진 것 같은데 이 step이 없어도 npm install이 잘 되나요,,?
저는 기존에 따로 쓰던 yml 파일보면서 추가해줘서 해결했네요 ㅠㅠ

1개의 답글