본문 바로가기
사이드 프로젝트

[CI/CD 프로젝트] GitAction을 통한 CI 구성

by 간장공장공차장 2024. 11. 20.
반응형

GitHub Actions이란

  • GitHub Actions는 코드 변경 사항에 따라 자동으로 워크플로우(빌드, 테스트, 배포 등)를 실행하는 GitHub의 CI/CD 도구입니다.

2. GitHub Actions의 기본 구성 요소

  • Workflow: 하나 이상의 작업을 포함하는 프로세스.
  • Job: 병렬 또는 순차적으로 실행되는 작업의 묶음.
  • Step: 각 Job 안에서 실행되는 개별 명령어 또는 스크립트.
  • Runner: 워크플로우가 실행되는 환경(가상 머신 또는 컨테이너).

다양한 CI 도구가 있지만, 접근의 편의성이 높은 Git Action으로 먼저 CI를 구축해보고자 한다.

실습

💡github action을 통해서 정적 분석을 진행하고, docker build를 진행한다.

아래 와 같이 동작하는 CI 구조를 만들어 본다.

  • git 레파지토리 상단 Actions 클릭

  • workflow 파일 생성

git 브라우저에서도 파일 생성이 가능하고, 경로는 리파지토리 내 .github/workflows/application-build.yml 에 생성된다.

아래는 sonarqube를 통해 지속적 통합 테스트를 진행하고 성공하면 docker build를 통해 이미지를 생성하는 workflow이다.

name: CI Pipeline

on:
  push:
    branches:
      - main
      - 'feature/*'
  pull_request:
    branches:
      - main

jobs:
  sonarqube-analysis:
    runs-on: ubuntu-latest

    steps:
      - name: Check out code
        uses: actions/checkout@v2

      - name: Set up JDK 
        uses: actions/setup-java@v2
        with:
          java-version: '17'

      - name: Run SonarQube analysis
        env:
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
        run: |
          ./gradlew sonarqube -Dsonar.host.url=${{ secrets.SONARQUBE_URL }} -Dsonar.projectKey=your_project_key -Dsonar.login=${{ secrets.SONAR_TOKEN }}

  build-and-push-docker:
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/')

    steps:
      - name: Check out code
        uses: actions/checkout@v2

      - name: Set Docker image tag
        id: docker_tag
        run: |
          if [[ "${{ github.ref }}" == refs/tags/* ]]; then
            IMAGE_TAG=${{ github.ref }}  
            IMAGE_TAG=${IMAGE_TAG#refs/tags/}  # "refs/tags/" 부분 제거
          else
            IMAGE_TAG=latest  # 메인 브랜치에서는 latest 사용
          fi
          echo "TAG=${IMAGE_TAG}" >> $GITHUB_ENV  # 환경 변수에 TAG 저장

      - name: Build Docker image
        run: |
          echo "Building Docker image with tag: ${{ env.TAG }}"
          docker build -t ${{ secrets.DOCKER_USERNAME }}/hellospring:${{ env.TAG }} .

      - name: Push Docker image
        run: |
          echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin
          docker push ${{ secrets.DOCKER_USERNAME }}/hellospring:${{ env.TAG }}
  • on : 어떤 상황에서 workflow가 수행되는지 정의한다. 본 실습에선 feature 브랜치나, main에서 push 또는 pr이 수행되면 실행되도록 설정하였다.
  • job : sonarqube-analysis → build-and-push-docker 가 순차적으로 수행된다.
  • 이미지 빌드 : 버전 control을 위해서 가장 최신의 tag를 가져와 build한다. 배포를 위해서 latest 버전도 같이 배포한다.
  • git에서 보안을 위해서 민감 정보는 모두 secret로 관리하고 있는데, DOCKER_USERNAME, DOCKER_PASSWORD를 secret에서 참조하는 것을 볼 수 있다.

아래와 같이 setting - Secret and variables - Actions에서 설정해준다.

  • 아래 두번째 Repository secrets를 선택하면 변수와 value를 입력할 수 있다.

  • workflow에서 사용한 두개의 secret를 모두 입력하였다.

  • 파일을 생성하게되면, main으로 push가 되기 때문에 trigger조건이 만족되므로 Action이 수행되는 것을 볼 수 있다.
  • 아래와 같이 docker image 빌드가 성공하고, push까지 진행된 것을 볼 수 있다.

(현재 sonarqube의 서버가 내려가 있어 실패한 것은 무시한다. 실제 환경에서는 sonarqube를 통해 지속적으로 테스트하고, 성공한 뒤에 docker build를 진행한다. )

  • docker image 확인

docker hub에 정상적으로 image가 push된 것을 확인할 수 있다.

  • docker images 버전 관리를 수행한다.
git tag -a v1.0.0 -m "릴리즈 버전 1.0.0"
git push ssh-demo-application --tags # 모든 태그 푸시하기

or 

git push ssh-demo-application v1.0.0 # 특정 태그 푸시하기
  • 버전 관리

위에 스크립트를 보면, 버전 관리를 위해 두가지 docker image tag를 생성하여 push하는 것을 볼 수 있다. git 의 tag 기능을 사용하여 버전 별 tag를 붙이고, 버전 관리를 진행할 수 있다.

latest버전과 tag 버전이 모두 push 된 것을 볼 수 있다.

참고)

버전 관리를 위해 tag가 push되었을 때 트리거를 진행시키는 것은 정상적으로 수행되지 않는다. 따라서 버전 관리를 위해 tag값을 가져오는 방향으로 진행한다.

아래 내용 참고)

According to GitHub documentation “When you use the repository’s GITHUB_TOKEN to perform tasks on behalf of the GitHub Actions app, events triggered by the GITHUB_TOKEN will not create a new workflow run […] If you would like to trigger a workflow from a workflow run, you can trigger the event using a personal access token.”.

https://github.com/orgs/community/discussions/27028

  • PAT으로 접근하기

  • (참고) node 프로젝트에서 정상적으로 실행되는지 테스트할 수 있는 스크립트
name: Matrix Testing

on: [push]

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node: [12, 14, 16]

    steps:
      - name: Checkout repository
        uses: actions/checkout@v2

      - name: Setup Node.js
        uses: actions/setup-node@v2
        with:
          node-version: ${{ matrix.node }}

      - name: Install dependencies
        run: npm install

      - name: Run tests
        run: npm test
반응형