[개인프로젝트] github actions build 에러
개인프로젝트도 배포를 하려고 github actions를 생성했다. 그러나... build에러가 계속 터지고..나의 시도 노력들...
이거말고 더 있답니다... 거의 50번정도..? ㅋㅋㅋㅋ
문제 상황
에러코드 보면 결국에는 application.properties의 값들을 못찾아서 그런거 같았다.
java.lang.IllegalStateException at DefaultCacheAwareContextLoaderDelegate.java:143
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException at PlaceholderConfigurerSupport.java:230
Caused by: java.lang.IllegalArgumentException at PropertyPlaceholderHelper.java:180
음... gitignore에 application넣어서 그런건가?? 싶어서 테스트용 application.properties를 생성해주었다..
그러나..
이런 에러도 만낫다.
SpringApplicationTests > contextLoads() FAILED
java.lang.IllegalStateException at DefaultCacheAwareContextLoaderDelegate.java:98
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException at ConstructorResolver.java:800
Caused by: org.springframework.beans.factory.BeanCreationException at ConstructorResolver.java:658
Caused by: org.springframework.beans.BeanInstantiationException at SimpleInstantiationStrategy.java:185
Caused by: java.lang.IllegalStateException at Assert.java:97
아 에러 투성이네...
문제 원인
찾아보니 repository 테스트코드 때문이었다. repository테스트코드의 경우 mysql과 연동하여 실행중이었으며 redis뿐만아니라 elasticsearch또한 연결이 되어야지 테스트 코드가 성공하는 케이스 였다.
그래서..
name: Java CI with Gradle
on:
push:
branches: [ "develop" ]
pull_request:
branches: [ "develop" ]
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
- name: Make application.properties
run : |
touch ./src/main/resources/application-test.properties
echo "${{ secrets.DATABASE_PROPERTIES }}" >> ./application-test.properties
cat ./src/main/resources/application-test.properties
- name: Setup MySQL
uses: samin/mysql-action@v1
with:
mysql database: 'walker'
mysql user: 'dogWalker'
mysql password: '${{ secrets.DATABASE_PROPERTIES }}'
- name: Start Redis
uses: supercharge/redis-github-action@1.1.0
with:
redis-version: 6
- name: ElasticSearch Setup
uses: DreamsOfImran/elasticsearch-action@v1.0
with:
elasticsearch version: '7.17.4'
- name: grant execute permission for gradlew
run: chmod +x gradlew
- name: Build with Gradle
run: ./gradlew build
workflow를 수정했다. mysql, redis, elasticsearch를 셋업해주었다.
그럼에도 계속 에러가 나왔다.
WalkerInfoResponseRepositoryImplTest > 해당 날짜 예약된 날짜+시간 보내기 FAILED
java.lang.IllegalStateException at DefaultCacheAwareContextLoaderDelegate.java:143
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException at AutowiredAnnotationBeanPostProcessor.java:767
Caused by: org.springframework.beans.TypeMismatchException at TypeConverterSupport.java:79
Caused by: java.lang.NumberFormatException at NumberFormatException.java:67
ReserveDistributeTest > 예약 중복 진행시 분산락 기능 성공 FAILED
java.lang.IllegalStateException at DefaultCacheAwareContextLoaderDelegate.java:143
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException at PlaceholderConfigurerSupport.java:230
Caused by: java.lang.IllegalArgumentException at PropertyPlaceholderHelper.java:180
에러들을 자세하게 보기 위해 workflow에 옵션?을 추가하였다.
- name: Build and test
run: ./gradlew clean build --info
그랬더니 springboot가 띄어지는 로그까지 보여지면서 아주 자세하게 에러가 나오기 시작했다.
org.springframework.beans.factory.BeanDefinitionStoreException:
Invalid bean definition with name 'com.project.dogwalker.member.client.goolge.GoogleClient'
defined in null: Could not resolve placeholder 'google.auth.url' in value "http://${google.auth.url}"at
아 @SpringBootTest와 @SpringBatchTest때문에 모든 스프링빈들이 로드하는데 환경변수가 없어서 에러가 나오는구나..
정리하자면
- application.properties에 필요한 환경변수가 없어서 에러
- mysql과 같은 테스트 db가 없어서 에러
해결 방법
아근데 생각해봣는데 굳이 mysql를 workflow에 추가해야할까?? 그냥 h2인메모리 데이터베이스를 사용하는 방법을 없을까?? 해서 찾아보니 가능했다.
1. build.gradle에 h2데이터베이스를 추가
implementation 'com.h2database:h2'
2. test용 application.properties를 생성 및 sql파일 생성
google.client.id=test
google.client.pw=test
google.login.url=test
google.redirect.url=test
google.auth.url=test
#naver
naver.token.url=test
naver.client.id=test
naver.client.pw=test
naver.login.url=test
naver.redirect.url=test
naver.user.info.url=test
#aws
aws.s3.folder=test
aws.s3.bucket=test
aws.s3.accessKeyId=test
aws.s3.secretKey=test
aws.s3.region=test
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
spring.flyway.enabled=false
spring.jpa.hibernate.ddl-auto=none
#data source
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_LOWER=TRUE
spring.datasource.username=sa
spring.datasource.password=
#Batch
spring.batch.jdbc.initialize-schema=always
spring.batch.job.enabled=false
logging.level.org.springframework.batch=DEBUG
#redis
spring.data.redis.host=127.0.0.1
spring.data.redis.port=6379
#elastic
logging.level.org.springframework.data.elasticsearch.client.WIRE=TRACE
logging.level.org.springframework.data.elasticsearch.core=debug
spring.main.allow-bean-definition-overriding=true
spring.elastic.url=localhost:9200
spring.search.distance=3
#security
security.jwt.expire-length=36000000
security.jwt.secret-key=testfejoncdkgnoiegndklvnwioejklddxciowedcnendkjaeigbucneskasjdkj
security.refresh.expire-length=604800
위에 google,naver관련해서 추가한 이유는 앞서 말했듯이 모든 스프링빈들을 로드한다. 그과정에서 저 value값이 필요한 클래스들이 있는데 해당 value값이 없으면 에러가 터져서 test라고 간단하게 추가하였다.
추가적으로 sql파일을 따로 만든 이유는 spring batch관련 create table이 mysql과 h2가 다르기때문이다.
그래서 schema.sql파일을 생성하여 테스트 h2용 create table파일을 생성하였다.
3. 테스트코드에 profile 추가
@ActiveProfiles(profiles = "test")
이후 workflow에 mysql관련 설정들과 application.properteis생성해주는 설정을 빼주고 다시 ci테스트를 해봤더니..
룰루!!! 아주 build 테스트가 잘된다
거의 한달동안 고민하였다... 왜 안될까...왜..?? 한달동안 이거만 고민했던 건 아니다. 일단 협업프로젝트하면서 코드짜고 가끔식 왜 안되는지 테스트도 해보고...
다행히 해결되었다..아 통쾌해 기분 좋아...!!
근데 그거알아?? jenkins쪽에서 build할때 다른 에러 터진다..??하하하ㅏ하하하하하하ㅏ하하하하하하