🤖

본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.

⚠️

본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.

이미지 로딩 중...

GitHub Marketplace 액션 활용 완벽 가이드 - 슬라이드 1/7
A

AI Generated

2025. 11. 28. · 17 Views

GitHub Marketplace 액션 활용 완벽 가이드

GitHub Actions의 Marketplace에서 검증된 액션을 찾고 활용하는 방법을 배웁니다. checkout, setup-node, artifact 관련 액션의 상세 옵션과 보안 고려사항까지 실무에 필요한 모든 것을 다룹니다.


목차

  1. Marketplace_액션_찾기
  2. actions/checkout_상세_옵션
  3. actions/setup-node_활용
  4. actions/upload-artifact
  5. actions/download-artifact
  6. 버전_지정과_보안_고려

1. Marketplace 액션 찾기

어느 날 김개발 씨는 GitHub Actions 워크플로우를 처음 작성하게 되었습니다. "테스트 자동화를 해야 하는데, 이걸 처음부터 다 만들어야 하나요?" 선배 박시니어 씨가 웃으며 대답했습니다.

"Marketplace에 가면 다 있어요. 바퀴를 다시 발명할 필요 없습니다."

GitHub Marketplace는 전 세계 개발자들이 만든 검증된 액션들이 모여 있는 곳입니다. 마치 앱스토어에서 필요한 앱을 다운로드하듯이, Marketplace에서 원하는 액션을 찾아 바로 사용할 수 있습니다.

이를 활용하면 복잡한 CI/CD 파이프라인도 몇 줄의 설정만으로 구축할 수 있습니다.

다음 코드를 살펴봅시다.

# .github/workflows/example.yml
name: CI Pipeline

on: [push, pull_request]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      # Marketplace에서 가져온 공식 checkout 액션
      - uses: actions/checkout@v4

      # Node.js 환경 설정 액션
      - uses: actions/setup-node@v4
        with:
          node-version: '20'

      # 의존성 설치 및 테스트
      - run: npm ci
      - run: npm test

김개발 씨는 입사 후 첫 번째 큰 과제를 받았습니다. 팀에서 사용하는 프로젝트에 자동화된 테스트 파이프라인을 구축하라는 것이었습니다.

CI/CD라는 말은 많이 들어봤지만, 직접 구축해본 적은 없었습니다. "일단 GitHub Actions를 써보라고 했는데..." 김개발 씨는 공식 문서를 열어보았습니다.

그런데 문서를 읽다 보니 걱정이 앞섰습니다. 코드를 체크아웃하고, 환경을 설정하고, 테스트를 실행하는 모든 과정을 직접 스크립트로 작성해야 하는 걸까요?

그때 옆자리 박시니어 씨가 힌트를 주었습니다. "혹시 Marketplace 확인해봤어요?" GitHub Marketplace는 쉽게 말해 액션들의 앱스토어입니다.

스마트폰에서 필요한 앱을 검색해서 설치하듯이, Marketplace에서는 필요한 기능을 검색해서 워크플로우에 추가할 수 있습니다. 게다가 대부분의 액션은 무료입니다.

Marketplace에 접속하는 방법은 간단합니다. GitHub 상단 메뉴에서 Marketplace를 클릭하거나, 직접 github.com/marketplace로 접속하면 됩니다.

왼쪽 사이드바에서 Actions 카테고리를 선택하면 수천 개의 액션이 나타납니다. 검색창에 원하는 기능을 입력해봅시다.

예를 들어 "node setup"을 검색하면 Node.js 환경을 설정해주는 액션들이 나타납니다. 이 중에서 actions/setup-node라는 액션이 보입니다.

