반응형

최근 github action 을 workflow CI/CD 로 활용하는 사례가 점점 늘어나고 있다. 이전 글인 "10분만에 만드는 Docker image 저장 자동화"도 github action 을 활용하여 docker registry 에 컨테이너 이미지를 빌드하고 push 하는 방법을 설명하였다.

이번에는 github action 을 client cli 를 활용하여 원하는 시점에 manual 로 호출하는 방법을 알아보자.

1. 새로운 github repository 만들기

먼저 github repository 를 만들어 clone 한다.

$ git clone https://github.com/seungkyua/github-action-sample.git
$ cd github-action-sample

2. workflow action 파일 만들기

github action 을 위한 .github/workflows 디렉토리를 생성하고 action 파일인 hello.yaml 파일을 만든다. 디렉토리 명이 workflow 가 아닌 workflows 이니 실수하지 않게 조심하자.

$ mkdir -p .github/workflow
$ touch .github/workflows/hello.yaml

hello.yaml 은 다음과 같다.

name: Hello

on: 
  workflow_dispatch:
    inputs:
      greeting:
        required: false
        default: 'Hello'
        type: string
      name:
        required: false
        default: 'Seungkyu'
        type: string

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v2

      - name: Run hello.sh
        run: |
          set -xe
          chmod +x .github/workflows/hello.sh
          .github/workflows/hello.sh ${{ github.event.inputs.greeting }} ${{ github.event.inputs.name }}

workflow 에서 parameter 를 받기 위해서는 workflow_dispatch: 를 명시적으로 선언하고 parameter 는 inputs 아래에 기술한다. inputs 아래 나오는 이름이 parameter 명이 되며 필수 여부, 기본값, 타입 등을 지정할 수 있다.

여기서는 'greeting' 과 'name' 이라는 2개의 parameter 를 받는 다고 선언하였다.

다음은 workflow step 인데 첫번째 actions/checkout@v2 는 현재의 github repository 소스를 다운 받는 다는 의미이다. 두번째 name: Run hello.sh 는 run: 으로 shell 을 실행하겠다는 의미이며, 앞 단계에서 소스를 다운받았으니 hello.sh 을 실행할 수 있게 되었으며, 실제로 hello.sh 을 실행하면서 parameter 를 argument 로 호출한다.

parameter 는 ${{ github.event.inputs.파라미터명 }} 과 같이 활용할 수 있다.

다음은 간단산 hello.sh 쉡스크립트 이다.

#!/bin/bash

