Dev/Infra | Cloud

Github Actions | contextLoads() FAILED 해결하기

vanss 2022. 11. 2. 02:11
본 글은 사이드 프로젝트 진행 시, 트러블 슈팅한 경험을 기록하기 위함입니다.
피드백은 언제든지 환영입니다. 🤩

 

상황

로컬에서 동일한 에러가 발생을 했었고 그때 당시에는 yml파일(MySQL의 연결 정보를 담은)을 설정으로 등록해주는 Config 클래스에서 classpath가 잘못되어 수정을 해줬더니 해결을 할 수 있었다. 그리고 나서 main branch에 PR을 하였고 CI.yml이 작동하였는데 ./gradlew test 단계에서 똑같은 에러인 context load() FALED 에러가 발생하였다.

 

원인

Github Action 환경에서 MySQL Server가 안 띄워져 있기 때문에 해당 DB를 찾지 못해서 생기는 에러라고 생각했었다.

 


1차 해결시도 - 실패

MySQL Server를 띄워주기 위해서, CI.yml 스크립트에 Setup을 위한 스크립트를 아래와 같이 추가한 뒤에 다시 테스트를 실행해봤지만 실패했다.

(user와 password는 Github Secret을 활용하여 환경변수로 넣는 게 가장 안전하지만 우선 에러가 해결되는지 확인이 필요했다.)

name: CI

...
            
      - name: Setup MySQL
        uses: samin/mysql-action@v1
        with:
          host port: 3306
          container port: 3306
          character set server: utf8
          mysql database: oauth
          mysql user: root
          mysql password: 1234
        
      - name: Grant execute permission for gradlew
        run: chmod +x gradlew

      - name: Test with Gradle
        run: ./gradlew test
        
...

MySQL Server를 Docker Container로 띄우기 위해 스크립트를 2가지 방식으로 실행해봤다.

...

       - name: create mysql docker container  
         run: |
           sudo docker run -d -p 3306:3306 --env MYSQL_DATABASE=oauth --env MYSQL_PASSWORD= --env MYSQL_ROOT_PASSWORD= mysql:8.0.23

...

 

2차 해결시도 - 성공

2차 해결을 시도하기 전까지 1차 시도했던 방법에서 각종 경우의 수를 수정해봤었는데 해당 내용들은 너무 자잘하고 많아서 생략했다. Github Action 환경에서 docker ps로 MySQL Server Container가 정상적으로 띄워진 것을 확인했었던 터라 더욱 막막했었는데 1차 시도를 하던중, MySQL Server Container가 실행되고 나서 MySQL Server 프로그램이 구동이 되기도 전에./gradlew test 스크립트가 실행되버리는게 아닌가?라는 의견이 나왔었다.

 

위 가설을 증명하기 위해 우리는 CI.yml 스크립트에다가, MySQL Server에서 동작을 하고 있다는 신호가 발생하기 전까지 Sleep을 걸어보기로 하였다. 아래와 같이 CI.yml에서 docker check 부분을 추가하였고 결과는 성공적으로 MySQL Server에 접근하여 에러를 해결할 수 있었다.!

...

      - name: create mysql docker container
        run: |
          sudo docker run -d --name vans -p 3306:3306 --env MYSQL_DATABASE=oauth --env MYSQL_ROOT_PASSWORD=1234 mysql:8.0.23
          
      - name: Grant execute permission for gradlew
        run: chmod +x gradlew
        
      - name: docker check
        run: |
          docker ps
          while ! docker exec vans mysql --user=root --password=1234 -e "SELECT 1" >/dev/null 2>&1; do 
            sleep 2 
            echo "waiting for mysql.."
          done
          
      - name: Test with Gradle
        run: ./gradlew test --stacktrace
        
...

왼쪽은 1차시도 했을때 MySQL Server 띄우기만 했을 때고, 오른쪽은 Sleep을 줬던 2차 시도 결과이다.

정상적으로 Test With Gradle(./gradlew test)이 통과된것을 볼 수 있다.