포스트

[GitHub 100일 챌린지] Day 89 - 재사용 가능한 Workflows

[GitHub 100일 챌린지] Day 89 - 재사용 가능한 Workflows

100일 챌린지 Day 89 - Workflow를 재사용하여 중복을 제거합니다.

배울 내용

  1. Reusable Workflows 개념
  2. Workflow 호출하기
  3. 입력과 출력 전달

Reusable Workflows란?

개념

다른 Workflow에서 호출 가능한 Workflow

1
2
3
4
5
6
7
8
9
문제:
- 여러 저장소에서 같은 Workflow 복사/붙여넣기
- 수정 시 모든 곳을 업데이트해야 함
- 유지보수 어려움

해결:
- 공통 Workflow를 한 곳에 정의
- 다른 Workflow에서 호출
- 한 번 수정으로 모든 곳 업데이트

Reusable Workflow 만들기

기본 구조

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# .github/workflows/reusable-build.yml
name: Reusable Build

on:
  workflow_call:  # 호출 가능하게 만들기
    inputs:
      node-version:
        description: 'Node.js 버전'
        required: true
        type: string
    
    outputs:
      build-status:
        description: '빌드 상태'
        value: $

jobs:
  build:
    runs-on: ubuntu-latest
    outputs:
      status: $
    
    steps:
      - uses: actions/checkout@v4
      
      - uses: actions/setup-node@v4
        with:
          node-version: $
      
      - run: npm ci
      
      - id: build
        run: npm run build

Workflow 호출하기

기본 호출

1
2
3
4
5
6
7
8
9
10
# .github/workflows/main.yml
name: Main Workflow

on: push

jobs:
  build:
    uses: ./.github/workflows/reusable-build.yml
    with:
      node-version: '20'

다른 저장소의 Workflow

1
2
3
4
5
jobs:
  build:
    uses: organization/repo/.github/workflows/reusable.yml@main
    with:
      node-version: '20'

버전 지정:

1
2
3
4
5
6
7
8
# 브랜치
uses: org/repo/.github/workflows/reusable.yml@main

# 태그
uses: org/repo/.github/workflows/reusable.yml@v1.0.0

# 커밋 SHA
uses: org/repo/.github/workflows/reusable.yml@abc123

입력과 출력

입력 타입

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
on:
  workflow_call:
    inputs:
      # 문자열
      environment:
        type: string
        required: true
      
      # 숫자
      timeout:
        type: number
        default: 30
      
      # 불리언
      debug:
        type: boolean
        default: false

Secrets 전달

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
on:
  workflow_call:
    secrets:
      api-key:
        required: true
      deploy-token:
        required: false

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: 배포
        env:
          API_KEY: $
        run: deploy.sh

호출 시:

1
2
3
4
5
6
jobs:
  deploy:
    uses: ./.github/workflows/deploy.yml
    secrets:
      api-key: $
      deploy-token: $

모든 Secrets 전달

1
2
3
4
jobs:
  deploy:
    uses: ./.github/workflows/deploy.yml
    secrets: inherit  # 모든 Secrets 상속

실전 예제

공통 테스트 Workflow

재사용 가능한 Workflow:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# .github/workflows/reusable-test.yml
name: Reusable Test

on:
  workflow_call:
    inputs:
      node-version:
        type: string
        default: '20'
      coverage:
        type: boolean
        default: true
    
    outputs:
      test-result:
        value: $

jobs:
  test:
    runs-on: ubuntu-latest
    outputs:
      result: $
    
    steps:
      - uses: actions/checkout@v4
      
      - uses: actions/setup-node@v4
        with:
          node-version: $
          cache: 'npm'
      
      - run: npm ci
      
      - id: test
        run: npm test
      
      - if: inputs.coverage
        uses: codecov/codecov-action@v3

호출:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# .github/workflows/ci.yml
name: CI

on: [push, pull_request]

jobs:
  test-node-18:
    uses: ./.github/workflows/reusable-test.yml
    with:
      node-version: '18'
      coverage: false
  
  test-node-20:
    uses: ./.github/workflows/reusable-test.yml
    with:
      node-version: '20'
      coverage: true
  
  summary:
    needs: [test-node-18, test-node-20]
    runs-on: ubuntu-latest
    steps:
      - run: |
          echo "Node 18: $"
          echo "Node 20: $"

배포 Workflow

재사용 가능한 배포:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# .github/workflows/reusable-deploy.yml
name: Reusable Deploy

on:
  workflow_call:
    inputs:
      environment:
        type: string
        required: true
      version:
        type: string
        required: true
    
    secrets:
      deploy-token:
        required: true

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: $
    
    steps:
      - uses: actions/checkout@v4
      
      - name: 배포
        env:
          TOKEN: $
          VERSION: $
        run: |
          echo "Deploying v$VERSION to $"
          # 배포 스크립트 실행

호출:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# .github/workflows/release.yml
name: Release

on:
  push:
    tags:
      - 'v*'

jobs:
  deploy-staging:
    uses: ./.github/workflows/reusable-deploy.yml
    with:
      environment: staging
      version: $
    secrets:
      deploy-token: $
  
  deploy-production:
    needs: deploy-staging
    uses: ./.github/workflows/reusable-deploy.yml
    with:
      environment: production
      version: $
    secrets:
      deploy-token: $

여러 Job이 있는 Reusable Workflow

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# .github/workflows/reusable-full-ci.yml
name: Full CI

on:
  workflow_call:
    inputs:
      node-version:
        type: string
        default: '20'

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: $
      - run: npm ci
      - run: npm run lint
  
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: $
      - run: npm ci
      - run: npm test
  
  build:
    needs: [lint, test]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: $
      - run: npm ci
      - run: npm run build

호출:

1
2
3
4
5
jobs:
  ci:
    uses: ./.github/workflows/reusable-full-ci.yml
    with:
      node-version: '20'

Matrix와 함께 사용

1
2
3
4
5
6
7
8
9
10
11
12
# 호출하는 Workflow
jobs:
  test:
    strategy:
      matrix:
        node-version: [18, 20]
        os: [ubuntu-latest, windows-latest]
    
    uses: ./.github/workflows/reusable-test.yml
    with:
      node-version: $
      os: $

제약 사항

1
2
3
4
5
6
7
8
9
제약:
- 최대 4단계 중첩 (A → B → C → D까지)
- 같은 저장소: ./.github/workflows/
- 다른 저장소: public이거나 접근 권한 필요
- workflow_call 필수

호출 시:
- uses로만 호출 가능
- steps에서 호출 불가

정리

완료 체크:

  • Reusable Workflow 작성
  • 입력/출력 정의
  • 다른 Workflow에서 호출

핵심 요약:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Reusable Workflow:
- on: workflow_call
- inputs, secrets, outputs 정의
- 다른 Workflow에서 uses로 호출

장점:
- 코드 중복 제거
- 중앙 집중 관리
- 유지보수 용이

사용:
- 공통 CI/CD 패턴
- 조직 표준 Workflow
- 여러 저장소에서 재사용

다음: Day 90 - Actions 디버깅 →


← Day 89 | 전체 커리큘럼 | Day 90 →

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.