Github actions: Basic(with YAML)
위 글에서 YAML문법과 workflow의 기본구성에대해 알아보았다. 이번 글에서는 직접 워크플로우를 작성해보도록 하겠다. 😎
👨🏻💻 워크플로우 작성하기
이번 글에서는 테스트자동화를 위한 workflow를 작성해보도록 하겠다.
먼저 어떠한 순서로 작업들이 이루어질지 구상해보고 실제 코드로 옮겨 작성해보자.
- 이벤트 및 작업환경 설정
- main 브랜치로 체크아웃
- Node.js 환경설정
- npm 캐싱
- 패키지 설치
- 테스트 실행
- PR 시, 테스트 실패할 경우 자동 closed 및 comment 작성
- 슬랙에 알림
0. 이벤트 및 작업환경 설정
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [ 12.x,14.x,16.x ]
main
브랜치에 push
,pull_request
이벤트가 발생할 경우 jobs가 실행되도록 설정하였고
같은 작업들이 3가지 node 버전에서 실행되도록 strategy에 설정하였다.
1. main 브랜치로 체크아웃
- name: checkout main branch
uses: actions/checkout@v2
MarketPlace에서 checkout
action을 사용하여 repository의 소스를 가져온다.
2. Node.js 환경설정
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
setup-node
action을 사용하여 node환경을 설정해준다. strategy의 matrix.node-version을 참조하여 설정해주었다.
3. npm 캐싱
- name: npm cache
uses: actions/cache@v2
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
GIthub의 러너는 각 작업에서 새로운 환경으로 실행되므로 작업들이 종속성을 재사용하는 경우 파일들을 캐싱하여 성능을 향상시킬 수 있다. 캐시를 생성하면 해당 저장소의 모든 워크 플로우에서 사용 가능하다.
위의 코드에서는 매번 node 모듈을 설치하지않고 ~/.npm
디렉토리를 캐시하여 작업 실행속도를 높였다.
cache action에서 사용법을 확인할 수 있다.
4. 패키지 설치 & 5. 테스트 실행
- name: npm install
run: npm install
- name: npm test
run: npm test
6. PR 시, 테스트 실패할 경우 자동 closed 및 comment 작성
- name: if fail
uses: actions/github-script@v5.0.0
with:
script: |
const ref = "${{github.ref}}"
const pull_number = Number(ref.split("/")[2])
await github.rest.pulls.createReview({
...context.repo,
pull_number,
body:"테스트를 통과하지 못했습니다.😢 ",
event: "REQUEST_CHANGES"
})
await github.rest.pulls.update({
...context.repo,
pull_number,
state: "closed"
})
if: failure()
이 step에서는 github-script action을 사용하였다.
이 액션을 사용하면 다양한 Github API들을 쉽게 사용할 수 있다. 그 중 github과 context라는 변수를 자주 사용하게되는데,
github은 octokit객체이고, context는 현재 실행중인 워크플로우에 대한 컨텍스트 객체로 sha, action, workflow등의 정보를 참조할 수 있다.
github-script를 사용할 때 with 안에 github-token
을 설정해주기도 하는데, 이는 필수값은 아니며 github-token을 따로 설정해주지 않을 경우 github에 설정해 둔 default token이 사용된다.
가장 아래의 if
를 보면 failure()
을 설정하면 "이 step은 다른 step이 중단될 경우에만 실행한다"라는 의미이다. 따라서 테스트가 모두 통과되지 않으면 이 작업이 실행되어 아래처럼 PR이 closed되고 코멘트가 자동으로 작성되게 된다.
7. 슬랙에 알림
- name: build result to slack
uses: 8398a7/action-slack@v3
with:
status: ${{job.status}}
fields: repo,message,commit,author,action,eventName,ref,workflow,job,took
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
if: always()
action-slack
을 사용하여 슬랙에 알람을 보내도록 설정하였다.
이 설정을 위해서는 슬랙 채널에 App을 생성해야 하고 이 App에 Webhook을 추가하여 Webhook URL을 Secrets에 설정해주어야한다.
사전 설정
Slack Api으로 이동하여 create new App 버튼을 누른 뒤 연결할 슬랙 워크스페이스를 선택한다.
Building Apps for Slack / Add features and functionality / Incoming Webhooks 으로 이동하여
On으로 설정해준다.
이후 가장 하단의 Add New Webhook to Workspace 버튼을 클릭하면
webhook이 생성되는데 이 URL을 복사해준다.
복사한 URL을 github action을 생성하는 repository의 setting/secrets에 입력하여 설정해준다.
이 값을 env.SLACK_WEBHOOK_URL에 secrets.xxx
로 접근하여 할당해주면 슬랙에 연결 완료!
이후 git action이 실행되면 아래처럼 슬랙에 알람이 가게된다.
슬랙에 보내지는 메시지는 원하는 형태로 커스텀마이징할 수도 있다. 😎
완성된 workflow
name: PR Test
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node: [ 12,14,16 ]
steps:
- name: checkout main branch
uses: actions/checkout@v2
# strategy의 matrix.node-version 참조
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: npm cache
uses: actions/cache@v2
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: npm install
run: npm install
- name: npm test
run: npm test
# PR 시, test 실패할 경우 close 후 comment남기기
- name: if fail
uses: actions/github-script@v5.0.0
with:
# 원하는 script 선언
script: |
const ref = "${{github.ref}}"
const pull_number = Number(ref.split("/")[2])
await github.rest.pulls.createReview({
...context.repo,
pull_number,
body:"테스트를 통과하지 못했습니다.😢 ",
event: "REQUEST_CHANGES"
})
await github.rest.pulls.update({
...context.repo,
pull_number,
state: "closed"
})
if: failure()
- name: build result to slack
uses: 8398a7/action-slack@v3
with:
status: ${{job.status}}
fields: repo,message,commit,author,action,eventName,ref,workflow,job,took
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
if: always()
🙏 참고
'개인공부 > CI&CD' 카테고리의 다른 글
Github actions: Basic (with YAML) (0) | 2021.12.01 |
---|