Github action에서 workflow를 재사용해 보자

eunji·2023년 11월 20일
1

문제 발견

오늘도 고도화할게 뭐가 있을까하고 두리번 거리던 프론트엔드 개발자 A씨. 그순간 그녀의 눈에 띈건 비슷한 내용으로 여러개 작성되어 있던 Github action workflow 파일들 ! 중복을 최소화하고 재사용성을 높힐 수 있는 방법이 없을까 하고 구글링을 하던 중 'Reusing workflows'라는 글을 보게 되었고 바로 실행에 옮겼다.

문제 진단

본인은 Github action을 배포 자동화를 위해 사용하고 있는데, 브랜치 전략에 따라 develop, stage, product 브랜치에 푸시나 PR이 머지되면 자동으로 배포되게 workflow 파일을 구성해 놨다.

배포의 구성은 모든 workflow파일이 동일한데 다른 점은 env파일, AWS버킷 URL 그리고 AWS distribution ID 총 세개 뿐이다. 이 다른 세개를 위해 70줄이 되는 비슷한 파일이 3개가 존재하고 있던것이다.

리액트에서 공통컴포넌트를 만들어 변경되야하는 부분만 props로 받아 사용하듯이 Reusable workflow를 구성하게 된다면 변경되는 부분만 제외하고 나머지는 재사용 할 수 있을것이라는 기대효과를 위해 작업을 시작하였다.

작업 시작

Reusable workflow 구성을 위해 workflow가 최소 2개가 필요한데 하나는 called workflow(공통 workflow) 다른 하나는 caller workflow(상황에 따라 달라지는 workflow)이다.

Called workflow

우선 공통이 되는 Reusable workflow를 작성해보자.

name: Reusable Deploy Workflow

on:
  workflow_call:
    secrets:
      AWS_S3_BUCKET_URL:
        required: true
    inputs:
      env:
        required: true
        type: string
jobs:
  build:
    runs-on: ubuntu-20.04
    steps:
      - run: cp ${{ inputs.env }} .env
      ... 생략
      - name: Copy the files from build folder to the S3 bucket
        run: aws s3 sync . ${{ secrets.AWS_S3_BUCKET_URL }} --cache-control max-age=31536000
        working-directory: ./dist/

workflow_call

  • workflow가 재사용 되기 위해서는 on에 workflow_call이 무조건 포함이 되야한다.
  • workflow_call에는 크게 secrets와 inputs이 포함된다.
  • secrets은 caller workflow에서 넘겨주는 secret과 관련된 문자 식별자들이다. (secrets 환경변수와 관련된)
  • inputs은 caller workflow에서 넘겨주는 정보. required과 type을 지정할 수 있다.

jobs안에서 사용되기 위해서는 secrets 혹은 inputs을 참조하여 호출하면 된다.

  • ${{ secrets.PERSONAL_ACCESS_TOKEN }}
  • ${{ inputs.env }}

현재 workflow_call안에는 설명을 위해 secrets하나 inputs하나로 구성되어있지만 각자 workflow의 구성에 따라 변하는 요소들은 다 저기에 선언해 놓으면 된다. 이 부분에 대해서는 caller workflow에서 연관지어 설명하도록 하겠다.

Caller workflow

공통 컴포넌트를 구성했으니 이제 props를 넘겨줄 일만 남았다.
dev브랜치에 푸시되면 배포하는 workflow를 새로 구성해보자.

name: Dev deploy

on:
  push:
    branches: dev

jobs:
  deploy-dev:
    uses: [owner name]/[repo name]/.github/workflows/deploy-project.yml@dev
    with:
      env: env/dev.env
    secrets:
      PERSONAL_ACCESS_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
      AWS_S3_BUCKET_URL: ${{ secrets.AWS_S3_BUCKET_URL }}
      ... 생략

uses

  • called workflow를 지정해줘야 한다.
  • {owner}/{repo}/.github/workflows/{filename}@{ref} 로 구성되어 있다.
  • 여기서 '@dev'를 왜 붙일까? {ref}는 브랜치 이름, 릴리스 태그, 또는 커밋 SHA이 될 수있고 릴리스나 브랜치 이름을 사용하면 릴리스나 브랜치에 대한 최신상태로 워크플로우가 실행된다.

with

  • with는 called workflow의 'inputs'에서 접근가능한 변수들을 선언할 수 있다. 우리 같은 경우 called workflow에 env를 선언하였고 dev 배포를 위한 dev.env 파일 경로를 넣어주었다. 단순한 문자열이기 때문에 called workflow에서는 type: string으로 지정하였다.
  • secrets은 모두 눈치 챘듯이 레포에 선언해 놓은 action secrets 환경변수에 접근할 수 있다. 선언하는 이름은 called workflow와 일치하면 된다. 여기서는 배포마다 다르게 구성되는 AWS 버킷 url, AWS distribution ID가 들어갈 수 있다.

변화된 점

우선 파일에 작성되어 있는 코드 수가 획기적으로 줄었다.
Called workflow에만 기존 workflow와 비슷한 70줄 정도 작성이 되어 있고 caller workflow 파일 하나에는 18줄 밖에 작성되어 있지 않다.
파일 3개 * 70줄 = 210줄(기존) -> 70줄 + 18 x 3 = 124줄(현재)

210줄에서 124줄, 즉 41%정도 반복되는 코드를 줄였다.

또한 앞으로 다른 개발자가 자동 배포를 구축해야할때도 같은 코드를 작성하지 않고 변화가 필요한 부분만 called workflow에 넘겨주게 된다면 아주 빠르게 배포환경을 구축할 수 있을것이다.

profile
프롱이

0개의 댓글