컴공생의 다이어리

[GitHub Action] workflow 재사용하기 본문

Development/Git

[GitHub Action] workflow 재사용하기

컴공 K 2024. 8. 28. 03:00

[GitHub Action] workflow 재사용하기

GitHub Action 워크플로우를 작성하다 보면 동일한 프로세스의 워크플로우가 반복되는 경우가 있다. 일부 로직이 변경될 때, 동일한 워크플로우를 모두 수정하거나 변경 사항을 놓치는 경우가 발생할 수 있다. 이로 인해 추가로 수정하고 커밋해야 하는 번거로움이 발생한다. 이런 불편함으로부터 워크플로우를 재사용할 필요성에 대해 느꼈고 이 글에서 워크플로우 재사용하는 방법에 대해 정리하고자 한다.

 

 

 

 

workflow 재사용을 적용해볼 example

워크플로우 재사용을 적용해볼 예시는 다음과 같다. 같은 워크플로우에 client-checkadmin-check job은 실행 조건과 작업 디렉토리 설정 값을 제외한 나머지 로직이 동일하다.

 

 

 

 

재사용 workflow 생성

앞서 본 예시에서 동일한 로직을 재사용 워크플로우로 분리해보자!

 

워크플로우 파일을 재사용 용도로 사용하기 위해서는 아래와 같이 on에 workflow_call을 설정해야 한다.

name: Reusable Build & Lint Test
 
on:
  workflow_call: # 다른 워크플로우에서 이 워크플로우를 재사용(호출)할 수 있도록 설정
    inputs: # 인자 정의
      working_dir: # working 디렉토리 인자
        required: true # 필수 입력 여부
        type: string   # 인자 데이터 타입

 

workflow_call의 inputs를 사용하면 재사용 워크플로우를 호출하는 쪽에서 인자를 받아 내부에서 활용할 수 있도록 설정할 수 있다. 예시에서 중복되는 로직과 연관되는 부분 중 기본 작업 디렉토리를 설정하는 부분을 working_dir로 정의하였다.

(inputs 외에도 secets를 추가하여 민감 정보를 안전하게 전달할 수 있다)

 

 

동일한 로직에 대해 기존 워크플로우 작성 방식과 동일하게 작성해준다. 이때, 작업 디렉토리 설정 부분에만 working_dir 값을 사용할 수 있도록 설정한다.

# .github/workflows/reusable-build-lint-test.yml
name: Reusable Build & Lint Test

on:
  workflow_call:
    inputs:
      working_dir:
        required: true
        type: string

jobs:
  build-test-lint-format:
    runs-on: ubuntu-latest
    defaults:
      run:
       working-directory: ${{ inputs.working_dir }} # 작업 디렉토리 설정
    steps: # 중복되는 로직 작성
      - name: Checkout code
        uses: actions/checkout@v4

      # ... 생략 ...

      - name: Run linter
        run: yarn lint

 

 

 

 

 

재사용 workflow 호출

재사용 워크플로우 사용시 steps 내부에서 중간에 호출할 수 없고 jobs.*.uses 에서만 호출 가능하다. 아래와 같이 uses에 재사용 workflow를 호출하고, 호출시 필요한 인자인 working_dir 값을 with 에 정의한다.

  client-check:
    needs: changes
    if: ${{ needs.changes.outputs.client == 'true' }} # client 변경이 있을 경우 실행
    uses: ./.github/workflows/reusable-build-lint-test.yml # 재사용할 워크플로우 호출
    with: # 재사용 워크플로우에 인자 전달
      working_dir: CLIENT # 작업 디렉토리 인자 설정

 

 

재사용 워크플로우는 내부 워크플로우 뿐만 아니라 다른 외부 저장소에 정의된 워크플로우도 호출 가능하다.(물론 public으로 오픈되어 있거나 접근 권한이 있다는 가정하에..)

  client-check:
    needs: changes
    if: ${{ needs.changes.outputs.client == 'true' }} # client 변경이 있을 경우 실행
    uses: CodeDiary18/TEMP-REUSABLE-WF/reusable-build-lint-test.yml@main # 재사용할 워크플로우 호출
    with: # 재사용 워크플로우에 인자 전달
      working_dir: CLIENT # 작업 디렉토리 인자 설정

 

 

 

 