if [ $# -eq 1 ]; then
  greeting=$1
elif [ $# -eq 2 ]; then
  greeting=$1
  name=$2
fi

echo "[hello.sh] ${greeting} ${name}\n"

이제 해당 파일들을 github 에 push 한다.

3. workflow 호출하기

github workflow client 를 다운 받는다. mac 에서는 brew 로 간단히 설치할 수 있다.

$ brew install gh

github-action-sample 소스를 clone 한 디렉토리에서 gh auth login 으로 github 에 로그인 한다.

$  gh auth login
? What account do you want to log into?  [Use arrows to move, type to filter]
> GitHub.com
  GitHub Enterprise Server

GitHub.com 을 선택하고 엔터를 치면 아래의 내용이 나온다.

? What account do you want to log into? GitHub.com
? You're already logged into github.com. Do you want to re-authenticate? (y/N) y

이미 로그인을 했기 때문에 다시 로그인 하겠다는 의미이며 처음이면 로그인 하라는 메세지가 나온다. y 로 선택하고 로그인을 하자.

? What account do you want to log into? GitHub.com
? You're already logged into github.com. Do you want to re-authenticate? Yes
? What is your preferred protocol for Git operations?  [Use arrows to move, type to filter]
> HTTPS
  SSH

HTTPS 를 선택한다.

? What account do you want to log into? GitHub.com
? You're already logged into github.com. Do you want to re-authenticate? Yes
? What is your preferred protocol for Git operations? HTTPS
? Authenticate Git with your GitHub credentials? (Y/n) y

y 로 Github credentials 로 로그인을 한다.

? What account do you want to log into? GitHub.com
? You're already logged into github.com. Do you want to re-authenticate? Yes
? What is your preferred protocol for Git operations? HTTPS
? Authenticate Git with your GitHub credentials? Yes
? How would you like to authenticate GitHub CLI?  [Use arrows to move, type to filter]
  Login with a web browser
> Paste an authentication token

token 으로 로그인을 한다.

? What account do you want to log into? GitHub.com
? You're already logged into github.com. Do you want to re-authenticate? Yes
? What is your preferred protocol for Git operations? HTTPS
? Authenticate Git with your GitHub credentials? Yes
? How would you like to authenticate GitHub CLI? Paste an authentication token
Tip: you can generate a Personal Access Token here https://github.com/settings/tokens
The minimum required scopes are 'repo', 'read:org', 'workflow'.
? Paste your authentication token: ****************************************

정상적으로 login 이 되면 아래와 같이 표시된다.

- gh config set -h github.com git_protocol https
✓ Configured git protocol
✓ Logged in as seungkyua

로그인 후에 gh workflow list 명령어로 workflow 를 조회하면 아래와 같이 Hello 란 workflow 가 있음을 알 수 있다.

➜ github-action-sample git:(main) gh workflow list
Hello  active  14639329

이를 실행해 본다.

$ gh workflow run hello.yaml -f greeting=Welcome -f name=Seungkyu

실행 중인 workflow 를 조회할 수 있다.

$ gh run list --workflow=hello.yaml
STATUS  NAME            WORKFLOW  BRANCH  EVENT              ID          ELAPSED  AGE
*       Initial commit  Hello     main    workflow_dispatch  1390917347  7s       0m

완료된 후의 workflow 를 조회하면 STATUS 가 완료로 체크되어 있다.

$ gh run list --workflow=hello.yaml
STATUS  NAME            WORKFLOW  BRANCH  EVENT              ID          ELAPSED  AGE
✓       Initial commit  Hello     main    workflow_dispatch  1390917347  15s      2m

웹 브라우저로 repository https://github.com/seungkyua/github-action-sample 에 접속하여 Action 탭의 build 를 클릭해보면 아래의 화면 처럼 '[hello.sh] Welcome Seungkyu\n' 가 출력되어 있음을 알 수 있다.

 

 

 

 

4. 활용법

manual 하게 github action 을 호출하는 부분은 다른 workflow tool 과 같이 사용할 때가 많다. 예를 들면 argo workflow 에서 하나의 단계로 github action 을 필요한 시점에 호출하여 결과를 활용하는 등으로 사용할 수 있다.

github action 은 github 의 리소스를 활용하므로 CI 에서 많은 리소스가 필요할 때는 github action 을 같이 활용하는 것도 좋은 대안이 될 것이다.

반응형
Posted by seungkyua@gmail.com
,
반응형

애플리케이션을 개발하면서 원하는 시점에 자동으로 Docker image 를 build 하고 이를 docker hub 저장소에 push 할 수 있는 방법을 소개한다. 보통은 이를 CI 로 구축하는데 CI 시스템을 따로 구축하기에는 시간과 비용이 들고 이를 유지보수 하기에도 귀찮은 면이 있다. 만약 Github 을 사용하고 있다면 10분 만에 Github Action 으로 이를 쉽게 구현할 수 있다.

 

1. Dockerfile 만들기

가장 먼저 해야할 일은 도커 이미지 빌드를 위한 Dockerfile 을 만드는 것이다. golang 으로 개발하고 있다면 아래와 같이 만들 수 있을 것이다. 어느 정도 최적화를 고려했지만 완전히 최적화한 부분은 아니니 자신의 환경에 맞게 변경해야 한다. Dockerfile 의 위치는 $PROJECT_HOME 디렉토리 바로 아래이다.

FROM golang:1.16.3-stretch AS builder
LABEL AUTHOR Seungkyu Ahn (seungkyua@gmail.com)

RUN mkdir -p /build
WORKDIR /build

COPY . .
RUN go mod tidy && go mod vendor
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o bin/server ./cmd/server

RUN mkdir -p /dist
WORKDIR /dist
RUN cp /build/bin/server ./server


FROM golang:alpine3.13

RUN mkdir -p /app
WORKDIR /app

COPY --chown=0:0 --from=builder /dist /app/
EXPOSE 9111

ENTRYPOINT ["/app/server"]
CMD ["-port", "9110"]

 

2. Github Action 파일 만들기

Github Action 은 규칙에 맞게 yaml 을 파일은 정해진 위치에 넣으면 Github 에서 알아서 실행시켜 준다. Action 을 실행시키는 시점은 소스가 github 에 push 되는 순간이며, 어느 branch 에 push 되었는지, Pull Request 를 했을 때 등의 실행 조건을 정의 할 수 있다.

$PROJECT_HOME 디렉토리에서 다음과 같이 디렉토리를 만든다.

$ mkdir -p .github/workflows

 

github action yaml 은 아래와 같다.

$ vi .github/workflows/deploy-image.yml

name: Build and Push Docker Image
on:
  push:
    branches:
      - main
jobs:
  build-and-push-image:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout
      uses: actions/checkout@v2

    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v1

    - name: Login to DockerHub
      uses: docker/login-action@v1
      with:
        username: ${{ secrets.DOCKERHUB_USERNAME }}
        password: ${{ secrets.DOCKERHUB_TOKEN }}

    - name: Build and push
      id: docker_build
      uses: docker/build-push-action@v2
      with:
        push: true
        tags: seungkyua/tks-contract:latest

처음의 on 은 해당 action 이 수행될 조건을 의미한다. push - branches - main 은 main branch 에 push 가 일어나면 수행된다는 의미이다. 그렇기 때문에 요청된 PR 을 merge 하거나 main branch 에 직접 push 하면 해당 action 이 trigger 된다.

모든 branch 의 push 에 대해서 동작하게 하려면 '*' 로 하면 된다.

 

job 은 pipeline 을 구성하는 부분이다. steps 처음을 보면 "name: Checkout" 부분에 uses: actions/checkout@v2 로 되어 있는데 이는 github action 으로 정의된 모듈이다. 실체 소스는 https://github.com/actions/checkout 으로 접속하면 볼 수 있으며 해당 기능은 디폴트로 action 이 수행되는 github repository 의 소스 (현재 project 의 소스)를 내려받는 기능이다. 내려 받을 repository 를 바꿀려면 변경 가능하다. (action/checkout 에 접속하여 사용법을 확인하자)

 

"name: Set up Docker Buildx" 부분은 builder driver 나 platform 등을 세팅하는 부분이다. 역시 자세한 부분은 https://github.com/docker/setup-buildx-action 를 확인하자.

 

"name: Login to DockerHub" 는 docker hub 에 접근하기 위해서 id 와 password 를 지정하는 부분이다. 이를 위해서는 github repository 의 settings 로 들어가서 좌측 하단의 secrets >> Actions 에서 Action 용 secret 을 만들어야 한다.

 

 

 

 

 

 

 

docker hub 에 접속할 id 와 password 에 대한 secret 을 만들고 이를 github action 에서 ${{ secrets.DOCKERHUB_USERNAME }} 와 같이 변수로 가져다 쓰는 방식이다.

 

마지막으로 "name: Build and push" 부분은 docker image 를 build 하고 push 하는 부분이다. 이미지 name 과 tag 는 tags 로 지정했다. Dockerfile 의 위치 및 파일명은 file 키로 변경할 수 있다. 아무런 지정을 하지 않으면 해당 프로젝트 디렉토리에 있는 Dockerfile 을 찾는다. 자세한 내용은 https://github.com/docker/build-push-action 를 참조하자.

 

최종적으로 파일들은 아래와 같이 존재하게 된다.

 

 

 

보너스로 한가지 더.

 

main branch 로 merge 될 때 외에도 PR 을 할 때 docker image 를 build 하고 push 할 수 는 없을까? 이미지의 tag 는 latest 가 아니라 PR 을 요청한 source 의 branch 명으로 만들고 싶을 수 있다.

 

이럴 때는 새로운 파일을 만들고 github 의 내장 환경 변수를 사용하면 된다. 앞부분의 on 부분과 마지막 Build and push 부분의 tags 를 다음과 같이 수정하면 된다.

$ vi .github/workflows/deploy-image-with-branch.yml

name: Create and publish a package
on:
  pull_request:
    branches:
      - main
...
...
  - name: Build and push
      id: docker_build
      uses: docker/build-push-action@v2
      with:
        push: true
        tags: seungkyua/tks-contract:${{ github.head_ref }}
반응형
Posted by seungkyua@gmail.com
,