preview image
Posted by January 31 2020 / github
Github Action 빠르게 시작하기
Updated on March 30 2024
2135 words
5 minutes read

... visits

Github Action이란?

Github Action은 Github 저장소를 기반으로 소프트웨어 개발 Workflow를 자동화 할 수 있는 도구이다. 간단하게 말하자면 Github에서 직접 제공하는 CI/CD 도구라고 할 수 있다.

Workflow는 Github 저장소에서 발생하는 build, test, package, release, deploy 등 다양한 이벤트를 기반으로 직접 원하는 Workflow를 만들 수 있다.

Workflow는 Runners라고 불리는 Github에서 호스팅 하는 Linux, macOS, Windows 환경에서 실행된다. 그리고 이 Runners를 사용자가 직접 호스팅하는 환경에서 직접 구동시킬 수도 있다.(self-hosted runner)

Github 마켓 플레이스에는 여러 사람이 공유한 Workflow는 찾을 수 있으며, 자신이 직접 만들어서 공유할 수도 있다.

⏳ 얼마나 사용 할 수 있을까?

Workflow는 저장소마다 최대 20개까지 등록할 수 있다. 그리고 Workflow 안에 존재하는 Job이라는 단계마다 최대 6시간 동안 실행될 수 있고, 초과하게 되면 자동으로 중지된다.

그리고 Github 계정 플랜에 따라 전체 Git 저장소를 통틀어 동시 실행할 수 있는 Job 개수가 정해져 있다.
Job 안에서 Github API를 호출한다면 1시간 동안 최대 1,000번까지만 가능하다.

💵 사용료 얼마나?

공개 저장소는 무료이며, 비공개 저장소는 해당 계정에 부여된 무료 사용량 이후에 과금된다.
Github 무료 계정의 전체 비공개 저장소를 기준으로 한달에 500MB 스토리지와 실행 시간 2,000분(minute)까지 제공된다.

하지만 기본적인 방법은 저장소에 .github/workflows 폴더를 만들어서 .yml 형식 파일 만든 뒤 Workflow를 정의하는 것이다.

먼저 간단한 예제를 살펴보면서 구성을 익혀보자.

name: Greet Everyone
# 이 Workflow는 저장소에 Push가 되면 실행 되도록 한다
on: [push]

jobs:
  # Job ID: 문자와 -(대시), _(언더바)로 구성된 Job 고유 식별자
  build:
    # Job 이름
    name: Greeting
    # 이 Job은 리눅스에서 실행된다
    runs-on: ubuntu-latest
    steps:
      # 이 Step은 Github이 제공하는 `hello-world-javascript-action` Action을 사용한다
      - name: Hello world
        uses: actions/hello-world-javascript-action@v1
        with:
          who-to-greet: 'Mona the Octocat'
        id: hello
      # 이 Step은 이전 Step에서 나온 출력을 사용한다
      - name: Echo the greeting's time
        run: echo 'The time was ${{ steps.hello.outputs.time }}.'

⚠️ 반복 스케줄은 UTC 타임존 시간을 사용하고, 기본 브랜치나 마지막 커밋을 기준으로 동작한다. 최소 간격은 5분까지만 가능하다. (참고: Scheduled Events - Github Help )

예를 들자면 master 브랜치 또는v1 태그가 Push 되었을 때 test 폴더안에 어떤 파일이 변경된 경우에 Workflow가 실행되게 할 수 있다.

on:
  push:
    branches:
      - master
    tags:
      - v1
    paths:
      - 'test/*'

실행 환경은 runs-on 항목으로 지정하고, Github이 호스팅하는 머신 환경은 Ubuntu, Windows, MacOS가 있다. (참고: Virtual environments for GitHub-hosted runners - GitHub Help )

예를 들어 NPM 패키지를 빌드해서 배포하거나 Go 바이너리를 Github 저장소 release에 올리는 동작을 적절한 도구나 여러 API를 조합해서 만든 것을 Action으로써 활용하는 것이다.
그리고 이렇게 만든 Action을 공유하면 마치 코딩할 때 라이브러리를 가져다 쓰는 것처럼 쓸 수 있다.

도커 컨테이너로 Action을 만드는 경우 일관된 동작을 보장할 수 있는 장점이 있지만, Github이 호스팅하는 리눅스 환경에서만 실행할 수 있다.

