Programming/Java

[Java] OSSRH에서 Central Portal로 패키지 배포 마이그레이션하기 (gradle + jreleaser)

SpiralMoon 2025. 6. 27. 21:57
반응형

OSSRH에서 Central Portal로 패키지 배포 마이그레이션하기 (gradle + jreleaser)

OSSRH Nexus Repository 서비스 종료에 따라 Central Portal로 마이그레이션하는 방법을 알아보자

선행 작업

이 문서는 기존 OSSRH를 통해 Java 패키지를 배포하고 있는 개발자 또는 조직에게 해당되는 내용이다. GPG Key가 발급되어 있고 gradle, github 사용을 상정한다.

 

2024.01.02 - [Programming/Java] - [Java] Java 라이브러리 패키지를 Github Actions를 이용하여 Maven central repository에 배포하는 방법

 

[Java] Java 라이브러리 패키지를 Github Actions를 이용하여 Maven central repository에 배포하는 방법

Java 라이브러리 패키지를 Git Actions를 이용하여 Maven central repository에 배포하는 방법자바 라이브러리를 Github Actions을 이용하여 쉽고 빠르게 Maven central에 배포하는 환경을 구축해보자.주의!해당 문

blog.spiralmoon.dev


OSSRH 종료되다

OSSRH 서비스 종료 알림

그 동안 Maven Repository에 Java로 개발된 패키지를 게시하기 위해 전통적인 서비스인 OSSRH를 사용해왔다.

그러나 2025년 6월 30일 서비스 종료공지되면서 Central Portal로의 마이그레이션이 필요해졌다.


Central Portal로 마이그레이션 준비하기

 

Maven Central

Official search by the maintainers of Maven Central Repository.

central.sonatype.com

마이그레이션은 Sonatype Central Portal에서 진행한다. OSSRH 계정 프로필은 Central Portal에서 사용하는 것과 동일하게 통합되었다.

1. 네임스페이스 마이그레이션

계정의 Namespaces 항목으로 들어간다.

 

OSSRH Namespaces 항목에 마이그레이션이 필요한 네임스페이스가 표시된다. Migrate Namespace 버튼 클릭

 

항목을 체크하고 Migrate 버튼 클릭

 

네임스페이스가 Central Portal Namespaces로 옮겨지고 Verified 표시가 됐다면 마이그레이션이 완료되었다는 뜻이다.

이제부터 Central Portal로 패키지를 게시할 수 있다.

2. Token 발급

다른 패키지 저장소와 마찬가지로 인증에 필요한 Token 발급이 필요하다.

계정의 Account 항목으로 들어간다.

 

Generate User Token 버튼 클릭

 

OK 버튼 클릭

 

Token(Username, Password)이 생성된다. 창이 1분 뒤에 자동으로 사라지므로 다른 곳에 빨리 메모해두자. (Token인데 왜 계정 형태로 발급해주는지는 모르겠음)

 

웹 콘솔에서 해야하는 작업은 이것으로 끝.

 

※ NPM, PyPi 등 다른 패키지 저장소들은 개별 권한이 적용된 Token을 여러 개 관리할 수 있으나, Central Portal은 아직 1개의 Token만 관리할 수 있다. 분실하면 굉장히 꼬운 상황이되니 제대로 관리하자.

JReleaser 플러그인을 사용하여 Central Portal에 배포하기

앞서 웹 콘솔에서 준비단계를 마쳤으므로, 이번에는 배포 설정을 수정해야 한다.

 

2025년 6월 23일 기준 gradle 공식 플러그인 미지원 안내

아직까지 gradle 기반의 프로젝트는 Central Portal로의 공식 배포 플러그인이 없기 때문에 커뮤니티 플러그인으로 대체해야한다. (로드맵에 예정되어있다고 하나 언제 추가될지는 모르는 상황이기에...)

 

커뮤니티 플러그인은 여러 종류가 있는데 JReleaser가 맨 위에 있으니 JReleaser 플러그인 기반으로 배포 설정을 변경해보자.

build.gradle에 jreleaser 설정하기

maven-publish 플러그인과 jreleaser 플러그인을 동시하여 gradle 환경에서 패키지를 배포하도록 구성할 수 있다. 우선 아래의 기존 build.gradle을 살펴보자.

(build.gradle에 등장하는 설정 값은 gradle.properties에 할당 되어있어야 함)

 

plugins {
    id 'java-library'
    id 'signing'
    id 'maven-publish'
}

repositories {
    mavenCentral()
}

task sourcesJar(type: Jar) {
    archiveClassifier.set('sources')
    from sourceSets.main.allSource
}

task javadocJar(type: Jar) {
    archiveClassifier.set('javadoc')
    from tasks.javadoc.destinationDir
}