앞에 **actions/**가 붙은 것은 GitHub 공식 액션이라는 뜻입니다. 액션을 클릭하면 상세 페이지가 나타납니다.

여기서 사용 방법, 입력 파라미터, 예제 코드를 확인할 수 있습니다. 특히 Verified creator 배지가 있는 액션은 GitHub이 검증한 믿을 수 있는 액션입니다.

액션을 사용하는 방법은 놀라울 정도로 간단합니다. 워크플로우 파일에서 uses 키워드 뒤에 액션 이름과 버전을 적으면 됩니다.

uses: actions/checkout@v4처럼 말입니다. 이 한 줄로 코드 체크아웃에 필요한 모든 복잡한 작업이 자동으로 처리됩니다.

김개발 씨는 Marketplace를 둘러보며 감탄했습니다. AWS에 배포하는 액션, Docker 이미지를 빌드하는 액션, Slack으로 알림을 보내는 액션까지.

상상할 수 있는 거의 모든 기능이 이미 만들어져 있었습니다. "이거 진짜 편하네요.

근데 아무 액션이나 써도 되는 건가요?" 김개발 씨의 질문에 박시니어 씨가 대답했습니다. "좋은 질문이에요.

별점, 다운로드 수, 그리고 마지막 업데이트 날짜를 꼭 확인하세요. 오래 방치된 액션은 보안 취약점이 있을 수 있거든요." 이제 김개발 씨는 자신 있게 워크플로우를 작성할 수 있게 되었습니다.

Marketplace라는 강력한 무기를 손에 넣었으니까요.

실전 팁

💡 - actions/ 접두사가 붙은 공식 액션을 우선적으로 사용하세요

  • Verified creator 배지와 별점, 다운로드 수를 확인하여 신뢰할 수 있는 액션을 선택하세요
  • 액션의 README와 입력 파라미터를 꼼꼼히 읽어보세요

2. actions/checkout 상세 옵션

김개발 씨가 워크플로우를 작성하는데, 이상한 일이 벌어졌습니다. 분명히 actions/checkout을 사용했는데 서브모듈이 비어 있는 것입니다.

"왜 서브모듈 코드가 없죠?" 박시니어 씨가 설명을 시작했습니다. "checkout 액션은 기본적으로 서브모듈을 가져오지 않아요.

옵션을 알아야 해요."

actions/checkout은 가장 기본이면서도 가장 중요한 액션입니다. 레포지토리의 코드를 Runner 환경으로 가져오는 역할을 합니다.

단순해 보이지만 서브모듈, LFS, fetch-depth 등 다양한 옵션을 제공하며, 이 옵션들을 제대로 활용해야 원하는 결과를 얻을 수 있습니다.

다음 코드를 살펴봅시다.

- name: Checkout with full options
  uses: actions/checkout@v4
  with:
    # 특정 브랜치 체크아웃
    ref: 'develop'

    # 전체 히스토리 가져오기 (기본값: 1)
    fetch-depth: 0

    # 서브모듈 포함
    submodules: 'recursive'

    # Git LFS 파일 가져오기
    lfs: true

    # 다른 레포지토리 체크아웃
    repository: 'owner/other-repo'
    token: ${{ secrets.PAT_TOKEN }}

모든 CI/CD 파이프라인의 첫 번째 단계는 무엇일까요? 바로 소스 코드를 가져오는 것입니다.

actions/checkout은 이 작업을 담당하는 가장 기본적인 액션입니다. GitHub Actions 워크플로우의 99%가 이 액션으로 시작한다고 해도 과언이 아닙니다.

그런데 김개발 씨처럼 기본 사용법만 알고 있다가 낭패를 보는 경우가 많습니다. checkout 액션은 겉보기엔 단순하지만, 내부적으로는 수많은 옵션을 제공합니다.

가장 자주 마주치는 문제가 fetch-depth 관련입니다. 기본값이 1이라는 것을 아는 사람이 얼마나 될까요?

이 말은 가장 최근 커밋 하나만 가져온다는 뜻입니다. 빌드와 테스트에는 문제가 없지만, git log를 보거나 커밋 히스토리 기반으로 무언가를 하려면 문제가 됩니다.

예를 들어 "지난 릴리스 이후의 변경 사항"을 추출하는 스크립트가 있다고 가정해봅시다. fetch-depth가 1이면 이전 커밋 정보가 없으니 스크립트가 실패합니다.

이럴 때는 fetch-depth: 0을 설정해서 전체 히스토리를 가져와야 합니다. 서브모듈을 사용하는 프로젝트라면 submodules 옵션이 필수입니다.

기본적으로 checkout 액션은 서브모듈을 무시합니다. submodules: true를 설정하면 서브모듈도 함께 체크아웃됩니다.

서브모듈 안에 또 서브모듈이 있는 경우라면 submodules: recursive를 사용해야 합니다. Git LFS를 사용하는 프로젝트도 주의가 필요합니다.

대용량 파일을 Git LFS로 관리하고 있다면 lfs: true 옵션을 켜야 실제 파일을 받을 수 있습니다. 그렇지 않으면 포인터 파일만 받게 되어 빌드가 실패할 수 있습니다.

가끔은 현재 레포지토리가 아닌 다른 레포지토리의 코드가 필요할 때도 있습니다. 공통 라이브러리나 설정 파일을 별도 레포지토리에서 관리하는 경우가 그렇습니다.

이때는 repository 옵션에 다른 레포지토리 주소를 적고, token에 해당 레포지토리에 접근할 수 있는 Personal Access Token을 넣어주면 됩니다. ref 옵션을 사용하면 특정 브랜치, 태그, 또는 커밋을 체크아웃할 수 있습니다.

기본적으로는 워크플로우를 트리거한 이벤트의 ref를 사용하지만, 명시적으로 지정하고 싶을 때 유용합니다. 예를 들어 배포 워크플로우에서 항상 main 브랜치를 배포하고 싶다면 ref: 'main'을 설정합니다.

김개발 씨는 이제 이해했습니다. 단순히 uses: actions/checkout@v4만 적는 것이 아니라, 프로젝트의 특성에 맞게 옵션을 설정해야 한다는 것을요.

"앞으로는 옵션을 꼼꼼히 확인해야겠네요." 박시니어 씨가 덧붙였습니다. "그리고 checkout 후에는 작업 디렉토리가 레포지토리 루트로 설정돼요.

이후 단계에서 상대 경로를 사용할 때 이 점을 기억하세요."

실전 팁

💡 - fetch-depth: 0은 전체 히스토리를 가져오므로 필요한 경우에만 사용하세요

  • 프라이빗 레포지토리 체크아웃 시에는 적절한 권한의 토큰이 필요합니다
  • 서브모듈과 LFS 옵션은 빌드 시간에 영향을 주므로 필요할 때만 활성화하세요

3. actions/setup-node 활용

"Node.js 버전이 안 맞아서 빌드가 깨졌어요!" 김개발 씨가 당황한 표정으로 말했습니다. 로컬에서는 잘 되던 빌드가 CI에서는 실패한 것입니다.

박시니어 씨가 워크플로우 파일을 확인했습니다. "setup-node 액션에서 버전을 고정하지 않았네요.

그리고 캐싱도 설정 안 했고요."

actions/setup-node는 Node.js 개발 환경을 구성하는 공식 액션입니다. 단순히 Node.js를 설치하는 것을 넘어서, 원하는 버전을 정확히 지정하고, 패키지 매니저의 캐시를 관리하며, 레지스트리 인증까지 설정할 수 있습니다.

현대적인 JavaScript 프로젝트의 CI/CD에서 빠질 수 없는 필수 액션입니다.

다음 코드를 살펴봅시다.

- name: Setup Node.js with caching
  uses: actions/setup-node@v4
  with:
    # Node.js 버전 지정
    node-version: '20.x'

    # 또는 .nvmrc, .node-version 파일 참조
    # node-version-file: '.nvmrc'

    # 패키지 매니저 캐시 활성화
    cache: 'npm'

    # npm 레지스트리 설정
    registry-url: 'https://npm.pkg.github.com'
    scope: '@myorg'

- name: Install dependencies
  run: npm ci

- name: Publish package
  run: npm publish
  env:
    NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

Node.js 프로젝트를 CI/CD로 자동화할 때 가장 먼저 해야 할 일은 무엇일까요? 당연히 Node.js를 설치하는 것입니다.

하지만 단순히 "Node.js 최신 버전 설치"라고만 하면 안 됩니다. 김개발 씨처럼 버전 불일치로 고생할 수 있기 때문입니다.

actions/setup-node는 이런 문제를 해결해주는 공식 액션입니다. 가장 중요한 기능은 node-version 옵션입니다.

여기에 원하는 버전을 명시하면 항상 그 버전이 설치됩니다. 버전을 지정하는 방법은 여러 가지입니다.

node-version: '20'처럼 메이저 버전만 적으면 해당 메이저의 최신 버전이 설치됩니다. node-version: '20.10.0'처럼 정확한 버전을 적을 수도 있습니다.

node-version: '20.x'node-version: 'lts/*' 같은 패턴도 지원합니다. 팀에서 .nvmrc 파일을 사용하고 있다면 더 좋은 방법이 있습니다.

node-version-file: '.nvmrc'를 설정하면 해당 파일에서 버전을 읽어옵니다. 이렇게 하면 로컬 개발 환경과 CI 환경의 Node.js 버전이 항상 일치합니다.

두 번째로 중요한 기능은 캐싱입니다. npm이나 yarn으로 패키지를 설치할 때마다 매번 다운로드하면 시간이 오래 걸립니다.

cache: 'npm'을 설정하면 node_modules가 아닌 npm 캐시 디렉토리를 캐싱합니다. 다음 실행부터는 이미 다운로드된 패키지를 재사용하므로 설치 시간이 크게 단축됩니다.

yarn을 사용한다면 cache: 'yarn'을, pnpm을 사용한다면 cache: 'pnpm'을 설정하면 됩니다. 각 패키지 매니저에 맞는 캐시 전략이 자동으로 적용됩니다.

npm 패키지를 발행하는 워크플로우라면 registry-url 옵션이 필요합니다. GitHub Packages나 프라이빗 npm 레지스트리를 사용한다면 해당 URL을 지정합니다.

scope 옵션으로 조직 스코프를 설정할 수도 있습니다. 레지스트리 인증은 NODE_AUTH_TOKEN 환경 변수로 처리합니다.

setup-node 액션이 .npmrc 파일을 자동으로 생성하고, 이 환경 변수를 인증 토큰으로 사용합니다. 토큰은 반드시 GitHub Secrets에 저장하고 ${{ secrets.NPM_TOKEN }}처럼 참조해야 합니다.

김개발 씨는 워크플로우를 수정했습니다. node-version을 프로젝트의 .nvmrc 파일을 참조하도록 바꾸고, cache 옵션을 추가했습니다.

다시 실행하니 빌드 시간이 2분에서 40초로 줄어들었습니다. "캐싱 하나로 이렇게 빨라지다니!" 김개발 씨가 놀라워했습니다.

박시니어 씨가 웃으며 말했습니다. "CI/CD 최적화의 핵심은 캐싱이에요.

나중에 의존성 캐싱도 더 깊게 파보면 좋을 거예요."

실전 팁

💡 - .nvmrc 파일을 사용하면 로컬과 CI 환경의 버전을 쉽게 동기화할 수 있습니다

  • cache 옵션만 설정하면 lock 파일 기반으로 자동 캐싱되므로 별도 캐시 키 설정이 필요 없습니다
  • 매트릭스 빌드로 여러 Node.js 버전을 동시에 테스트할 수 있습니다

4. actions/upload-artifact

김개발 씨가 빌드 결과물을 확인하려고 했습니다. "빌드는 성공했는데, 결과 파일은 어디서 보죠?" CI 서버에서 빌드한 파일은 잡이 끝나면 사라집니다.

박시니어 씨가 해결책을 알려주었습니다. "artifact로 저장하면 나중에 다운로드할 수 있어요."

actions/upload-artifact는 워크플로우 실행 중 생성된 파일을 저장하는 액션입니다. 빌드 결과물, 테스트 리포트, 로그 파일 등을 artifact로 업로드하면 워크플로우가 끝난 후에도 다운로드하거나 다른 잡에서 사용할 수 있습니다.

CI/CD 파이프라인에서 잡 간의 데이터 전달에 핵심적인 역할을 합니다.

다음 코드를 살펴봅시다.

# 빌드 잡
- name: Build application
  run: npm run build

- name: Upload build artifacts
  uses: actions/upload-artifact@v4
  with:
    # artifact 이름 (다운로드 시 사용)
    name: build-output

    # 업로드할 파일/폴더 경로
    path: |
      dist/
      build/
      !dist/**/*.map

    # 보관 기간 (기본값: 90일)
    retention-days: 7

    # 파일이 없으면 실패 처리
    if-no-files-found: error

    # 압축 레벨 (0-9, 기본값: 6)
    compression-level: 6

