Custom GitHub Actions 개발 | Composite·JavaScript·Docker Action 완전 정리

okorion·2025년 12월 6일

📡 GitHub Actions

목록 보기
9/11
post-thumbnail

GitHub Actions는 공개 Action을 조합해 CI/CD를 구성할 수 있지만, 실무에서는 “우리 팀만의 표준 동작”을 재사용 가능한 Action으로 만들어야 한다.
Custom Action은 Composite / JavaScript / Docker Action 세 종류이며, 구조적 차이를 이해하면 선택과 구현이 명확해진다.

이 글은 Custom Actions의 구조를 기능 단위로 분해하고, 가장 많이 요구되는 AWS S3 배포용 Action 예제까지 제공한다.


1. Custom GitHub Actions의 구조적 분류

종류실행 방식장점단점
Composite Action여러 Step을 YAML로 묶음개발 가장 쉬움복잡한 로직에는 부적합
JavaScript ActionNode 환경에서 JS 실행빠름, 로직 구현 용이Node 런타임 필요
Docker ActionDocker 컨테이너에서 실행실행환경 완전 제어빌드·이미지 관리 필요

세 종류 모두 동일한 Action 메타데이터 파일(action.yml)로 정의된다.


2. Composite Action: 여러 Step을 묶어 재사용

Composite Action은 “여러 Step을 하나의 Action처럼 묶는 기능”이다.
Team 단위 공통 빌드·포맷·테스트 흐름을 통합할 때 적합하다.

Composite Action 구조

my-action/action.yml

name: "My Composite Action"
runs:
  using: "composite"
  steps:
    - run: echo "Hello ${{ inputs.name }}"
inputs:
  name:
    required: true

Workflow에서 사용

steps:
  - uses: ./.github/actions/my-action
    with:
      name: "World"

Composite Action의 핵심:

  • Step 기반 기능만 묶을 수 있음
  • Node/npm 등 별도의 실행환경은 없음

3. JavaScript Action: Node 기반 실행 로직 구현

JavaScript Action은 Node.js 환경에서 JS 파일을 실행하는 방식이다.
외부 API 호출·파일 처리·데이터 변환 등 “로직 중심” 구현에 적합하다.

action.yml

name: "JS Action"
runs:
  using: "node20"
  main: "index.js"
inputs:
  message:
    required: true

index.js (최소 예제)

const core = require("@actions/core");

function run() {
  const msg = core.getInput("message");
  console.log(`Message: ${msg}`);
}

run();

Workflow에서 사용

steps:
  - uses: ./.github/actions/js-action
    with:
      message: "Hello JS Action"

장점:

  • 로직 구현 자유도 높음
  • 속도 빠름

단점:

  • Node 버전 호환성 관리 필요
  • 패키지 설치 후 node_modules 포함해 배포해야 함

4. Docker Action: 실행환경을 완벽히 통제

Docker Action은 컨테이너 내부에서 실행되므로 OS·언어·패키지 버전을 완전히 통제할 수 있다.

action.yml

name: "Docker Action"
runs:
  using: "docker"
  image: "Dockerfile"
inputs:
  path:
    required: true

Dockerfile

FROM node:18
WORKDIR /app
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]

entrypoint.sh

#!/bin/sh
echo "Path: $1"

Workflow에서 사용

steps:
  - uses: ./.github/actions/docker-action
    with:
      path: "./dist"

Docker Action은 다음 상황에서 필수다.

  • 시스템 패키지 설치 필요
  • DB client tool 필요(psql, mysql 등)
  • 대규모 애플리케이션 빌드

5. 비교: Composite vs JS vs Docker

기능CompositeJSDocker
개발 난이도가장 쉬움중간높음
실행 속도빠름매우 빠름느림
실행환경 제어낮음중간매우 높음
복잡한 로직어려움적합적합
시스템 패키지 필요불가능Node 패키지만가능

선택 기준:

  • 빠르고 간단 → Composite
  • 로직 중심 → JavaScript
  • 환경 완전 통제 → Docker

6. Secrets와 Custom Action

Custom Action에서 Secrets를 받는 경우 반드시 inputs로 받아 env로 전달해야 한다.

# action.yml
inputs:
  token:
    required: true

runs:
  using: composite
  steps:
    - run: echo "Using token"
      env:
        TOKEN: ${{ inputs.token }}

주의:

  • Secrets는 절대 출력 금지
  • Docker Action에서도 ENTRYPOINT로 직접 전달 가능하지만 echo하지 않도록 해야 함

7. 실무 예제: AWS S3 배포 Custom Action (Composite)

AWS CLI가 runner에 설치되어 있으므로 Composite Action이 가장 적합하다.

7.1 action.yml

.github/actions/s3-deploy/action.yml

name: "Deploy to S3"
inputs:
  bucket:
    required: true
  region:
    required: true
  dist-path:
    required: true
  aws-access-key-id:
    required: true
  aws-secret-access-key:
    required: true

runs:
  using: "composite"
  steps:
    - run: aws configure set aws_access_key_id ${{ inputs.aws-access-key-id }}
    - run: aws configure set aws_secret_access_key ${{ inputs.aws-secret-access-key }}
    - run: aws s3 sync ${{ inputs.dist-path }} s3://${{ inputs.bucket }} --region ${{ inputs.region }}

7.2 Workflow에서 사용

steps:
  - uses: actions/checkout@v4

  - uses: ./.github/actions/s3-deploy
    with:
      bucket: "my-app"
      region: "ap-northeast-2"
      dist-path: "./dist"
      aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
      aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

실무 적용 가능하며 S3 정적 배포 환경에 바로 사용된다.


8. 보안 및 운영 주의사항

1) Secrets를 로그에 출력하면 안 됨

Custom Action 내부에서도 echo 금지.

2) JS Action은 node_modules를 반드시 포함해 저장

런타임에 npm install을 시키면 Actions 속도가 크게 느려짐.

3) Docker Action은 빌드 시간이 추가로 들어감

이미지를 GitHub Container Registry(GHCR)에 미리 푸시하는 방식을 고려.

4) Composite Action 내부에서 checkout을 중복 사용하는 실수

필요한 위치에서만 사용.

5) Custom Action은 버전 태그를 명확히 관리

Action 재사용 시 @v1, @v1.1.0 등 버전 태그 필수.


9. 핵심 개념 정리

  • Composite Action: Step 묶음. 구현 쉬움.
  • JavaScript Action: Node 기반 로직 실행.
  • Docker Action: 컨테이너 기반. 환경 완전 제어.
  • action.yml: 모든 Action의 메타 정보.
  • S3 배포 Action은 Composite 형태가 가장 효율적.
  • Secrets는 inputs로 전달, echo 금지.

Custom Action은 CI/CD 플랫폼을 “팀 내부 개발 플랫폼”으로 확장하는 핵심 기술이다.


10. 실수하기 쉬운 포인트

  • JS Action에서 node_modules 누락
  • Dockerfile ENTRYPOINT에서 Secrets 출력
  • Composite Action 내부에서 GitHub Context를 잘못 참조
  • Action 버전 태그 미관리 → 예측 불가능한 동작
  • docker build와 Docker Action 혼동
  • Custom Action을 workflow_call와 혼동

Custom Actions를 정확히 이해하면 팀 전체의 자동화 품질을 높은 수준으로 통일할 수 있다.

profile
Tech Blog

0개의 댓글