재사용 workflow의 이점과 적용해보면 좋을 곳

재사용 workflow의 이점
  • 중복된 코드 감소: 중복 코드를 줄여 관리 효율성 향상과 가독성 개선
  • 유지보수 용이: 공통 작업을 하나의 워크플로우로 정의하여 유지보수 간편
  • 신속한 적용: 하나의 파일 수정으로 모든 워크플로우에 변경사항 신속 적용

 

재사용 workflow 적용해보면 좋을 부분
  • CI/CD 파이프라인: 빌드, 테스트, 배포 등의 공통 작업을 재사용하여 설정의 일관성 유지
  • 코드 품질 검사: 린트(lint)나 테스트 실행과 같은 품질 검사 작업을 통합하여 여러 프로젝트에서 재사용
  • 배포 자동화: 다양한 환경에 배포하는 과정을 표준화하여 관리
  • 문서화: 문서 생성 및 배포 작업을 하나의 워크플로우로 관리하여 문서화 프로세스 간소화
  • 환경 설정: 여러 프로젝트에서 공통으로 사용하는 환경 변수나 설정을 통합하여 관리

 

 

 

 

전체 workflow 파일

# main workflow 파일
name: CI

on:
  pull_request:
    branches: [ dev ]

permissions:
  contents: write

jobs:
  changes:
    name: Check for changes # 변경 사항 확인 작업
    runs-on: ubuntu-latest
    outputs:
      client: ${{ steps.filter.outputs.client }}  # client 변경 여부 출력
      admin: ${{ steps.filter.outputs.admin }}    # admin 변경 여부 출력
    steps:
      - uses: dorny/paths-filter@v3
        id: filter
        with:
          token: ${{ secrets.TOKEN }}
          filters: |
            client:
              - 'CLIENT/**'      # CLIENT 디렉토리 변경 감지
            admin:
              - 'ADMIN/**'       # ADMIN 디렉토리 변경 감지

  client-check:
    needs: changes
    if: ${{ needs.changes.outputs.client == 'true' }} # client 변경이 있을 경우 실행
    uses: ./.github/workflows/reusable-build-lint-test.yml # 재사용할 워크플로우 호출
    with: # 재사용 워크플로우에 인자 전달
      working_dir: CLIENT # 작업 디렉토리 인자 설정
      
  admin-check:
    needs: changes
    if: ${{ needs.changes.outputs.admin == 'true' }} # admin 변경이 있을 경우 실행
    uses: ./.github/workflows/reusable-build-lint-test.yml # 재사용할 워크플로우 호출
    with:  # 재사용 워크플로우에 인자 전달
      working_dir: ADMIN # 작업 디렉토리 인자 설정
# 재사용 workflow : .github/workflows/reusable-build-lint-test.yml
name: Reusable Build & Lint Test

on:
  workflow_call:
    inputs:
      working_dir:
        required: true
        type: string

jobs:
  build-test-lint-format:
    runs-on: ubuntu-latest
    defaults:
      run:
       working-directory: ${{ inputs.working_dir }}
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '18'

      - name: Install dependencies
        run: yarn install

      - name: Build the project
        run: yarn build

      - name: Run tests
        run: yarn test --passWithNoTests

      - name: Run formatter check
        run: yarn format

      - name: Run linter
        run: yarn lint

 

 

 

 

 

 

Reusing workflows - GitHub Docs

Learn how to avoid duplication when creating a workflow by reusing existing workflows.

docs.github.com

 

Events that trigger workflows - GitHub Docs

You can configure your workflows to run when specific activity on GitHub happens, at a scheduled time, or when an event outside of GitHub occurs.

docs.github.com

 

728x90
Comments