Javasript로 Action을 만들면 좀 더 간단하며, 도커 컨테이너보다 더 빨리 실행된다.

이렇게 만든 Action에 필요한 Input, Output 설정이나 메인 실행 파일 같은 메타 정보를 정의하기 위해 action.yaml 또는 action.yml을 반드시 작성해야 한다.

Acton 메타 정보의 종류와 의미는 Metadata syntax for GitHub Actions - GitHub Help 에서 참고하자.

name: 'Hello World'
description: 'Greet someone and record the time'
branding:
  color: 'yellow'
  icon: 'code'
inputs:
  who-to-greet:
    description: 'Who to greet'
    required: true
    default: 'World'
outputs:
  time:
    description: 'The time we greeted you'
runs:
  using: 'node12'
  main: 'index.js'

action.yml 마지막에 정의한 index.js 이름으로 메인 실행 파일을 만든다.
Javascript로 Action 로직을 만드는 경우 도움이 될만한 Node.js 패키지가 있다.
@actions/core , @actions/github 이 두 패키지는 Input, Output을 쉽게 처리하고, Github Action 컨텍스트에 접근할 수 있는 인터페이스 등을 제공한다.

const core = require('@actions/core');
const github = require('@actions/github');

try {
  const nameToGreet = core.getInput('who-to-greet');
  console.log(`Hello ${nameToGreet}!`);

  const time = (new Date()).toTimeString();
  core.setOutput("time", time);

  const payload = JSON.stringify(github.context.payload, undefined, 2)
  console.log(`The event payload: ${payload}`);
} catch (error) {
  core.setFailed(error.message);
}

Action 저장소가 다른 저장소의 Workflow에서 사용되려면 반드시 Public 저장소로 설정되어 있어야 한다.
아래 내용은 위에서 살펴본 Workflow 예제에 Hello world Step 부분을 수정했다.

# 윗부분 생략
jobs:
  greeting_job:
    name: Greeting
    runs-on: ubuntu-latest
    steps:
      - name: Hello world
        uses: jonnung/github-action-practice@master
        with:
          who-to-greet: 'Jonnung'
        id: hello
      - name: Echo the greeting's time
        run: echo 'The time was ${{ steps.hello.outputs.time }}.'

GitHub Marketplace · Actions to improve your workflow · GitHub

만약 Action을 공유할 목적이 아니라 특정 프로젝트에 종속된 구성을 한다면 action.yaml 파일을 어디에 두던 상관이 없다.
하지만 .github/actions/action1, .github/actions/action2 같은 구성을 하는 것이 관리하는 측면에서 유용하다.

Action을 독립된 Git 저장소로 구성한다면, 반드시 Public 저장소 타입으로 만들어야 한다.
하지만 이 저장소가 바로 Github 마켓 플레이스에 올라가는 건 아니다. 하지만 Github이 자동으로 action.yml을 감지해서 마켓 플레이스에 올릴 수 있다는 배너를 노출해준다.

Jenkinsfile을 도입한 결정적인 이유는 아무래도 역사와 전통이 깊은 Jenkins를 사용하는게 다양한 사례들을 활용하고, 문제가 발생했을 때 더 쉽게 정보를 얻을 수 있을 것이라고 판단했었다.

최근 Github Action이 정식 출시되었을 때 크게 관심을 갖지 않았지만, 조만간 Gitlab EE 라이센스가 끝나기 때문에 Github Team으로 이사 가는 것을 추진하고 있다. (당연히 동료 개발자들은 환호했음)

하지만 Gitlab EE에서 제공하는 Docker Registry 서버 기능을 사용하고 있기 때문에 이 부분을 해결하고, 중요하진 않지만 Git Remote 도메인 부분도 기존 것을 활용할 수 있을지 좀 더 조사를 해봐야 한다.

아무튼 Github Action을 살펴본 결론은 굉장히 쉽고 간단하다는 것이다.
CI/CD에 대한 개념이 익숙한 상태에서 Workflow를 구성하는 핵심적인 요소들만 이해하면 쉽게 익혀서 사용할 수 있다고 생각한다.

comments powered by Disqus
TAGS
On this page