grep

Engineering

깃헙 액션을 마켓에 등록해보자

NHN

2020년 6월 2일

원문에서 보기 ↗

1.png

지난 글에서는 github actions를 이용해 workflow를 만드는 법을 소개했다. 이번 시간은 Github Market place에 등록되어있는 액션들처럼 쉽게 가져다가 쓸 수 있는 액션을 만들어보려고 한다.

마켓에 등록하는 액션을 만드는 것은 기존 workflow를 만드는 것과는 방법이 다르다. 하나의 범용적인 step이나 job을 만든다고 생각할 수 있다. 코드에 대한 설명보다는 어떤 것들을 사용할 수 있는지 위주로 소개하겠다.

굳이 Action을 만들어야 하나?

만약 프로젝트가 하나라면 직접 workflow에 포함하는 것이 훨~씬 간단하긴 하다. 하지만 관리해야 하는 저장소가 50개 100개라면 이야기가 달라진다. TOAST UI에서 확인이 필요한 상품들의 브라우저 지원 범위는 모두 다르고 코드에 수정이 필요하다고 하면 끔찍한 일이 벌어질 수 있다. 최대한 APP에서만 수행할 수 있는 일을 제외하고 액션화를 시킨다면 한 저장소에서 관리가 가능해지고 사용이 훨씬 편리해지리라 생각해 액션을 만들었다.

개발 환경, 해야할 일

시작하기 전에 개발 환경과 해야할 일을 빠르게 적어보겠다.

위 환경을 고려해서 workflow를 적어보면

  1. tuidoc.config.js를 참고해 url을 생성해준다.
  2. url을 기준으로 셀레니윰과 browserstack을 이용해 방문한다.
  3. 각 page를 방문해 에러가 발생했는지 확인한다.
  4. 결과를 확인하고 메일로 리포팅한다. 여기서 2, 3번째 step을 공통 액션화 할 것이다.

액션 만들기

처음 액션을 만들어본다면 이 튜토리얼을 따라 해보는 것을 추천한다. 이 튜토리얼 순서대로 작성해보겠다.

저장소 환경 만들기

  1. 튜토리얼에 나온 것처럼 node12 버전을 이용해 npm init -y로 초기화했다.
  2. 루트 경로에 메타데이터를 명시하는 파일인 action.yml을 만든다. 이 링크를 확인해보면 어떤 것들이 메타데이터로 들어가는지 알 수 있다.
name: 'TOAST UI Checking url error using browserstack'
description: 'Checking url error using browserstack'
inputs:
  urls:
    description: 'urls'
    required: true
  global-error-log-variable:
    description: 'error log array variable name(ex: errorLogs)'
    required: true
    default: 'errorLogs'
  browserlist:
    description: 'browser list'
    required: true
    default: 'ie10, ie11, safari, edge, chrome, firefox'
runs:
  using: 'node12'
  main: 'dist/index.js'
branding:
  icon: 'check-circle'
  color: 'blue'

입력, 출력, 실패

잠깐 이 액션을 사용하는 곳의 workflow를 상상해보자. 우리는 이 workflow를 실행할 액션을 만드는 것이 목표다.

jobs:
    detectError:
        steps:
            - name: detect runtime error
              uses: 계정/액션-저장소-이름@v버전
              with:
                  browserlist: "ie8, ie9, ie10"
                  urls: "https://nhn.com"
              env:
                  BROWSERSTACK_USERNAME: ${{secrets.BROWSERSTACK_USERNAME}}
                  BROWSERSTACK_ACCESS_KEY: ${{secrets.BROWSERSTACK_ACCESS_KEY}}

uses로 액션을 명시하고 with로 액션에서 사용할 값을 넘겨줄 것이다. browserstack에서 사용할 USERNAME과 ACCESS_KEY도 저장소에서 넘겨줄 것이다. 이제 이렇게 넘겨준 값들은 어떻게 받아서 사용하는지 살펴보자.

main에 작성한 index.js에 액션에서 수행할 코드를 작성한다. 액션을 생성하기 위해 깃헙에서는 여러 가지 toolkit을 제공한다. input, output, logging 등 기본적인 기능을 사용하기 위한 @action/core나 cli로 함수를 실행하기 위해 사용하는 @actions/exec, 현재 수행 중인 깃헙의 컨텍스트에 접근하는 @actions/github등을 제공한다. 우리는 단순하게 input과 로깅이 필요하기 때문에 @actions/core만 사용했다.

$ npm i @actions/core

그럼 workflow에서 with를 통해 넘겨줄 입력값을 받아 코드에서 사용해보자. core의 getInput을 통해 입력값을 받을 수 있다. 이름은 위 action.yml에서 작성한 이름 그대로 사용한다. 출력값은 setOutput을 통해 정할 수 있다.

