Maven Central 포털의 Gradle 플러그인을 사용한 방식으로 라이브러리를 배포하는 방법을 정리한 글입니다.
2024년 3월 12일부터 issues.sonatype.org는 폐쇄되어 모든 등록은 중앙 포털을 통해 이루어지도록 변경되었습니다. 기존 Nexus repository(OSSRH)로 올리는 방식을 사용하던 사용자는 기존 방식을 그대로 사용할 수 있지만, 신규 사용자라면 Maven Central을 통해서 라이브러리를 배포해야 합니다.
1. Maven Central 계정 설정
따로 도메인이 존재하는 경우 지침서에 따라 Namespace를 등록 하시면 됩니다. 참고로 github는 io.github.사용자이름 형식입니다.
아래의 공식 홈페이지에 github 소셜 로그인을 하면 번거로운 작업 없이 Namespace를 자동으로 등록해 주는 것을 확인할 수 있습니다.
참고로 2024년 3월 12일 전에 기존 OSSRH를 사용하던 방식으로 도메인을 등록한 경우에는 Namespace를 새로 등록해 주지 않고 AddNamespace를 통해 등록 하려 해도 아래와 같은 오류를 보게 됩니다.
해당 링크 하단에서 Central Support 팀 메일로 현재 로그인한 Maven Central 계정 ID, 이메일과 현재 계정으로 마이그레이션 하려는 Namespace 명, Namespace URL 정보를 보내면 답장으로 더 필요한 것을 요구하고(정말 동의 하냐는 등) 해당 계정으로 Namespace를 마이그레이션 해 줍니다. (저는 1일 걸렸습니다.)
2. GPG 키 생성
gpg 다운로드
먼저 window 기준으로 라이브러리 배포에 필요한 gpg 키를 생성하기 위해서는 아래의 사이트에서 Gpg4win 을 다운로드 받아줍니다.
다운로드는 그냥 기본값으로 모두 Next 눌러주고 다운로드 했습니다.
버전 확인
다운로드가 잘 되었는지 확인하는 방법은 터미널을 열고 gpg --version 명령어를 사용하시면 됩니다.
$ gpg --version
gpg (GnuPG) 2.4.5
libgcrypt 1.10.3
Copyright (C) 2024 g10 Code GmbH
License GNU GPL-3.0-or-later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Home: C:\\Users\\YYC30\\AppData\\Roaming\\gnupg
Supported algorithms:
Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA
Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
CAMELLIA128, CAMELLIA192, CAMELLIA256
Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB, BZIP2
버전 정보가 나온다면 다음 단계로 gpg key를 발급해야 합니다.
gpg key 발급
아래의 key 발급 명령어를 입력한 후 이름, 이메일, 사용할 비밀번호 등을 입력해 주면 됩니다. 이때 작성한 비밀번호(password)는 라이브러리 배포 시 사용하기 때문에 메모장에 적어둡니다.
$ gpg --gen-key
생성된 key 확인
key를 발급 받았다면 생성된 키를 아래의 명령어로 확인합니다. 주석으로 적어둔 끝 8 자리가 key ID며 라이브러리 배포 시 사용하기 때문에 메모장에 적어둡니다.
$ gpg --list-keys
[keyboxd]
---------
pub ed25519 2024-05-08 [SC] [expires: 2027-05-08]
703DFBAE436FFD068FDDE14EA5E971A363196272 // 끝 8자리(63196272)가 key ID
uid [ultimate] dami325 <wnekfa1004@naver.com>
sub cv25519 2024-05-08 [E] [expires: 2027-05-08]
gpg key 를 서버에 등록
아래의 명령어로 공개 키 서버에 배포해줍니다. 뒤의 숫자8자리는 Key ID 입니다.
- Maven Central Repository에서 사용하는 공개 키 서버는 3가지가 있습니다. 이 중 아무곳이나 보내도 상관 없다고 하는데 저는 keyserver.ubuntu.com 서버로 보냈습니다.
$ gpg --keyserver keyserver.ubuntu.com --send-keys 63196272
gpg: sending key A5E971A363196272 to hkp://keyserver.ubuntu.com
signing.pgp 파일 생성
배포 시 필요한 key 파일을 export(gpg --export-secret-keys 63196272 > {원하는 경로}) 합니다. 이때 작성한 경로는 라이브러리 배포 시 사용하기 때문에 메모장에 적어둡니다.
$ gpg --export-secret-keys 63196272 > C:\\dev/signing.pgp
3. 프로젝트 Gradle 설정
gpg key 생성이 끝났다면 이제 배포를 위한 설정을 하면됩니다.
가장 먼저 플러그인을 추가해줍니다. 현재기준(2024-05-08) Maven Central에 게시하기 위한 공식 Gradle 플러그인이 없기 때문에 공식 사이트에서 제공하는 대체 플러그인 ‘vanniktech/gradle-maven-publish-plugin’ 을 사용했습니다.
build.gradle 에 플러그인 추가
plugins {
id "com.vanniktech.maven.publish" version "0.28.0" // 대체 플러그인
id 'signing' // GPG 서명을 위한 플러그인 추가
}
Maven Central 구성
포털을 통해 게시하기 때문에 CENTRAL_PORTAL로 설정합니다. import 는 꼭 해주세요. 참고로 signAllPublications() 는 Gradle의 maven-publish 플러그인에 포함된 기능 중 하나로, 배포되는 모든 출판물(artifacts)에 디지털 서명을 추가하는 작업을 수행합니다.
import com.vanniktech.maven.publish.SonatypeHost
mavenPublishing {
publishToMavenCentral(SonatypeHost.CENTRAL_PORTAL)
signAllPublications()
}
POM 구성
coordinates는 네임 스페이스, 라이브러리 이름, 버전 순서로 작성해주시면 되고, 라이선스 같은 경우 저는 배포할 프로젝트의 github repository 에서 LICENSE 파일을 만들면 제공되는 템플릿으로 등록했습니다. scm 설정에 대한 설정은 주석을 참고해주세요.
mavenPublishing {
coordinates("io.github.dami325", "excel-utils", "0.0.5") // 네임 스페이스, 라이브러리 이름, 버전 순서로 작성
// POM 설정
pom {
/**
name = '[라이브러리 이름]'
description = '[라이브러리 설명]'
url = '[오픈소스 Repository Url]'
*/
name = 'excel-utils'
description = 'SpringBoot Excel Download Library'
url = '<https://github.com/dami325/excel-utils>'
// 라이선스 정보
licenses {
license {
name = 'Apache License'
url = '<https://github.com/dami325/excel-utils/blob/master/LICENSE>'
}
}
// 개발자 정보
developers {
developer {
id = 'dami325'
name = 'Judalm Park'
email = 'wnekfa1004@naver.com'
}
// 다른 개발자 정보 추가 가능...
}
/**
connection = 'scm:git:github.com/[Github 사용자명]/[오픈소스 Repository 이름].git'
developerConnection = 'scm:git:ssh://github.com/[Github 사용자명]/[오픈소스 Repository 이름].git'
url = '<https://github.com/>[Github 사용자명]/[오픈소스 Repository 이름]/tree/[배포 브랜치명]'
*/
scm {
connection = 'scm:git:github.com/dami325/excel-utils.git'
developerConnection = 'scm:git:ssh://github.com:dami325/excel-utils.git'
url = '<https://github.com/dami325/excel-utils/tree/master>'
}
}
}
build.gradle 전문
import com.vanniktech.maven.publish.SonatypeHost // import 꼭 해주세요
plugins {
id 'java'
id "com.vanniktech.maven.publish" version "0.28.0"
id 'signing' // GPG 서명을 위한 플러그인 추가
}
// Maven 그룹 및 버전 설정
group = 'io.github.dami325'
version = '0.0.5'
repositories {
mavenCentral()
}
tasks.withType(Javadoc) {
options {
encoding 'UTF-8'
}
}
signing {
sign publishing.publications
}
// Maven Publishing 블록 설정
mavenPublishing {
signAllPublications() // Gpg 서명을 위한 설정
publishToMavenCentral(SonatypeHost.CENTRAL_PORTAL) // 포탈로 등록 할거기 때문에 타입 추가
coordinates("io.github.dami325", "excel-utils", "0.0.5") // 네임 스페이스, 라이브러리 이름, 버전 순서로 작성
// POM 설정
pom {
/**
name = '[라이브러리 이름]'
description = '[라이브러리 설명]'
url = '[오픈소스 Repository Url]'
*/
name = 'excel-utils'
description = 'SpringBoot Excel Download Library'
url = '<https://github.com/dami325/excel-utils>'
// 라이선스 정보
licenses {
license {
name = 'Apache License'
url = '<https://github.com/dami325/excel-utils/blob/master/LICENSE>'
}
}
// 개발자 정보
developers {
developer {
id = 'dami325'
name = 'Judalm Park'
email = 'wnekfa1004@naver.com'
}
// 다른 개발자 정보 추가 가능...
}
/**
connection = 'scm:git:github.com/[Github 사용자명]/[오픈소스 Repository 이름].git'
developerConnection = 'scm:git:ssh://github.com/[Github 사용자명]/[오픈소스 Repository 이름].git'
url = '<https://github.com/>[Github 사용자명]/[오픈소스 Repository 이름]/tree/[배포 브랜치명]'
*/
scm {
connection = 'scm:git:github.com/dami325/excel-utils.git'
developerConnection = 'scm:git:ssh://github.com:dami325/excel-utils.git'
url = '<https://github.com/dami325/excel-utils/tree/master>'
}
}
}
dependencies {
... 생략
}
4. 라이브러리 배포
build.gradle을 모두 작성 했다면 gradle.properties 파일을 프로젝트 루트 경로에 추가해주고 아래의 정보를 입력해 주어야 합니다.
mavenCentralUsername , mavenCentralPassword 설정 정보는 사이트의 View Account → Generate User Token → Ok 를 누르면 나오는 username 과 password 를 각각 작성하시면 됩니다. 참고로 설명드리면 유효기간이 있고 Ok를 누를 때마다 발급되는 토큰이라 배포 시 계속 바뀌는 정보입니다.
gradle.properties
// maven central account 토큰 정보
mavenCentralUsername= // 공식 사이트의 토큰 username
mavenCentralPassword= // 공식 사이트의 토큰 password
// gpg 관련
signing.keyId= // key 뒤 8자리 값
signing.password= // key 발급 시 입력한 gpg password
signing.secretKeyRingFile= // gpg export 한 파일 경로 ex) C:/dev/signing.pgp
해당 정보는 외부로 노출되면 안되는 정보기 때문에 주의합니다.
명령어로 배포실행
작성이 완료 되었다면 프로젝트에서 터미널 명령어를 실행합니다. 인텔리제이 Gradle 탭의 Tasks/publishing/ 하위에 있는 publishAllPublicationsToMavenCentralRepository 를 더블클릭 으로 실행해도 같은 동작입니다.
$ ./gradlew publishAllPublicationsToMavenCentralRepository
토큰 발행 후 일정 시간이 지나서 실패할 경우 아래의 에러 메시지가 뜨는데 당황하지 말고 토큰을 재발행해서 값을 입력해 주시면 됩니다.
Upload failed: {"error":{"message":"Invalid token"}}
배포명령어가 성공적으로 이루어졌다면 사이트의 Deployments를 확인해 보면 Drop 과 publish가 활성화된 것을 볼 수 있습니다. 잘못 배포한 경우 Drop을 눌러 지워주시면 되고 Publish 버튼을 눌러 라이브러리 발행을 계속 진행합니다.
Publish를 누르면 유효성검사가 진행되는데 대부분 몇분 내로 진행된 것 같습니다. 두레이 메신저 같은 업무 툴을 사용해 사이트의 View WebHooks 메뉴를 통해 웹 훅을 등록해 두레이 메신저로 알람을 받을 수 있으니 참고하시면 좋을것 같습니다.
배포가 정상적으로 이루어져 PUBLISHED 상태로 변경된다면 사이트의 Search 검색을 통해 등록한 라이브러리 정보를 확인할 수 있고 사용할 프로젝트에서 의존성을 추가해준다면 여러 프로젝트에서 사용 가능한 라이브러리 배포가 완료됩니다.
build.gradle.kts 사용 코드
dependencies {
implementation("io.github.dami325:excel-utils:0.0.5")
}
참고 자료