GitHub Actions의 Runner는 워크플로우가 끝나면 깨끗이 정리됩니다. 빌드 중에 생성된 모든 파일은 사라집니다.

그렇다면 빌드 결과물은 어떻게 보관할까요? 바로 artifact를 사용합니다.

artifact는 워크플로우 실행 중에 생성된 파일을 GitHub에 저장하는 기능입니다. actions/upload-artifact 액션을 사용하면 원하는 파일이나 폴더를 artifact로 업로드할 수 있습니다.

가장 기본적인 사용법은 namepath만 지정하는 것입니다. name은 artifact의 이름이고, path는 업로드할 파일 경로입니다.

이 두 가지만 설정하면 해당 파일이 artifact로 저장됩니다. path에는 여러 경로를 지정할 수 있습니다.

파이프(|) 기호를 사용해서 여러 줄로 나열하면 됩니다. glob 패턴도 지원하므로 dist/**/*.js처럼 특정 패턴의 파일만 선택할 수 있습니다.

느낌표(!)로 시작하는 패턴은 제외를 의미합니다. 예를 들어 !dist/**/*.map은 소스맵 파일을 제외합니다.

retention-days 옵션은 artifact의 보관 기간을 설정합니다. 기본값은 90일인데, 프라이빗 레포지토리에서는 저장 공간에 따른 비용이 발생하므로 적절히 조절하는 것이 좋습니다.

