백엔드

github packages를 통한 공통 모듈 개발기

shoon95 2025. 2. 13. 20:50

공통 모듈 개발기

팀 단위로 MSA 프로젝트를 개발하다보니 여러 프로젝트에서 공통으로 사용되고 반복되는 코드와 클래스들이 생겨나게 됐다.

주로 response, ExceptionHandler, Audit table, customArgumentsResolver 등이 공통적으로 사용되고 있었다.

이 부분에서 불필요한 반복을 줄이기 위해 공통 모듈을 개발하고, 다른 모듈에서 의존성을 주입해 사용한 후기를 공유한다.


1. 공통 모듈 개발 방법 선택

공통 모듈을 만들기에 앞서 어떤 방식으로 공통 모듈을 개발하는 것이 가장 좋을까에 대한 고민을 했다.

찾아본 결과 다양한 방법이 있었는데 크게 다음과 같은 세 가지로 구현이 가능했으며 장단점이 존재했다.

  • github packages
    • git을 통해 관리하기에 관리 포인트가 적음
    • 무료 제한 존재
  • maven 사설 저장소
    • Nexus, Artifactory
    • 초기 설장 복잡
    • 팀단위로 안정적 공유 가능
  • AWS S3
    • 익숙한 방식
    • 어차피 git에 올리고 git action을 통해 s3에 빌드한 파일을 관리한다면 굳이 github packages가 아닌 s3 방식을 선택해야 하나?

위와 같은 고민 결과 공통 모듈은 프로젝트에서 핵심점이 부분은 아니기에 관리 포인트를 최대한 줄이기를 바랬고, 또한 우리의 프로젝트 규모를 봤을 때 github packages의 무료 제한 안에서 충분히 해결 가능하다고 판단해 최종적으로 github packages를 통해 공통 모듈을 관리하기로 결정했다.


2. Github Packages

GitHub Packages는 프로젝트의 종속성이나 빌드 아티팩트를 GitHub 레포지토리 내에서 관리하고, 배포할 수 있는 서비스

github packages를 통해 공통 모듈을 개발하고 배포하는 것은 전혀 어렵지 않았다.

공통 모듈의 build.gradle에서 publishing 관련 설정만 진행해주면 끝이었다.

plugins {
  id 'java'
  id 'org.springframework.boot' version '3.3.4'
  id 'io.spring.dependency-management' version '1.1.6'
  id 'maven-publish'
}
​
group = 'com.qticket'
version = '0.0.7'
​
java {
  toolchain {
    languageVersion = JavaLanguageVersion.of(17)
  }
}
​
configurations {
  compileOnly {
    extendsFrom annotationProcessor
  }
}
​
repositories {
  mavenCentral()
}
​
dependencies {
  implementation 'org.springframework.boot:spring-boot-starter-data-jpa:3.3.4'
  implementation 'org.springframework.boot:spring-boot-starter-web:3.3.4'
​
  implementation 'com.h2database:h2:2.2.220'
​
  compileOnly 'org.projectlombok:lombok:1.18.34'
  annotationProcessor 'org.projectlombok:lombok:1.18.34'
​
  testImplementation 'org.springframework.boot:spring-boot-starter-test:3.3.4'
  testRuntimeOnly 'org.junit.platform:junit-platform-launcher:1.10.3'
}
​
publishing {
  publications {
    mavenJava(MavenPublication) {
      from components.java
    }
  }
  repositories {
    maven {
      name = "GitHubPackages"
      url = uri("https://maven.pkg.github.com/QueueTicket/common")
      credentials {
        username = project.findProperty("gpr.user") ?: System.getenv("USERNAME")
        password = project.findProperty("gpr.token") ?: System.getenv("TOKEN")
      }
    }
  }
}
​
tasks.named('test') {
  useJUnitPlatform()
}

위 코드와 같이 설정하면 되는데 순차적으로 정리하면 다음과 같다

  • plugin 추가
    • id 'maven-publish'
  • publishing 설정
    • publications 추가
    • repositories 추가

위와 같이 build.gradle을 작성하고 ./gradlew publish 명령어를 실행하면 git packages로 배포되게 된다.

하지만, 공통 모듈의 버전이 업데이트 될 때마다 수동으로 배포를 하는 것은 매우 귀찮은 일이 될 수 있다. 따라서 github action을 사용해서 이 부분을 자동화하였다.


3. Git Action을 통한 github packages 자동 배포

git action을 통해 github packges 자동 배포 설정은 배우 간단하다.

  1. git action이 실행될 트리거 설정
  2. gradle build
  3. gradle publish

위와 같이 세 단계를 진행하면 된다.

  • .yml여기서 동적 변수로 할당되는 값들은 전부 git에서 자체적으로 제공해주는 값이기에 우리가 환경변수나 secrets로 추가할 필요는 없다!
  • 이 코드를 그대로 복사하고 붙여넣기 하여 사용해도 전혀 문제 없다!
  • name: Gradle Package

    on:
    push:
      tags:
        - 'v*'

    jobs:
    build:
      runs-on: ubuntu-latest
      permissions:
        contents: read
        packages: write

      steps:
      - uses: actions/checkout@v4
      - name: Set up JDK 17
        uses: actions/setup-java@v4
        with:
          java-version: '17'
          distribution: 'temurin'
          server-id: github # Value of the distributionManagement/repository/id field of the pom.xml
          settings-path: ${{ github.workspace }} # location for the settings.xml file

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0

      - name: Build with Gradle
        run: ./gradlew build -x test

       # The USERNAME and TOKEN need to correspond to the credentials environment variables used in
       # the publishing section of your build.gradle
      - name: Publish to GitHub Packages
        run: ./gradlew publish
        env:
          USERNAME: ${{ github.actor }}
          TOKEN: ${{ secrets.GITHUB_TOKEN }}

나는 공통 모듈을 tag를 통한 version를 통한 버전 관리를 진행하기에 tag의 v*(v0.0.1) 가 push 될 때마다 git action이 작동하도록 설정하였다.


4. 버전 관리 및 사용

이제 공통 모듈을 실제로 다시 업데이트하고 재배포하는 과정을 진행 해보자!

먼저 공통 모듈에서 새로운 기능을 개발 또는 업데이트를 완료했다고 가정하고 다음 순서는 build.gradle의 version을 업데이트 하는 것이다. 나는 새로운 기능이 추가되거나 기존 기능이 제거되지 않는 업데이트는 0.0.1에서 0.0.2로 마지막 숫자만 변경하는 식으로 버전을 변경하였다.

  • 공통 모듈 기능 업데이트 완료
  • build.gralde
    • version = '0.0.1' -> version = '0.0.2'

이후 tag를 붙이고 github에 push를 진행하면 된다.

git add .
git commit -m 'refactor: 기능 안정화'
git tag -a v0.0.2 -m 'Release v0.0.2: 버그 수정'
git push origin v0.0.2