새로운 pr을 생성하고, 머지할때 두근대는 마음으로 성공 여부를 기다린다.
프로젝트 배포 자동화를 Git Actions을 이용하고 있는데, 5분 가까운 시간이 소요된다는건 오래걸린다 생각이 들어 ci/cd 스크립트를 수정해서 시간을 줄여보도록 한다.
name: CI
on:
pull_request:
branches:
- develop
jobs:
build:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
#CI
- name: Generate environment file
run: |
mkdir -p env
echo "${{secrets.DOCKER_COMPOSE_ENV}}" >> env/docker-compose.env
echo "${{secrets.LOCAL_SPRING_ENV}}" >> env/spring.env
echo "${{secrets.AWS_ENV}}" >> env/aws.env
echo "${{secrets.JWT_ENV}}" >> env/jwt.env
echo "${{secrets.OAUTH2_ENV}}" >> env/oauth2.env
echo "${{secrets.TEST_DB_ENV}}" >> env/test-db.env
- name: Run docker-compose
uses: isbang/compose-action@v1.4.1
with:
compose-file: "./docker/docker-compose.yml"
- name: Get execution permission to gradlew
run: chmod +x ./gradlew
- name: Build with Gradle
run: ./gradlew clean build
기존의 ci 방식을 살펴보면 secrets를 env파일로 변환 후 도커컴포즈 환경에서 빌드하는 방식이다.
시간을 줄일 방법은 그래들 캐싱과 빌드과정 간소화이다.
그래들 캐싱
- name: Caching gradle
uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
그래들 또는 프로퍼티가 변경되는경우 path 하위 폴더를 캐싱한다.
그렇지 않은 경우 캐시된 그래들을 사용한다.
캐시 빌드과정 간소화
- name: Test with Gradle
run: ./gradlew test
빌드는 테스트, 컴파일, jar파일 생성 세가지로 나뉘는데 ci에서는 테스트만 실행하도록 변경했다.
하단에 수정했습니다.
기존에 4분 20초대의 CI 소요 시간이
1분 30초대로 상당히 단축되었다!!
name: CD
on:
push:
branches:
- develop
jobs:
build:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
- name: Generate environment file
run: |
mkdir -p env
echo "${{secrets.DOCKER_COMPOSE_ENV}}" >> env/docker-compose.env
echo "${{secrets.DEV_SPRING_ENV}}" >> env/spring.env
echo "${{secrets.AWS_ENV}}" >> env/aws.env
echo "${{secrets.JWT_ENV}}" >> env/jwt.env
echo "${{secrets.DEV_OAUTH2_ENV}}" >> env/oauth2.env
echo "${{secrets.TEST_DB_ENV}}" >> env/test-db.env
- name: Run docker-compose
uses: isbang/compose-action@v1.4.1
with:
compose-file: "./docker/docker-compose.yml"
- name: Get execution permission to gradlew
run: chmod +x ./gradlew
- name: Build with Gradle
run: ./gradlew clean build
- name: Make zip file
run: zip -qq -r ./$GITHUB_SHA.zip .
shell: bash
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1-node16
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_KEY }}
aws-region: ap-northeast-2
- name: Upload to AWS S3
run: aws s3 cp --region ap-northeast-2 $GITHUB_SHA.zip s3://${{secrets.AWS_S3_BUCKET_NAME}}/$GITHUB_SHA.zip
- name: Code Deploy
run: |
aws deploy create-deployment \
--application-name ${{ secrets.CODE_DEPLOY_APPLICATION_NAME }} \
--deployment-config-name CodeDeployDefault.AllAtOnce \
--deployment-group-name ${{ secrets.CODE_DEPLOY_DEPLOYMENT_GROUP_DEV }} \
--s3-location bucket=${{secrets.AWS_S3_BUCKET_NAME}},bundleType=zip,key=$GITHUB_SHA.zip
cd는 ci와 다르게 restDocs를 사용하기 때문에 그래들 캐싱만 적용했다.
평소에 사용하던 스크립트가 정말 필요한 것인지 한번 더 검토해볼 필요가 있다. 필요하지 않은 과정을 수행하고 있는지, 필요한 과정이 누락되었는지 한번 더 면밀히 살펴보는 시간을 가져보자.
ci과정에서 테스트만 수행하도록 사용했었다. 하지만, ci시에 빌드를 한다면 테스트 단계에서 코드를 실행하기 전에 컴파일 및 패키징 오류 등을 미리 잡아낼 수 있다. 빌드 단계를 건너뛰고 테스트만 진행하면 이러한 오류를 발견할 수 없고, 테스트 실패로 인해 불필요한 디버깅 시간을 허비할 수 있다.
이와 같은 이유로 다시 ci에서 build하도록 변경했다.
결론적으로 ci, cd 모두 build를 하고 있다. 두 번의 빌드는 효율적이지 않다 생각하는데, 그렇다고 ci에서 항상 jar파일을 업로드하면 s3가 부담을 가지는데 좋은 방법이 없을까 생각이 든다.