일시적인 빌드 결과물이라면 7일 정도면 충분합니다. if-no-files-found 옵션은 지정한 경로에 파일이 없을 때의 동작을 정합니다.

기본값인 warn은 경고만 출력하고 계속 진행합니다. error로 설정하면 파일이 없을 때 워크플로우를 실패 처리합니다.

빌드 결과물처럼 반드시 있어야 하는 파일은 error로 설정하는 것이 안전합니다. artifact는 단순히 결과물을 보관하는 것 외에도 중요한 역할이 있습니다.

바로 잡 간의 데이터 전달입니다. GitHub Actions에서 각 잡은 독립적인 Runner에서 실행됩니다.

한 잡에서 만든 파일을 다른 잡에서 사용하려면 artifact를 통해 전달해야 합니다. 예를 들어 build 잡에서 애플리케이션을 빌드하고, deploy 잡에서 배포한다고 가정해봅시다.

build 잡에서 upload-artifact로 빌드 결과물을 저장하고, deploy 잡에서 download-artifact로 받아서 사용하는 방식입니다. 김개발 씨는 빌드 워크플로우에 upload-artifact를 추가했습니다.

이제 워크플로우가 완료되면 Actions 탭에서 artifact를 다운로드할 수 있습니다. "이제 빌드 결과물을 바로 확인할 수 있겠네요!" 박시니어 씨가 한 가지 팁을 더 알려주었습니다.

