직접 제작한 Kotlin 라이브러리를 Maven Central에 배포하기

kshired·2024년 6월 7일
3

세상에는 많은 라이브러리가 존재합니다. 이런 라이브러리 덕분에, 우리는 직접 기능을 구현하지 않고도 많은 기능등을 편하게 사용할 수 있습니다.

하지만, 언제나 원하는 기능이 라이브러리로 나와있지는 않습니다. 그런 경우에는 기능을 직접 구현해서 사용해야하는데요. 만약 그 기능이 다른 많은 프로젝트에서도 필요로한다면, 우리는 복사 붙여넣기 혹은 라이브러리로 만들어서 배포하기 등의 여러 방안을 고민하게 됩니다.

저도 이러한 고민을 하다 자주쓰던 기능을 라이브러리로 만들고 배포를 진행하게 되었는데요. 이 과정이 생각보다 정리되어 있지 않아서, 배포하는 과정을 공유해보려합니다.

Maven Central 설정

Maven Central은 Apache Maven 프로젝트의 공식적인 중앙 저장소로, 의존성을 관리하고 오픈 소스 프로젝트들을 전 세계 개발자에게 배포할 수 있는 플랫폼입니다.

Maven Central은 현재 Sonatype이라는 회사에서 관리하고 있으며, Maven Central에 라이브러리를 배포하기 위해 sonatype에서 계정을 생성해야합니다.

Sonatype 계정 생성 및 namespace 등록

계정 생성

먼저, https://central.sonatype.com/ 에 들어가서 계정을 생성해봅시다.

계정 생성은 일반적인 회원가입 과정과 동일하므로 그냥 진행하면 됩니다.

namespace 등록

계정을 생성하고 나서는 namespace 등록이 필요합니다.

namespace는 GroupId라고도 불리며, 프로젝트나 조직을 식별하는데 사용됩니다.
예를 들어, kotlin 공식 라이브러리의 org.jetbrains.kotlin 같은 것이 namespace라고 할 수 있습니다.

https://central.sonatype.com/publishing/namespaces 에 접속하여, Add namespace를 눌러줍니다.

만약 자신의 GitHub 계정을 namespace로 사용한다면, 아래의 Add Namespace의 입력창에 "io.github.계정명" 을 입력하면 됩니다.

도메인을 namespace로 사용한다면, 다음의 예시와 같이 도메인을 거꾸로 입력하면 됩니다.

www.springframework.org -> org.springframework
subdomain.example.com -> com.example
my-domain.com -> com.my-domain

namespace 인증

이렇게 namespace를 추가하고 나면, namespace의 소유주가 맞다는 것을 인증해야합니다.

  • GitHub을 namespace로 사용한다면, 위에서 나온 verification key를 이름으로 가진 GitHub 레포지토리를 하나 추가하고 verify namespace를 누르면 됩니다.

  • 만약 자신의 도메인을 namespace로 사용한다면, DNS에서 TXT 레코드를 하나 추가하는 방식으로 인증을 진행할 수 있습니다.

이 과정을 성공적으로 진행하고 나면, 아래와 같이 해당 namespace에 대해 인증을 받게됩니다.

User Token 생성

이제 배포에 사용할 user token을 만들어야합니다. GitHub의 personal-access-token 같은 것을 생각하면 이해하기 쉬울 것입니다.

https://central.sonatype.com/account 에 접속하여, Generate User Token 을 클릭해줍니다.

위 버튼을 클릭하게 되면, username password 쌍의 User Token이 생성되며 추후에 사용해야하니 잘 메모해두면 됩니다.

GPG 설정

Sonatype 외에도 추가적으로 설정을 해야하는게 있습니다. 바로 GPG 설정인데요. GPG(GNU Privacy Guard)는 공개키 암호화 방식의 도구로, 주로 소프트웨어의 무결성과 출처를 검증하기 위해 사용됩니다.

우리가 Maven 프로젝트를 배포할 때, GPG 서명을 통해 사용자들이 해당 라이브러리가 신뢰할 수 있는 출처에서 온 것임을 확인할 수 있습니다.

GPG 키 발급

만약 gpg가 설치되어 있지 않다면, 각 OS에 맞게 설치하시고 진행하시면 됩니다.

macOS에서는 Homebrew를 통해 brew install gnupg 명령어를 입력하여 간단하게 설치가 가능합니다.

설치가 완료되었다면, 아래의 명령어를 통해 gpg key를 발급합니다.

gpg --full-gen-key

key를 발급하게 되면 여러가지 선택지가 나오게 되는데, 아래와 같이 선택해주면 됩니다.

  • key kind : RSA and RSA
  • key size : 4096
  • key expire in : key의 만료 일자를 적절히 선택

추가로, 이름과 이메일 그리고 비밀번호까지 잘 설정해주도록 합니다.

GPG 공개키 업로드

우리는 이렇게 만든 gpg 공개키를 키 서버에 업로드하여, 비밀키를 생성할 것입니다.

공개키를 업로드함으로써, 파일이 업로드된 공개키로 서명되었는지를 다른 사람들이 확인할 수 있습니다.

gpg 공개키는 gpg --list-keys 를 통해 조회할 수 있으며, 조회되는 키의 뒤 8글자를 아래 명령어에 입력하면 됩니다.

