Jreleaser와 Upcoming4j를 활용한 시맨틱 버전 관리
Source: Dev.to
Node.js에서 애플리케이션 릴리스를 완전 자동화하기 위해 **semantic-release npm 패키지**를 사용하면서, **conventional commits**가 버전 계산, git 태깅, changelog 생성, GitHub 릴리스 및 CI‑안전 퍼블리싱을 담당하는 즉시 사용 가능한 워크플로우에 익숙해졌습니다.
Gradle‑Java 프로젝트로 전환했을 때, 동등한 솔루션을 찾지 못했습니다. 생태계를 조사한 결과, **JReleaser**가 Git 태그 생성, changelog 생성, GitHub 릴리스 퍼블리싱을 위한 가장 완전한 도구로 부각되었습니다. 하지만 이 도구는 버전이 미리 정의되어 있기를 기대합니다.
이러한 격차를 메우기 위해 **Upcoming4j**를 만들었습니다. 이는 오직 의미론적 버전 계산에만 초점을 맞춘 가벼운 Gradle 플러그인으로, JReleaser와 원활히 통합되어 소프트웨어 버전 관리를 완전 자동화하도록 설계되었습니다.
다음 단계별 가이드에서는 JReleaser와 Upcoming4j를 통합하여 다음 작업을 자동으로 수행하는 방법을 보여드리겠습니다.
- 버전 번호 증가
- Git 태그 생성
- changelog 생성
- GitHub 릴리스 퍼블리시
— 모두 Git 커밋 히스토리를 기반으로 의미론적 버전 관리를 사용합니다.
전제 조건
-
Sdkman 설치
$ sdk install java 21.0.9-amzn $ java --version -
Git 설치
$ brew install git $ git --version
Step 1: Download Playground Gradle‑Java Project u4j‑playground
**플레이그라운드 프로젝트**를 다운로드하고 압축을 푼 후 로컬 파일 시스템에 저장합니다. 이 프로젝트는 Gradle‑Java 기반이며, JReleaser와 Upcoming4j를 실제로 통합하는 방법을 시연하는 데 사용됩니다.
단계 2: JReleaser 플러그인 설치 및 구성
-
GitHub 저장소를 생성하고 로컬 playground 프로젝트를 원격 저장소에 연결합니다.
-
**이 gist**에서 JReleaser 설정 파일을 다운로드하고 다음 위치에 배치합니다:
/u4j-playground/gradle/jreleaser.gradle -
/u4j-playground/build.gradle에 구성을 적용합니다:plugins { id 'application' // install JReleaser plugin id 'org.jreleaser' version '1.22.0' } // Apply JReleaser configuration apply from: 'gradle/jreleaser.gradle' // Set a hard‑coded version for now version = '1.0.0' repositories { mavenCentral() } dependencies { testImplementation libs.junit.jupiter testRuntimeOnly 'org.junit.platform:junit-platform-launcher' implementation libs.guava } java { toolchain { languageVersion = JavaLanguageVersion.of(21) } } application { mainClass = 'org.example.App' } tasks.named('test') { useJUnitPlatform() }
단계 4: JReleaser 구성 확인
-
GitHub에서 **Personal Access Token (PAT)**을 생성하고 내보냅니다:
$ export JRELEASER_GITHUB_TOKEN=your_token -
변경을 적용하지 않고 릴리스 단계를 미리 보기 위해 dry‑run 모드로 JReleaser를 실행합니다:
$ ./gradlew clean jreleaserRelease \ --no-configuration-cache \ --stacktrace \ --dryrun -
로그를 확인합니다 (예시 스크린샷):
Note:
--dryrun모드에서도 JReleaser는 PAT가 내보내져 있어야 합니다.
Note: JReleaser는 아직 Gradle의 configuration cache와 완전히 호환되지 않으므로--no-configuration-cache플래그가 필요합니다.
단계 5: Upcoming4j 플러그인 설치 및 적용
다음과 같이 /u4j-playground/build.gradle 파일을 편집하여 Upcoming4j 플러그인을 추가하고, 하드코딩된 버전을 Upcoming4j가 계산한 동적 버전으로 교체합니다:
plugins {
id 'application'
// install JReleaser plugin
id 'org.jreleaser' version '1.22.0'
// Install Upcoming4j plugin
id 'io.github.sttamper.upcoming4j' version '0.0.4'
}
// Apply JReleaser configuration
apply from: 'gradle/jreleaser.gradle'
// Set up next version with Upcoming4j
version = nx()
repositories {
mavenCentral()
}
dependencies {
testImplementation libs.junit.jupiter
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
implementation libs.guava
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
application {
mainClass = 'org.example.App'
}
이제 프로젝트 버전이 커밋 기록을 기반으로 자동으로 계산되므로, JReleaser가 태그, changelog, GitHub 릴리스를 생성할 때 올바른 버전을 사용할 수 있습니다.
다음 단계
-
몇 개의 Conventional 스타일 커밋을 수행합니다 (예:
feat: add new feature,fix: correct typo). -
전체 릴리스 명령을 실행합니다:
$ ./gradlew clean jreleaserRelease --no-configuration-cache -
새로운 Git 태그, changelog 항목, GitHub 릴리스가 올바른 시맨틱 버전으로 생성되었는지 확인합니다.
Gradle‑Java 프로젝트를 위한 완전 자동화된 시맨틱 버전 기반 릴리스를 즐기세요!
ks.named('test') {
useJUnitPlatform()
}
5단계: Upcoming4j 구성 확인
Upcoming4j는 Gradle의 설정 단계에서 다음 의미 체계 버전을 계산하여 build.gradle 파일의 version 속성에 항상 올바른 버전이 사용되도록 합니다.
프로젝트 정리
./gradlew clean
최종 단계: 다음 시맨틱 버전 올리기
이제 JReleaser를 실행하여 커밋 기록 분석을 기반으로 Upcoming4j가 계산한 다음 릴리스 버전을 만들 수 있습니다:
./gradlew clean jreleaserRelease --no-configuration-cache --stacktrace 