"테스트 커버리지 리포트나 Lighthouse 결과 같은 것도 artifact로 저장하면 좋아요. PR에서 바로 확인할 수 있거든요."

실전 팁

💡 - 불필요한 파일(node_modules, 캐시 등)은 업로드하지 마세요. 용량 낭비입니다

  • 민감한 정보가 포함된 파일은 절대 artifact로 업로드하지 마세요
  • 동일한 이름의 artifact가 있으면 덮어쓰기 되므로 버전이나 빌드 번호를 이름에 포함시키는 것을 고려하세요

5. actions/download-artifact

김개발 씨는 빌드와 배포를 분리하고 싶었습니다. 빌드 잡에서 만든 파일을 배포 잡에서 어떻게 가져올 수 있을까요?

"artifact를 업로드했으니, 이제 다운로드하면 되겠네요." 박시니어 씨가 고개를 끄덕였습니다. "맞아요.

download-artifact로 가져오면 됩니다."

actions/download-artifact는 이전에 업로드된 artifact를 다운로드하는 액션입니다. 같은 워크플로우 내의 다른 잡에서 생성된 artifact를 가져오거나, 이전 워크플로우 실행의 artifact를 다운로드할 수 있습니다.

빌드-테스트-배포로 이어지는 파이프라인에서 데이터를 전달하는 핵심 역할을 담당합니다.

다음 코드를 살펴봅시다.

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npm run build
      - uses: actions/upload-artifact@v4
        with:
          name: build-files
          path: dist/

  deploy:
    needs: build  # build 잡이 먼저 완료되어야 함
    runs-on: ubuntu-latest
    steps:
      # 특정 artifact 다운로드
      - name: Download build artifact
        uses: actions/download-artifact@v4
        with:
          name: build-files
          path: ./dist

      # 다운로드된 파일로 배포
      - name: Deploy to server
        run: |
          ls -la ./dist
          # 배포 스크립트 실행

