본문 바로가기
도구/CICD

[CICD] GitHub Actions 사용 가이드

by webcodur 2024. 9. 24.
728x90

목차

     

     

     

    0. GitHub Actions 종합 가이드 서문

    GitHub Actions는 GitHub이 제공하는 지속적 통합 및 지속적 배포(CI/CD) 플랫폼이다. 이 플랫폼은 소프트웨어 개발 워크플로우를 자동화하고 사용자 정의할 수 있는 기능을 제공한다. 2018년에 베타 버전으로 처음 출시되었으며, 2019년 11월부터 모든 GitHub 저장소에서 사용 가능하게 되었다.

     

    GitHub Actions는 단순한 CI/CD 도구를 넘어서 소프트웨어 개발 lifecycle 전반을 자동화할 수 있는 확장성 있는 플랫폼이다. 이 가이드는 사용자가 GitHub Actions를 효과적으로 구현하고, 개발 프로세스를 최적화하는 데 필요한 정보를 제공한다. 하여 이 문서는 다음과 같은 내용을 안내하는 것을 목표로 하고 있다.


    1. GitHub Actions의 기본 아키텍처와 작동 원리를 설명한다.
    2. 워크플로우 구성 방법과 자동화 파이프라인 설계 과정을 단계별로 제시한다.
    3. 실제 사용 사례와 권장되는 구현 방식을 제공한다.
    4. 초보자부터 전문가까지 다양한 수준의 사용자에게 참조 자료로 활용될 수 있도록 한다.

     

    주의 사항

     

    github actions 이상으로 중요한 것은 실행 환경에서 사용하는 운영체제를 잘 다루는 것이다. 보통 리눅스 운영체제에서 github actions CICD 작업을 수행하므로, 리눅스에 대한 이해도가 필수적이다. 


    본 가이드는 GitHub Actions의 핵심 개념, 구성 요소, 사용 방법 및 모범 사례를 포괄적으로 다룬다.  다음 장부터 GitHub Actions의 각 구성 요소와 기능에 대해 상세히 설명한다.


     

     

     

     

    1. 개요

    GitHub Actions는 소프트웨어 개발 워크플로우를 자동화하기 위한 강력한 CI/CD (지속적 통합/지속적 배포) 플랫폼이다. 이 시스템은 GitHub Repository 에서 발생하는 다양한 이벤트에 반응하여 사용자 정의 워크플로우를 실행할 수 있게 해준다.

    1.1. 주요 구성 요소

    1. 워크플로우 (Workflow): 하나 이상의 작업으로 구성된 자동화된 프로세스
    2. 이벤트 (Event): 워크플로우를 트리거하는 특정 활동 또는 규칙
    3. 작업 (Jobs): 동일한 러너에서 실행되는 단계의 집합
    4. 단계 (Steps): 작업 내에서 실행되는 개별 작업 또는 쉘 명령
    5. 액션 (Actions): 워크플로우에서 자주 반복되는 작업을 수행하는 재사용 가능한 단위

    (워크플로우 구조 예시)

                     +----------------+
                     |    Workflow    |
                     +-------+--------+
                             |
                +------------v------------+
                |         Event           |
                +------------+------------+
                             |
             +---------------v---------------+
             |              Job              |
             |   +-------------------------+ |
             |   |          Step           | |
             |   |  +-------------------+  | |
             |   |  |      Action       |  | |
             |   |  +-------------------+  | |
             |   +-------------------------+ |
             |   |          Step           | |
             |   |  +-------------------+  | |
             |   |  |      Action       |  | |
             |   |  +-------------------+  | |
             |   +-------------------------+ |
             +---------------+---------------+
                             |
             +---------------v---------------+
             |              Job              |
             |   +-------------------------+ |
             |   |          Step           | |
             |   +-------------------------+ |
             |   |          Step           | |
             |   +-------------------------+ |
             +-------------------------------+

     

    각 구성 요소는 YAML 파일을 통해 정의되며, 이 파일은 프로젝트의 .github/workflows 디렉토리에 위치한다.

    1.2. 작동 방식

    1. 지정된 이벤트가 발생하면 워크플로우가 트리거된다.
    2. 워크플로우 내의 각 작업은 새로운 가상 환경 또는 컨테이너에서 실행된다.
    3. 작업 내의 단계들이 순차적으로 실행되며, 각 단계는 액션을 실행하거나 쉘 명령을 수행한다.
    4. 작업들은 기본적으로 병렬로 실행되지만, 필요에 따라 순차적 실행도 가능하다.

    이러한 구조를 통해 GitHub Actions는 코드 테스트, 빌드, 배포 등 다양한 자동화 작업을 효율적으로 수행할 수 있다.


     

     

     

     

    2. 전체 GitHub Actions 워크플로우 구조

    GitHub Actions 워크플로우는 YAML 형식의 파일로 정의된다. 이 파일은 프로젝트 내 .github/workflows 디렉토리에 위치해야 한다.

    2.1. 기본 구조

    보통 yaml 파일을 열면 바로 확인되는 워크플로우 기본 구조는 다음과 같다:

    name: 워크플로우 이름
    
    on:
      [트리거 이벤트]
    
    jobs:
      job1:
        [작업 정의]
      job2:
        [작업 정의]
    

     

    name (선택)

    워크플로우 이름. GitHub 저장소의 Actions 탭에서 이 이름이 표시된다.

     

    on (필수)

    워크플로우를 트리거하는 GitHub 이벤트를 지정한다. 단일 이벤트 문자열, 이벤트 배열, 또는 이벤트 구성 맵을 사용할 수 있다.

     

    jobs (필수)

    워크플로우에서 실행할 작업들을 정의한다. 각 작업은 독립적인 실행 환경에서 수행된다.

     

    2.2. 작동 원리

    1. GitHub 저장소에서 지정된 이벤트가 발생하면, GitHub은 on 필드의 워크플로우를 트리거해야 하는지 결정한다.
    2. 트리거 시, GitHub는 jobs 섹션에 정의된 각 작업을 새로운 가상 환경 또는 컨테이너에서 실행한다.
    3. 각 작업 내 단계들이 순차적으로 실행되며, 이 과정에서 액션이나 쉘 명령을 수행한다.

    이러한 구조를 통해 개발자는 복잡한 CI/CD 파이프라인을 유연하게 정의하고 관리할 수 있다.


     

     

     

     

    3. GitHub Actions 트리거 (on)

    GitHub Actions의 트리거 시스템은 워크플로우가 언제 실행될지를 결정한다. on 키워드를 사용하여 정의되며, 다양한 GitHub 이벤트에 반응할 수 있다.

    3.1. 기본 구문

    on:
      push:
        branches: [ main ]
      pull_request:
        branches: [ main ]
      schedule:
        - cron: '0 0 * * *'
    

    3.3. 주요 트리거 유형

    1. 푸시 (push): 저장소에 코드가 푸시될 때 워크플로우를 실행한다.
    2. 풀 리퀘스트 (pull_request): 풀 리퀘스트가 생성되거나 업데이트될 때 실행된다.
    3. 스케줄 (schedule): 정해진 시간에 주기적으로 워크플로우를 실행한다.
    4. 수동 트리거 (workflow_dispatch): 수동으로 워크플로우를 실행할 수 있게 한다.
    5. 저장소 디스패치 (repository_dispatch): 외부 이벤트에 의해 트리거될 수 있게 한다.

    (사용 팁) 워크플로우 파일 분리 예시: 다음과 같이 각기 푸쉬와 스케줄링 상황을 분리하여 별도의 워크플로우 파일을 관리할 수 있다.

     

    push-workflow.yml:

    on:
      push:
        branches: [ main ]
      pull_request:
        branches: [ main ]
    

     

     

    schedule-workflow.yml:

    on:
      schedule:
        - cron: '0 0 * * *'
    

     

    3.4. 작동 원리

    1. GitHub는 저장소에서 발생하는 모든 이벤트를 모니터링한다.
    2. 이벤트가 발생하면, GitHub는 해당 저장소의 모든 워크플로우 파일을 검사한다.
    3. on 섹션에 명시된 이벤트와 일치하는 워크플로우를 찾으면, 해당 워크플로우를 실행한다.
    4. 워크플로우는 지정된 러너(가상 환경)에서 실행된다.

    트리거 시스템을 통해 개발자는 특정 상황이나 조건에 맞춰 자동화된 작업을 실행할 수 있으며, 이는 CI/CD 파이프라인의 효율성을 크게 향상시킨다.


     

     

     

     

    4. GitHub Actions 작업 (Jobs)

    GitHub Actions의 작업(Jobs)은 워크플로우의 핵심 구성 요소로, 독립적인 실행 환경에서 수행되는 단계들의 집합이다.

    4.1. 기본 구문

    jobs:
      job_id:
        name: 작업 이름
        runs-on: ubuntu-latest
        steps:
          - name: 첫 번째 단계
            run: echo "Hello, World!"
          - name: 두 번째 단계
            run: echo "This is the second step"
    

    4.2. 주요 구성 요소

    1. job_id: 작업의 고유 식별자. 다른 작업에서 이 ID를 참조할 수 있다.
    2. name: GitHub UI에 표시될 작업의 이름 (선택사항).
    3. runs-on: 작업이 실행될 환경을 지정한다. (예: ubuntu-latest, windows-latest)
    4. steps: 작업 내에서 실행될 단계들의 순서를 정의한다. (5챕터에서 상세 안내)

    4.3 작동 원리

    1. 워크플로우가 트리거되면, GitHub는 jobs 섹션에 정의된 각 작업을 확인한다.
    2. 각 작업은 새로운 가상 환경 또는 컨테이너에서 독립적으로 실행된다.
    3. 작업 내의 단계들이 순차적으로 실행되며, 각 단계는 성공 또는 실패로 표시된다.
    4. 모든 단계가 성공적으로 완료되면 작업이 성공한 것으로 간주된다.
    5. 작업들은 기본적으로 병렬로 실행되지만, needs 키워드를 사용하여 순차적 실행을 강제할 수 있다.

    작업 시스템을 통해 개발자는 복잡한 워크플로우를 여러 독립적인 부분으로 나누어 관리할 수 있으며, 이는 CI/CD 파이프라인의 유지보수성과 확장성을 향상시킨다.


     

     

     

     

     

    5. GitHub Actions 단계(Steps)

    GitHub Actions 단계(Steps)는 워크플로우 내 작업(Job)의 실행 단위이다. 각 단계는 쉘 스크립트를 실행하거나 액션(Action)을 사용하여 특정 작업을 수행한다. 단계는 GitHub Actions 워크플로우의 핵심 구성 요소로, 작업을 논리적이고 순차적인 단위로 분할한다. 이를 통해 복잡한 CI/CD 프로세스를 체계적으로 구성하고 관리할 수 있다.

    5.1.기본 구문

    단계의 기본 구문은 다음과 같다:

    jobs:
      job_id:
        steps:
          - name: 첫 번째 단계
            run: echo "Hello, World!"
          - name: 두 번째 단계
            uses: actions/setup-node@v2
            with:
              node-version: '14'
    

    5.2. 주 속성

    name: 단계의 이름을 지정한다. 선택사항이나 워크플로우의 가독성을 위해 권장된다.

    uses: 사용할 액션을 지정한다. 공식 액션, 커뮤니티 액션, 또는 동일 저장소 내의 로컬 액션을 참조할 수 있다.

    run: 실행할 쉘 명령을 지정한다. 단일 명령 또는 여러 줄의 스크립트 실행이 가능하다.

    with: 액션에 전달할 입력 매개변수를 지정한다. 각 액션마다 필요한 매개변수가 다를 수 있다.

    env: 단계 레벨의 환경 변수를 설정한다. 이 변수들은 해당 단계 내에서만 사용 가능하다.

     

    5.3. 실행 순서와 의존성

    단계들은 정의된 순서대로 순차적으로 실행된다. 각 단계는 이전 단계가 성공적으로 완료된 후에 실행된다.

    5.4. 조건부 실행

    'if' 조건문을 사용하여 특정 조건에서만 단계를 실행할 수 있다.

    steps:
      - name: 조건부 단계
        if: github.event_name == 'push'
        run: echo "This step runs only for push events"
    

    5.5. 데이터 공유

    단계 간 데이터를 공유하기 위해 출력 매개변수와 환경 변수를 사용할 수 있다.

    steps:
      - name: 데이터 생성
        id: create_data
        run: echo "::set-output name=my_data::some value"
      - name: 데이터 사용
        run: echo "The data is ${{ steps.create_data.outputs.my_data }}"
    

     

    GitHub Actions의 단계는 워크플로우의 실행 단위로, 각 작업을 작은 단위로 나누어 관리하고 실행할 수 있게 해준다. 이를 통해 복잡한 CI/CD 프로세스를 체계적으로 구성하고 관리할 수 있다.


     

     

     

     

     

    6. GitHub Actions 액션(Actions)

    워크플로우에서 사용되는 재사용 가능한 코드 단위. 복잡하거나 반복적인 작업을 캡슐화하여 워크플로우에서 쉽게 사용할 수 있게 해주는 핵심 기능이다. 작업을 단순화하고 재사용성을 높여 CI/CD 프로세스를 효율적으로 만든다.

    6.1. 액션 유형

    JavaScript 액션

    Node.js로 작성되며, 빠른 실행 시간과 쉬운 설정이 특징이다.

     

    Docker 컨테이너 액션

    Dockerfile로 정의되며, 특정 환경 설정이 필요한 경우 유용하다.

     

    복합 실행 액션

    여러 단계를 하나의 액션으로 그룹화한다.

     

    액션의 구조

    액션은 'action.yml' 파일과 메인 코드 파일로 구성된다. 'action.yml' 파일은 액션의 메타데이터를 정의하며, 메인 코드 파일은 액션의 실제 로직을 구현한다.

     

    6.2. 액션 생성

    액션 생성 과정은 다음과 같다:

    1. 기본 구조 설정: 새 저장소 생성 및 필요 파일 생성
    2. 입력 매개변수 정의: 'action.yml' 파일에서 액션이 받을 입력 정의
    3. 출력 정의: 'action.yml' 파일에서 액션이 생성할 출력 정의
    4. 실행 로직 구현: JavaScript 파일이나 Dockerfile에서 액션의 실제 동작 구현

    6.3. 액션 사용

    액션은 다음과 같은 방법으로 사용할 수 있다:

    1. 공식 액션 사용: GitHub에서 제공하는 공식 액션 사용
    2. 커뮤니티 액션 사용: GitHub Marketplace에서 제공되는 커뮤니티 액션 사용
    3. 커스텀 액션 사용: 직접 만든 액션이나 조직 내부에서 만든 액션 사용

    6.4. 버전 관리

    액션은 버전 태그를 통해 관리된다. 메이저, 마이너, 패치 버전을 사용하여 액션의 변경 사항을 추적하고 관리한다.

    6.5. 보안 고려사항

    액션 사용 시 주의해야 할 보안 사항들은 다음과 같다:

    1. 신뢰할 수 있는 액션만 사용
    2. 액션의 소스 코드 검토
    3. 가능한 경우 특정 커밋 SHA를 참조하여 액션 사용

    6.6. 테스트 및 디버깅

    로컬 환경에서 테스트할 수 있으며, GitHub Actions의 디버그 로깅 기능을 활용하여 디버깅할 수 있다.

    6.7. 게시 및 공유

    만든 액션은 GitHub Marketplace에 게시하여 다른 사용자들과 공유할 수 있다. 이를 통해 커뮤니티에 기여하고 피드백을 받을 수 있다.

    6.8. 주요 공식 액션

    actions/checkout

    저장소 코드를 워크플로우 실행 환경으로 체크아웃한다.

    actions/setup-node

    Node.js 환경을 설정한다.

    actions/cache

    의존성이나 빌드 출력물을 캐시하여 워크플로우 실행 속도를 높인다.

    actions/upload-artifact 및 download-artifact

    워크플로우 실행 간 파일을 업로드하고 다운로드한다.

    6.9. 모범 사례 및 팁

    1. 액션의 목적을 명확히 정의하고 문서화한다.
    2. 입력과 출력을 명확히 지정한다.
    3. 버전 관리를 철저히 한다.
    4. 보안을 항상 고려한다.
    5. 테스트를 철저히 수행한다.

    GitHub Actions의 액션은 CI/CD 프로세스를 더욱 효율적으로 만드는 강력한 도구이다. 액션을 잘 활용하면 워크플로우의 가독성과 유지보수성을 크게 향상시킬 수 있다.


     

     

     

    7. Todo List 예시 서비스를 통한 GitHub Actions 워크플로우 설명


    마지막으로 Todo List 서비스(프론트엔드: React, 백엔드: Node.js)를 위한 GitHub Actions 워크플로우 YAML 파일의 예시이다. 다음 워크플로우는 main 브랜치 push 마다 실행되며, 코드 체크아웃, 종속성 설치, 빌드, 테스트와 배포를 자동화한다.

     

    7.1. yaml 코드 및 파일

    name: Todo List CI/CD
    
    on:
      push:
        branches: [ main ]
    
    jobs:
      build-and-deploy:
        runs-on: ubuntu-latest
    
        steps:
        # 1. 코드 체크아웃
        - name: 코드 체크아웃
          uses: actions/checkout@v2
    
        # 2. Node.js 설정
        - name: Node.js 설정
          uses: actions/setup-node@v2
          with:
            node-version: '14'
    
        # 3. 프론트엔드 종속성 설치 및 빌드
        - name: 프론트엔드 설치 및 빌드
          run: |
            cd frontend
            npm ci
            npm run build
    
        # 4. 백엔드 종속성 설치
        - name: 백엔드 설치
          run: |
            cd backend
            npm ci
    
        # 5. 테스트 실행
        - name: 테스트 실행
          run: |
            cd frontend
            npm test
            cd ../backend
            npm test
    
        # 6. PM2를 사용하여 백엔드 서비스 재시작
        - name: 백엔드 서비스 재시작
          run: |
            cd backend
            pm2 restart app.js || pm2 start app.js
    
        # 7. Nginx를 사용하여 프론트엔드 배포
        - name: 프론트엔드 배포
          run: |
            sudo cp -r frontend/build/* /var/www/html/
            sudo systemctl restart nginx
    
        # 8. 배포 완료 알림
        - name: 배포 완료 알림
          run: echo "배포가 완료되었습니다!"

     

     

    7.2. 상세 설명

    • 코드 체크아웃
      • actions/checkout@v2 액션을 사용하여 저장소의 코드를 워크플로우 실행 환경으로 가져온다.
    • Node.js 설정
      • actions/setup-node@v2 액션을 사용하여 Node.js 버전 14를 설정한다.
    • 프론트엔드 종속성 설치 및 빌드
      • frontend 디렉토리로 이동한 후, npm ci를 실행하여 종속성을 설치한다.
      • npm run build를 실행하여 프론트엔드 애플리케이션을 빌드한다.
    • 백엔드 종속성 설치
      • backend 디렉토리로 이동한 후, npm ci를 실행하여 종속성을 설치한다.
    • 테스트 실행
      • 프론트엔드와 백엔드 모두에 대해 npm test를 실행하여 테스트를 수행한다.
    • 백엔드 서비스 재시작
      • PM2를 사용하여 백엔드 서비스를 재시작한다.
      • 서비스가 이미 실행 중이면 재시작하고, 그렇지 않으면 새로 시작한다.
    • 프론트엔드 배포
      • 빌드된 프론트엔드 파일들을 Nginx의 서비스 디렉토리로 복사한다.
      • Nginx를 재시작하여 변경사항을 적용한다.
    • 배포 완료 알림
      • 배포 완료 메시지를 출력한다.

    7.3. 주의사항

    • 이 워크플로우는 Ubuntu 최신 버전에서 실행된다.
    • PM2와 Nginx가 서버에 사전 설치되어 있어야 한다.
    • 실제 환경에서는 보안 강화를 위해 환경 변수와 시크릿을 사용해야 한다.
    • 프로덕션 환경에서는 추가적인 보안 검사와 승인 단계를 고려해야 한다.

    이 워크플로우는 기본적인 CI/CD 파이프라인을 구현하며, 프로젝트의 요구사항에 따라 추가적인 단계나 조정이 필요할 수 있다.