// index.js
const core = require('@actions/core');

try {
  const urls = core.getInput('urls');
  const browserlist = core.getInput('browserlist');
  
  const { BROWSERSTACK_USERNAME, BROWSERSTACK_ACCESS_KEY } = process.env;
  ...
} catch (error) {
  core.setFailed(error.message);
}

env로 넘겨준 값들은 process.env로 접근할 수 있다.

제일 중요한 것은 setFailed다. setFailed는 해당 액션이 실패했다는 것을 알려준다. 만약 setFailed를 작성하지 않는다면 해당 스텝은 실패했더라도 통과한 것으로 노출이 되니 반드시 작성해줘야 한다.

이게 전부다! 값들을 받아 작업을 수행하고 실패 조건을 명시해줬다. 그럼, 이 액션을 배포해보자.

zeit/ncc로 번들링 해서 배포하기

ncc는 노드로 작성된 파일을 의존까지 함께 하나의 파일로 컴파일 해주는 CLI다. 노드 모듈파일을 전부 올리는건 비효율적이기 떄문에 하나의 파일로 만들어서 사용했다.

$ npm i -g @zeit/ncc
$ ncc build index.js

ncc를 이용하여 컴파일을 하면 하나의 index.js 파일이 dist 경로에 생겼다. 기존에 action.yml에 작성했던 env.main를 index.js 대신 dist/index.js로 바꿔준다.

# config
runs:
  using: 'node12'
  main: 'dist/index.js'

그럼 변경된 내용을 저장소에 푸시하자. 이렇게 될 경우 모든 저장소에서 해당 액션을 사용할 수 있게 된다. 또한, git에 태그로 버전을 명시해준다면 workflow에서 액션을 사용할 때 버전별로 선택해 사용할 수 있다.

$ git tag v1.0.0
$ git push origin v1.0.0

사용하기

workflow에서 생성한 저장소를 가리키면 사용이 가능하다. 만약 jung-han 계정에 browserstack-actions라는 저장소라면 아래처럼 사용할 수 있다. @뒤에 버전을 명시해 버전별로 선택해 사용할 수 있다.

jobs:
    detectError:
        steps:
            - name: detect runtime error
              uses: jung-han/browserstack-actions@master #master branch
              uses: jung-han/browserstack-actions@v1.0.0 # 1.0.0 버전 사용

marketplace에 등록하기

2.png

3.png

4.png

5.png

6.png

끝

액션을 만들어서 IE8 부터 edge, safari 등등 여러 브라우저의 에러 체킹을 자동화했다. 읽어보면 알겠지만 사실 액션을 만들고 배포하는 것은 어렵지 않다. (더 효율적으로 작성하는 방법이 있을 수 있을 것이다) 글에서 잘못된 내용이 있다면 언제든지 댓글 바란다!


추가로 알면 좋은 것들

needs, if

workflow에서 해당 job이 실행이 되어야 할지 말지 분기문으로 결정 할 수 있다. 또한 이전 작업이 반드시 성공적으로 끝나야만 진행이 되어야 하는 job 들도 있다. 그럴때 if나 needs를 활용하면 된다.

artifact

artifact는 워크 플로우 실행 중에 생성된 파일을 의미한다. artifact를 이용하면 작업이 끝난 뒤에도 데이터를 유지 할 수 있다. 이를 이용하면 workflow동안 데이터를 전달할 수 있다. actions/upload-artifact 액션을 통해 artifact를 업로드 할 수 있고 actions/download-artifact로 다운받아 사용할 수 있다. 또한 테스트 결과 report를 저장하거나 결과를 업로드해야 하는 경우에 편하게 사용할 수 있다.

env에 값 세팅하기

url을 만드는 함수를 수행한 뒤 그 결과를 다음 workflow에 사용했어야 했다. 이 값을 그대로 사용할 수 있는 방법을 찾아봤지만 찾지 못했다. 그래서 결과로 만든 url.txt를 쉘로 읽은 뒤 env에 할당한 뒤 꺼내 썼다. 다른 방법이 궁금하다면 링크를 들어가 보면 좋을 것 같다. 이에 관한 이야기가 있다.

jobs:
    # ...
            - name: make url
              run: |
                  node createUrl.js
            - name: set url
              shell: bash
              run: |
                  value=`cat ./url.txt`
                  echo ::set-env name=URLS::$value  # 값 env에 세팅
            - name: detect runtime error
              uses: nhn/toast-ui.detect-runtime-error-actions@master
              with:
                  urls: ${{ env.URLS }} # 꺼내 쓰기