앞서 upload-artifact로 파일을 저장하는 방법을 배웠습니다. 이제 그 파일을 다시 가져오는 방법을 알아보겠습니다.

actions/download-artifact가 바로 그 역할을 합니다. 가장 흔한 사용 시나리오는 멀티 잡 파이프라인입니다.

빌드, 테스트, 배포를 각각 독립적인 잡으로 분리하면 여러 장점이 있습니다. 각 단계가 명확히 구분되고, 실패한 잡만 재실행할 수 있으며, 병렬 실행도 가능합니다.

하지만 각 잡은 서로 다른 Runner에서 실행됩니다. build 잡에서 만든 dist 폴더는 deploy 잡에서 바로 접근할 수 없습니다.

이때 artifact가 다리 역할을 합니다. 먼저 중요한 것은 needs 키워드입니다.

deploy 잡 정의에서 needs: build를 설정하면 build 잡이 성공적으로 완료된 후에만 deploy 잡이 시작됩니다. 이 설정이 없으면 두 잡이 동시에 시작되어 artifact를 찾을 수 없다는 에러가 발생합니다.

download-artifact의 name 옵션에는 다운로드할 artifact의 이름을 적습니다. upload-artifact에서 설정한 이름과 정확히 일치해야 합니다.

path 옵션은 다운로드된 파일을 저장할 위치입니다. 생략하면 현재 디렉토리에 저장됩니다.

name을 생략하면 어떻게 될까요? 그러면 해당 워크플로우에서 업로드된 모든 artifact를 다운로드합니다.

각 artifact는 이름별로 별도의 폴더에 저장됩니다. 여러 artifact를 한 번에 가져와야 할 때 유용합니다.

v4 버전부터는 merge-multiple 옵션이 추가되었습니다. 여러 artifact를 하나의 디렉토리에 병합해서 다운로드할 수 있습니다.

예를 들어 매트릭스 빌드에서 각 OS별로 만든 바이너리를 하나의 폴더로 모을 때 유용합니다. 이전 워크플로우 실행의 artifact를 다운로드하려면 run-id 옵션을 사용합니다.

기본적으로는 현재 워크플로우 실행의 artifact만 접근 가능하지만, run-id를 명시하면 다른 실행의 artifact도 가져올 수 있습니다. 이 기능은 롤백이나 이전 버전 배포에 활용할 수 있습니다.

김개발 씨는 빌드와 배포를 분리한 새로운 워크플로우를 작성했습니다. build 잡에서 upload-artifact로 결과물을 저장하고, deploy 잡에서 download-artifact로 가져와 배포합니다.

"이제 빌드만 다시 하고 싶으면 build 잡만 재실행하면 되겠네요!" 박시니어 씨가 추가 팁을 주었습니다. "테스트 잡도 분리하면 더 좋아요.

build가 끝나면 test와 deploy가 동시에 시작되게 할 수도 있고, test가 통과해야만 deploy가 시작되게 할 수도 있어요."

실전 팁

💡 - needs 키워드로 잡 순서를 명확히 정의하세요. 순서가 맞지 않으면 artifact를 찾을 수 없습니다

  • 다운로드 후 파일 목록을 출력해서 예상대로 받아졌는지 확인하는 습관을 들이세요
  • artifact 이름을 일관성 있게 관리하세요. 오타 하나로 전체 파이프라인이 실패할 수 있습니다

6. 버전 지정과 보안 고려

"이 액션 @master로 되어 있는데, 괜찮은 건가요?" 코드 리뷰 중 박시니어 씨가 질문했습니다. 김개발 씨는 대수롭지 않게 생각했습니다.

"그냥 최신 버전 쓰면 되는 거 아닌가요?" 박시니어 씨의 표정이 심각해졌습니다. "보안 관점에서 매우 위험한 방식이에요."

GitHub Actions에서 액션 버전을 지정하는 방식은 보안과 안정성에 직접적인 영향을 미칩니다. 브랜치명, 태그, 커밋 SHA 등 다양한 방식으로 버전을 지정할 수 있는데, 각각의 장단점과 보안 위험을 이해해야 합니다.

특히 공급망 공격에 대비하기 위해 올바른 버전 지정 방식을 선택하는 것이 중요합니다.

다음 코드를 살펴봅시다.

