Github

[Packy] Github Actions과 Flyway를 사용한 엔티티-테이블 매핑 검증 자동화

짱정연 2024. 9. 1. 16:32
반응형

1. 들어가며

 

Spring boot 프로젝트에 Flyway 도입하기 (feat. 기존 데이터가 있을 경우)

Flyway란? Flyway는 데이터베이스의 형상 관리를 목적으로 하는 오픈소스 마이그레이션 툴이다. Flyway를 통해 변경 사항을 추적하고, 업데이트나 롤백을 보다 쉽게 할 수 있다. 우리가 개발하며 필수

leeeeeyeon-dev.tistory.com

 

지금 운영하고 있는 패키 프로젝트에서는 Flyway를 사용하여 DDL 생성을 자동화하고 있다.

Flyway를 사용하면 엔티티와 테이블 매핑이 일치하지 않을 때 애플리케이션 실행에 실패한다. 그렇기 때문에 테이블 컬럼을 수정하지 않아 나중에 서비스를 운영하다가 비즈니스 로직이 실패하는 문제 상황을 예방할 수 있다.

애플리케이션 실행 실패 예시

 

나는 해당 기능을 활용하여 개발/운영 환경을 배포하기 전에 로컬에서 profile을 dev와 prod로 변경한 뒤 애플리케이션을 실행해보며 배포 실패를 방지하고 있다. 최근에는 해당 단계를 깜빡하여 개발 환경 배포 시 애플리케이션 실행에 실패한 경험이 있다 ㅠㅠ

 

이번 포스트에서는 Github Actions에서 애플리케이션 실행을 대신하여 이러한 반쪽짜리 자동화를 발전시켜보자 !

 

2. FlywayApplication

참고로 패키는 멀티 모듈 프로젝트로 구성되어 있으며, 실제 SpringApplication이 실행되는 모듈은 api 모듈이다.

기존에는 flyway 관련 설정을 domain 모듈에서 진행했는데 해당 모듈은 api 모듈과 의존성을 가지고 있어 api 모듈과 독립된 flyway 모듈을 만들어 해당 모듈로 flyway 관련 설정을 옮겼다.

 

@EntityScan(basePackages = {"com.dilly.*"})
@SpringBootApplication
public class FlywayApplication {

    public static void main(String[] args) {
        System.setProperty("spring.config.name",
            "application-domain, application-flyway");

        ConfigurableApplicationContext ctx = SpringApplication.run(FlywayApplication.class, args);
        ctx.close();
    }
}

 

 

Github Actions에서 엔티티-테이블 매핑 검증 자동화를 위해 사용할 애플리케이션이다. 해당 애플리케이션은 검증에만 사용되고 계속 실행될 필요가 없으므로 close 메서드로 애플리케이션을 종료시켜주었다.

 

3. Github Actions 스크립트 수정

name: packy API Server - CI

on:
  pull_request:
    branches:
      - main
      - develop

permissions:
  contents: read

jobs:
  CI:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          token: ${{ secrets.ACTION_TOKEN }}
          submodules: true

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

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v4

      - name: Run build Flyway Module
        run: ./gradlew clean packy-flyway:build

      - name: Run FlywayApplication
        run: java -Dspring.profiles.active=${{ env.PROFILE }} -jar ./packy-flyway/build/libs/packy-flyway-0.0.1-SNAPSHOT.jar
        env:
          PROFILE: ${{ github.ref == 'refs/heads/main' && 'prod' || 'dev' }}

      - name: Run build with Gradle Wrapper
        run: ./gradlew clean build --parallel

      - name: Report to CodeCov
        uses: codecov/codecov-action@v4
        with:
          token: ${{ secrets.CODECOV_TOKEN }}
          file: 'packy-support/build/reports/jacoco/testCodeCoverageReport/testCodeCoverageReport.xml'

 

위 step 중 Run build Flyway Module, Run FlywayApplication이 매핑 검증 단계이고 나머지는 기존 CI 스크립트에 있던 코드이다.

 

gradle build를 할 경우 모든 모듈이 빌드되기 때문에 flyway 모듈만 빌드하도록 하였으며, dev 또는 prod로 profile을 설정하여 FlywayApplication을 실행했다.

 

4. 결과

엔티티와 테이블 매핑이 일치하지 않는 상황을 만들기 위해 Member 엔티티에 임의로 test라는 컬럼을 추가하고 워크플로우를 실행시켜보았다.

@Entity
public class Member extends BaseTimeEntity {
	@Id
	@GeneratedValue(strategy = IDENTITY)
	private Long id;
    
    // 중략 ...

	String test;
}

 

 

스키마 불일치로 인해 어플리케이션 실행에 실패하여 워크플로우가 실패한 모습을 볼 수 있다.

 

5. 마치며

이제는 직접 SpringApplication을 실행해보는 작업을 하지 않아도 배포 이전에 엔티티-테이블 스키마가 일치하는지 확인할 수 있도록 자동화 단계를 추가하였다 :)

기존에 Flyway를 도입한 것도 자동화였지만, 일부 수동 작업이 필요한 자동화였다. 이번 경험을 통해 이미 자동화를 적용한 영역에서도 불편함을 찾아 자동화 단계를 보다 개선할 수 있음을 배웠고, 앞으로도 자동화를 거친 단계에 수동으롤 반복되는 작업이 더 없는가 다시 고민해보고 개선하는 자세로 프로젝트를 관리해야겠다.

 

Reference

반응형