본문 바로가기

Diary/TIL

2024-05-19) CI/CD with github action에 대한 고찰

다음과 같은 방식으로 구현됐는데, 

러닝커브가 부족했던 것 같다.

 

하지만 이거에 대한 전략을 따로 생각했었어야 했을 것 같다.(git convcention과 같은 형식으로다가)

개인적인 생각으로는

  • CI 과정:
    • 코드가 dev 브랜치에 푸시되거나 풀 리퀘스트가 생성될 때 실행된다.
    • 빌드, 테스트, 정적 분석을 통해 코드 검증을 수행한다.
    • 테스트 리포트와 코드 커버리지 리포트를 생성하여 업로드한다.
  • CD 과정:
    • 풀 리퀘스트가 dev 브랜치에 병합될 때 실행된다.
    • 최종 빌드 및 배포 작업을 수행한다.

이렇게 분류해서 yml을 작성하는것도 괜찮았을 것 같은데 시간이 좀더 널널했으면 개선을 해보지 않았을까? 생각이 들었다.

name: Java CI with Gradle

on:
  push:
    branches: [ "dev" ]
  pull_request:
    branches: [ "dev" ]

jobs:
  build-and-test:
    runs-on: ubuntu-latest
    services:
      redis:
        image: redis
        ports:
          - 6379:6379

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

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

      - name: Cache Gradle packages
        uses: actions/cache@v3
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper
          key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
          restore-keys: ${{ runner.os }}-gradle

      - name: Grant execute permission for gradlew
        run: chmod +x ./gradlew

      - name: Build with Gradle
        run: ./gradlew clean build

      - name: Run tests with Gradle
        run: ./gradlew test

      - name: Generate test reports
        uses: actions/upload-artifact@v2
        with:
          name: test-reports
          path: build/reports/tests/test

      - name: Upload test coverage
        uses: actions/upload-artifact@v2
        with:
          name: code-coverage
          path: build/reports/jacoco/test

  static-analysis:
    runs-on: ubuntu-latest

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

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

      - name: Cache Gradle packages
        uses: actions/cache@v3
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper
          key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
          restore-keys: ${{ runner.os }}-gradle

      - name: Grant execute permission for gradlew
        run: chmod +x ./gradlew

      - name: Run static analysis
        run: ./gradlew check

 

# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle

name: Java CD with Gradle

on:
  pull_request_target:
    types: [closed]
    branches: [ "dev" ]

jobs:

  build:
    runs-on: ubuntu-latest
    services:
      redis:
        image: redis
        ports:
          - 6379:6379
    steps:
      - uses: actions/checkout@v2

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

      - name: Create directory for application.yml
        run: mkdir -p ./src/main/resources/

      - name: Create directory for TEST application.yml
        run: mkdir -p ./src/test/resources/

      - name: Generate application.yml
        run: echo "${{ secrets.APPLICATION_PROPERTIES_CONTENT }}" > ./src/main/resources/application.yml

      - name: Generate TEST application.yml
        run: echo "${{ secrets.TEST_APPLICATION_PROPERTIES_CONTENT }}" > ./src/test/resources/application.yml

      - name: Gradle Caching
        uses: actions/cache@v3
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper
          key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
          restore-keys: |
            ${{ runner.os }}-gradle-
      - name: Grant execute permission for gradlew
        run: chmod +x ./gradlew
        shell: bash

      - name: Build with Gradle
        run: ./gradlew clean build

      - name: Docker build & push to docker repo
        run: |
          docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }}
          docker build -f Dockerfile -t ${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKER_REPO }}:${{ github.run_number }} .
          docker push ${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKER_REPO }}:${{ github.run_number }}
  deploy:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ap-northeast-2
      - name: AWS EC2 Connection
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.EC2_HOST_DEV }}
          username: ${{ secrets.EC2_USER }}
          key: ${{ secrets.EC2_PEM }}
          port: ${{ secrets.EC2_PORT }}
          timeout: 60s
          script: |
            sudo docker pull ${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKER_REPO }}:${{ github.run_number }}
            sudo bash deploy-githubActions.sh ${{ github.run_number }}
            sudo docker image prune -f