# 위험: 브랜치 참조 (예측 불가능)
- uses: some-action/action@main

# 권장: 시맨틱 버전 태그
- uses: actions/checkout@v4

# 가장 안전: 전체 커밋 SHA
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11

# Dependabot으로 자동 업데이트 설정
# .github/dependabot.yml
version: 2
updates:
  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "weekly"
    # 커밋 SHA 사용 시에도 업데이트 지원
    allow:
      - dependency-type: "all"

GitHub Actions 워크플로우를 작성할 때, 액션 버전을 어떻게 지정하고 계신가요? 많은 개발자가 이 부분을 대수롭지 않게 생각합니다.

하지만 버전 지정 방식은 보안과 직결되는 중요한 문제입니다. 액션 버전을 지정하는 방법은 크게 세 가지입니다.

브랜치명, 태그, 그리고 커밋 SHA입니다. 각각의 특징을 살펴보겠습니다.

브랜치 참조(@main, @master)는 가장 위험한 방식입니다. 브랜치의 최신 커밋을 항상 가져오기 때문에, 액션 제작자가 악성 코드를 푸시하면 즉시 영향을 받습니다.

심지어 액션 레포지토리가 해킹당해도 마찬가지입니다. 절대 프로덕션 워크플로우에서는 사용하지 마세요.

태그 참조(@v4, @v4.1.0)는 가장 일반적인 방식입니다. 시맨틱 버전을 따르는 태그를 사용하면 메이저 버전 내에서 호환성이 유지됩니다.

@v4는 v4.x.x 중 최신을, @v4.1.0은 정확히 해당 버전을 가져옵니다. 하지만 태그는 이동 가능합니다.

악의적인 제작자가 태그를 삭제하고 다른 커밋에 같은 태그를 붙일 수 있습니다. 커밋 SHA 참조(@b4ffde65f46336ab88eb53be808477a3936bae11)가 가장 안전합니다.

커밋 SHA는 변경할 수 없으므로, 항상 정확히 그 코드를 실행한다는 것이 보장됩니다. 공급망 공격으로부터 보호받을 수 있는 유일한 방법입니다.

그렇다면 모든 액션을 SHA로 고정해야 할까요? 보안 관점에서는 그렇습니다.

하지만 실용적인 문제가 있습니다. SHA는 사람이 읽기 어렵고, 새 버전이 나와도 자동으로 업데이트되지 않습니다.

이 문제를 해결하는 것이 Dependabot입니다. .github/dependabot.yml 파일을 설정하면, Dependabot이 주기적으로 액션 업데이트를 확인하고 PR을 생성합니다.

SHA를 사용하더라도 새 버전이 나오면 해당 버전의 SHA로 업데이트하는 PR을 자동으로 만들어줍니다. 또 한 가지 고려할 점은 액션의 권한입니다.

액션은 워크플로우에 부여된 권한 범위 내에서 동작합니다. secrets에 접근할 수 있고, GITHUB_TOKEN으로 레포지토리를 수정할 수도 있습니다.

신뢰할 수 없는 액션에 이런 권한을 주는 것은 매우 위험합니다. 따라서 액션을 선택할 때는 다음을 확인하세요.

GitHub 공식 액션(actions/ 네임스페이스)인가? Verified creator 배지가 있는가?

오픈소스로 코드를 확인할 수 있는가? 최근에 업데이트되고 있는가?

김개발 씨는 모든 액션을 SHA로 고정하고 Dependabot을 설정했습니다. "처음에는 번거롭다고 생각했는데, 한번 설정해두니 오히려 편하네요." 박시니어 씨가 마무리했습니다.

"보안은 불편함을 감수해야 할 때가 있어요. 하지만 Dependabot 같은 도구를 활용하면 보안과 편의성을 둘 다 잡을 수 있습니다."

실전 팁

💡 - 프로덕션 워크플로우에서는 반드시 커밋 SHA나 특정 버전 태그를 사용하세요

  • Dependabot을 설정해서 보안 업데이트를 자동으로 받으세요
  • 서드파티 액션은 소스 코드를 확인하고, 정말 필요한 권한만 부여하세요

이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!

#GitHubActions#Marketplace#CICD#Workflow#Automation#GitHub Actions,CI/CD,DevOps

댓글 (0)

댓글을 작성하려면 로그인이 필요합니다.