publishing {
    publications {
        mavenJava(MavenPublication) {
            from components.java
            artifact sourcesJar
            artifact javadocJar

            groupId = 'com.example'
            version = '1.0.0'
            artifactId = 'sample-package'

            pom {
                // 생략
            }
        }
    }

    repositories {
        maven {
            name 'OSSRH'
            url uri('https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/')
            credentials {
                username = project.findProperty('ossrhUsername')?.toString()
                password = project.findProperty('ossrhPassword')?.toString()
            }
        }
    }
}

def gpgSecretKey = project.findProperty('gpgSecretKey')
def gpgPassphrase = project.findProperty('gpgPassphrase')

signing {
    useInMemoryPgpKeys(gpgSecretKey, gpgPassphrase)
    sign publishing.publications.mavenJava
}

 

기존 구성은 OSSRH + maven-publish 조합으로, 빌드된 패키지를 gpg key로 사이닝 후 sonatype nexus repository의 staging 저장소에 업로드하도록 되어있었다.

 

여기서 Central Portal + maven-publish + jreleaser 조합으로 설정을 변경해보자.

 

plugins {
    id 'java-library'
    id 'signing'
    id 'maven-publish'
    id 'org.jreleaser' version '1.17.0' // 추가
}

 

첫 번째, 플러그인 항목에 jreleaser를 선언한다.

 

publishing {
    ...

    repositories {
        maven {
            url = layout.buildDirectory.dir('staging-deploy') // 저장소 변경
        }
    }
}

 

두 번째, 빌드 output 경로를 local directory로 변경한다.

 

def githubToken = project.findProperty('githubToken') // 추가

def gpgPublicKey = project.findProperty('gpgPublicKey') // 추가
def gpgSecretKey = project.findProperty('gpgSecretKey')
def gpgPassphrase = project.findProperty('gpgPassphrase')

def centralUsername = project.findProperty('centralUsername') // 추가
def centralPassword = project.findProperty('centralPassword') // 추가

// 추가
jreleaser {
    project {
        gitRootSearch = true
    }

    release {
        github {
            token.set(githubToken)
        }
    }

    signing {
        active = 'ALWAYS'
        armored = true
        mode = 'MEMORY'
        publicKey.set(gpgPublicKey)
        secretKey.set(gpgSecretKey)
        passphrase.set(gpgPassphrase)
    }

    deploy {
        maven {
            mavenCentral {
                sonatype {
                    active = 'ALWAYS'
                    url = 'https://central.sonatype.com/api/v1/publisher'
                    username.set(centralUsername)
                    password.set(centralPassword)
                    stagingRepository('build/staging-deploy')
                }
            }
        }
    }
}

 

세 번째, 기존 사이닝 블록을 제거하고 jreleaser 블록을 새로 추가한다. jreleaser는 local directory에 생성된 패키지 아티팩트에 사이닝을 진행하고 Central Portal로 배포를 수행한다.

 

이전 방식과 비교해서 달라진점 목록 (diff)

  • Staging Repository의 위치가 원격에서 로컬로 변경됨
  • OSSRH 계정 정보 대신 Central Portal Token을 사용하여 인증
  • JReleaser는 GPG Public Key를 필수로 요구함
  • JReleaser는 Git 로그를 추적하므로 github token이 요구됨

배포 명령어 추가하기

앞서 build.gradle에서 repositories의 url을 로컬로 설정하여 publish 명령어가 아티팩트를 더 이상 원격 저장소에 스테이징하지 않고 로컬 디렉토리에 스테이징 하도록 동작이 바뀌었다.

로컬 디렉토리에 스테이징된 아티팩트를 central portal로 배포하기 위해서는 publish 이후에 jreleaserFullRelease 명령어를 실행해야 한다.

 

 

gradle build
gradle publish
gradle jreleaserFullRelease

 

배포 과정 (수정 전)

 

배포 과정 (수정 후)

패키지 배포

변경한 설정대로 배포를 진행하면 이제부터는 Central Portal의 Deployments 탭에서 배포한 패키지를 확인할 수 있다.

 

배포 대기

업로드된 패키지는 Publishing 상태로 표시된다. 아직 인덱싱이 진행중인 단계이므로 repository에 검색해도 표시되지 않는다.

 

배포 완료

시간이 지나면 인덱싱이 완료되어 Published 상태로 전환된다. (30분~1시간 정도 걸림)

이제부턴 repository에서 패키지가 검색된다.


마무리하며

여러 언어로 개발된 패키지를 배포하느라 다양한 로컬/원격 환경의 패키지 저장소를 접해봤지만, Java 진영의 패키지 배포 방식은 타 언어의 배포 방식보다 항상 구축하고 관리하기 번거롭다는 느낌을 지울 수 없었다.

 

레거시인 OSSRH를 이번 마이그레이션 작업에서 제거함으로써 앞으로 패키지 관리가 더 간소화, 현대화 되었으면 좋겠다.

반응형