현재 진행하고 있는 프로젝트의 CI/CD 스크립트를 작성했습니다.
나의 코드는 제대로 CI를 통과하는데, 함께 개발을 하던 친구의 코드가 CI를 통과하지 못했고,
ApplicationTests > contextLoads() FAILED 에러를 마주했습니다.
해당 에러를 좀 더 자세히 보았습니다.
LetscareerCApplicationTests > contextLoads() FAILED
java.lang.IllegalStateException at DefaultCacheAwareContextLoaderDelegate.java:180
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException at ConstructorResolver.java:795
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException at ConstructorResolver.java:795
Caused by: org.springframework.beans.factory.BeanCreationException at AutowiredAnnotationBeanPostProcessor.java:514
Caused by: java.lang.IllegalArgumentException at PropertyPlaceholderHelper.java:180
OpenJDK 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended
에러를 타고타고 올라가면 아래 에러가 원인임을 느꼈습니다.
Caused by: java.lang.IllegalArgumentException at PropertyPlaceholderHelper.java:180
해당 오류에 대해 구글링해보니 Spring에서 외부 설정 파일을 불러오지 못하는 경우 발생하는 에러임을 알았습니다.
추가로
org.springframework.beans.factory.BeanCreationException at AutowiredAnnotationBeanPostProcessor.java:514
위 에러를 통해 Bean이 제대로 설정되지 않아 Autowired가 안되고 있었습니다.
좀 더 자세히 알아보기 위해 ci 스크립트를 조금 수정했습니다.
빌드를 하는 과정에서 에러가 발생했기에 --stacktrace를 붙여 어떠한 에러가 발생하는지 보았습니다.
./gradlew build --stacktrace
3700 라인을 보고 당황했습니다.
Autowired가 안되는 부분이 있음을 에러를 통해 알았기에 Autowired, BeanCreationException을 중점적으로 찾아보았습니다.
그리고 s3Config가 autowired 되지 않음을 발견했습니다.
배포용 application.yml엔 s3 설정을 위한 환경변수들이 설정되어 있었지만, test를 위한 application.yml엔 s3 설정을 위한 환경변수가 없었기에 발생하는 오류였습니다.
(springboot의 경우 test시 사용되는 application.yml과 main에서 사용되는 application.yml이 다르다는 것도 이번에 처음 알았습니다 ㅎㅎ...)
이를 해결하기위해 s3 설정을 추가한 test용 application.yml을 깃허브 액션 환경변수에 추가하고 CI 스크립트를 다음과 같이 수정하였습니다.
name: ci
on:
push:
branches: [ dev ]
pull_request:
types: [opened, synchronize]
branches: [ dev ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: Set YML file
env:
APPLICATION_PROPERTIES: ${{ secrets.APPLICATION_PROPERTIES }}
TEST_APPLICATION_PROPERTIES: ${{ secrets.TEST_APPLICATION_PROPERTIES }}
run: |
cd ./src
mkdir -p main/resources
echo "$APPLICATION_PROPERTIES" > main/resources/application.yml
rm -rf test/resources/application.yml
echo "$TEST_APPLICATION_PROPERTIES" > test/resources/application.yml
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build with Tests
run: ./gradlew build --stacktrace
- name: Run Asciidoctor
run: ./gradlew asciidoctor
그러니 에러가 사라지고 CI를 통과했습니다.
(달라진 CI에 맞게 CD 스크립트도 수정해줘야 합니다.)
Github Actions를 통한 CI/CD, 배포, 스프링부트 모두 이번이 처음인데 짧은 시간에 에러를 마주하며 많이 배우게 됩니다.