gpg --keyserver keys.openpgp.org --send-keys GPG공개키

GPG 비밀키 생성

이제 공개키를 업로드하였다면, 비밀키를 생성해야합니다. 비밀키는 아래 명령어를 통해 생성할 수 있습니다.

gpg --keyring secring.gpg --export-secret-keys > ~/.gnupg/secring.gpg

이렇게 생성한 비밀키는 배포시에 사용됩니다.

Gradle 배포 설정

이제 배포를 위한 토큰과 키 값등의 준비는 다 되었으니, 프로젝트의 gradle에 배포 설정을 해볼 차례입니다.

gradle.properties 설정

여태까지 설정하고 만들어왔던 토큰과 키 값들을 사용하여, gradle.properties에 아래와 같이 값을 설정합니다.

mavenCentralUsername = USERNAME_TOKEN
mavenCentralPassword = PASSWORD_TOKEN
signing.keyId = GPG_PUBLIC_KEY
signing.password = GPG_PRIVATE_KEY_PASSWORD
signing.secretKeyRingFile = SECRET_KEY_PATH
  • mavenCentralUsername과 mavenCentralPassword 에는 Sonatype에서 발급한 UserToken 정보를 입력
  • signing.keyId, signing.password, signing.secretKeyRingFile 에는 GPG 설정을 통해 획득한 공개키, 비밀번호, 비밀키 위치를 입력

주의 : git에는 업로드되면 안되는 내용입니다. 로컬에서 배포할때만 추가로 세팅하거나, GitHub Actions 등을 통해 배포를 진행할 때 secret을 통해 관리해야합니다.

build.gradle.kts 설정

이제 gradle plugin을 통해, 배포를 하기위한 설정을 해봅시다.

이 글에서는 com.vanniktech.maven.publish 플러그인을 사용하여 배포를 진행해볼 예정입니다.

아래와 같이 설정하면 됩니다.

import com.vanniktech.maven.publish.SonatypeHost

plugins {
	id("com.vanniktech.maven.publish") version "0.28.0" // maven 배포 플러그인
}

mavenPublishing {
	// 이 세가지가 합쳐져서 implementation("io.github.username:my-library:1.0.0") 과 같이 사용됩니다.
    coordinates(
        groupId = "io.github.username", // namespace
        artifactId = "my-library", // 배포하려는 library artifact id
        version = "1.0.0" // version
    )

    pom {
        name.set("My Library") // 라이브러리 이름
        description.set("Description of library") // 라이브러리 설명
        inceptionYear.set("2024") // 라이브러리 시작 년도
        url.set("https://github.com/username/my-library") // 라이브러리 배포 url

        licenses {
            license { // 라이센스 이름과 라이센스 정보 url 세팅
                name.set("The Apache License, Version 2.0")
                url.set("https://www.apache.org/licenses/LICENSE-2.0.txt")
            }
        }

        developers {
            developer { // 개발자 정보 세팅
                id.set("user id")
                name.set("user name")
                email.set("user email")
            }
        }

        scm { // source code management 정보
            connection.set("scm:git:git://github.com/username/my-library.git")
            developerConnection.set("scm:git:ssh://github.com/username/my-library.git")
            url.set("https://github.com/username/my-library")
        }
    }

    publishToMavenCentral(SonatypeHost.CENTRAL_PORTAL) // maven central 배포 위치 설정

    signAllPublications() // 배포 gpg signing 설정
}

위와 같이 설정하였다면, 이제 배포를 진행해봅시다.

배포하기

배포 진행

배포는 간단하게 아래의 명령어를 입력하여 진행할 수 있습니다.

./gradlew publishAndReleaseToMavenCentral --no-configuration-cache

gradle task에 성공하면, https://central.sonatype.com/publishing/deployments 에서 아래와 같이 배포 상태를 체크할 수 있습니다.

배포는 Publishing -> Published 상태로 진행되며, 첫 배포에는 1시간 이상의 시간이 걸릴 수 있습니다.

사용하기

위의 배포가 끝나고 나면 (Published 상태가 되면), Maven Central에서 검색이 가능해지고 gradle 혹은 maven 설정을 통해 라이브러리 사용이 가능해집니다.

예를들어 Gradle(kotlin) 에서는, 아래와 같이 의존성을 추가하면 배포된 라이브러리를 사용할 수 있습니다.

dependencies { 
	implementation("io.github.username:my-library:1.0.0")
}

마치면서

오늘은 직접 제작한 라이브러리를 maven central에 배포하는 과정을 알아보았습니다. 생각보다 할게 많고 복잡한 과정이지만, 이제 여러 사람에게 라이브러리를 배포하고 사용할 수 있게 되었습니다.

추가로 GitHub Actions를 통해 main 브랜치에 push하거나, GitHub에서 release를 할 때마다 라이브러리를 자동 배포할 수 있도록 할 수도 있으니 이런 방법을 찾아보시는 것도 추천드립니다.

profile
글 쓰는 개발자

1개의 댓글

comment-user-thumbnail
2024년 6월 13일

헉 저도 제가 만든 라이브러리 배포해보고싶네요!!! 다음에 따라해보겠습니다:)

답글 달기