[Android] Maven Central에 라이브러리 배포하기

SangGun Park·2023년 10월 12일
0

Android

목록 보기
11/11
post-thumbnail

내가 보려고 쓰는..

1. Sonatype Jira 계정 생성 및 로그인

https://issues.sonatype.org/secure/Dashboard.jspa


위의 링크로 이동하여 회원가입을 진행합니다.

이메일, 이름, 유저 아이디, 패스워드를 모두 입력한다. 이 중 유저 아이디는 로그인시 쓰이는 아이디이니 꼭 기억해야 합니다.

2. 이슈 생성


로그인 후 상단탭의 만들기 버튼을 클릭하면 다음과 같은 화면이 나옵니다.


프로젝트와 이슈 유형은 위과 같이 설정하고


위와 같이 필수 값을 입력합니다.

Gitbub Repository를 퍼블리싱 한다고 하면
요약 : 프로젝트 이름
Group Id : io.github.(깃허브 유저 이름)
Project URL : Gitbub Repository 주소
SCM url : 깃허브에서 SSH 주소를 복사합니다.


모두 입력 후 생성하면 위과 같은 화면이 나오는데


댓글에 자신의 깃허브 주소를 검증하라는 댓글이 달립니다.


레포지토리 생성 후 인증해 줍니다. (이때 레포지토리는 반드시 Public으로 생성해야 합니다.)


잠시 기다리면 위와 같은 댓글이 달리는데 이러면 준비는 끝입니다.

3. Nexus 로그인

https://s01.oss.sonatype.org/#stagingRepositories

위 주소로 들어가면

위와 같은 화면이 나오는데 아까 Jira에서 가입한 유저 아이디로 로그인 해 줍니다.

왼쪽 메뉴 중 Staging Profiles를 클릭 후

자신의 프로필 주소를 클릭하면 주소창에 아래와 같이 생성이 되는데 https://s01.oss.sonatype.org/#stagingProfiles;
[Profile Id]
여기서 Profile Id만 복사해 둡니다.

4. GPG Key Pair 생성

커맨드 창을 열고 다음과 같이 진행합니다.

gpg key 설치

brew install gpg 

gpg key 생성

gpg --full-gen-key

1번 RSA and RSA 선택

Please select what kind of key you want:
   (1) RSA and RSA
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
   (9) ECC (sign and encrypt) *default*
  (10) ECC (sign only)
  (14) Existing key from card
Your selection? 1

키 길이는 4096 선택

RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (3072) 4096

키의 유효기간을 선택하는데 편의상 기간 제한이 없는 0번을 선택 했습니다.

Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 0

0번을 선택하면 확인 메세지가 나오는데 y 입력해 줍니다.

Is this correct? (y/N) y

마지막으로 다음의 정보를 입력합니다.

Real name: 이름
Email address: 이메일
Comment: 안써도 됩니다.

변경할 정보가 있으면 변경하고 없다면 O를 입력해서 넘어갑니다.

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O

이제 gpg key의 패스워드를 2번 반복해서 입력해 줍니다.
*(패스워드는 퍼블리싱시 꼭 필요하니 미리 저장)

키가 생성 되었으면 퍼블릭키의 마지막 8자리를 복사해 줍니다.

pub   rsa4096 2023-05-09 (SC)
      (퍼블릭키)
uid                      (이름) <(이메일)>
sub   rsa4096 2023-05-09 (E)

GPG Key를 export합니다.
이 명령어를 통해 나오는 문자열을 GPG Key로 저장해 줍니다.

gpg --export-secret-keys (퍼블릭키 마지막 8자리) | base64

4. Gradle 설정

gradle은 kotlin-dsl을 기준으로 작성되었습니다.

local.properties로 위와 같이 값을 저장 했습니다.

(root) build.gradle.kts

plugins {
    id("io.github.gradle-nexus.publish-plugin") version nexusPublishVersion
}

val properties = gradleLocalProperties(rootDir)

val userMap = mapOf(
    "ossrhUsername" to properties.getProperty("ossrhUsername"),
    "ossrhPassword" to properties.getProperty("ossrhPassword"),
    "sonatypeStagingProfileId" to properties.getProperty("sonatypeStagingProfileId"),
)

nexusPublishing {
    repositories {
        sonatype {
            stagingProfileId.set(userMap["sonatypeStagingProfileId"])
            username.set(userMap["ossrhUsername"])
            password.set(userMap["ossrhPassword"])
            nexusUrl.set(uri("https://s01.oss.sonatype.org/service/local/"))
            snapshotRepositoryUrl.set(uri("https://s01.oss.sonatype.org/content/repositories/snapshots/"))
        }
    }
}


buildSrc를 사용하여 위와 같이 publish-module-android.gradle.kts를 생성합니다. (groovy를 사용하거나 buildSrc를 사용하지 않는다면 따로 scripts 폴더를 생성하여 퍼블리싱용 gradle 파일을 생성해도 무관합니다.

buildSrc/build.gradle.kts

plugins {
    `kotlin-dsl`
    `kotlin-dsl-precompiled-script-plugins`
}

repositories {
    google()
    mavenCentral()
    gradlePluginPortal()
    mavenLocal()
}

dependencies {
    implementation("com.android.tools.build:gradle:8.1.1")
    implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.21")
}

buildSrc/publish-module-android.gradle.kts

import com.android.build.gradle.BaseExtension
import com.android.build.gradle.LibraryExtension
import com.android.build.gradle.internal.cxx.configure.gradleLocalProperties

plugins {
    `maven-publish`
    signing
}

group = "io.github.plz-no-anr" (퍼블리싱 그룹Id) 
version = "1.0.2" (퍼블리싱 버전) 

val androidSourceJar by tasks.registering(Jar::class) {
        archiveClassifier.set("sources")
        from(project.extensions.getByType<BaseExtension>().sourceSets.getByName("main").java.srcDirs)
    }

(project as ExtensionAware).extensions.configure<LibraryExtension>("android") {
    publishing.singleVariant("release")
}

afterEvaluate {
    publishing {
        publications {
            create<MavenPublication>("release") {
                if (project.plugins.hasPlugin("com.android.library")) {
                    from(components["release"])
                } else {
                    from(components["java"])
                }
                artifact(androidSourceJar.get())
                groupId = "io.github.plz-no-anr" (퍼블리싱 그룹Id) 
                artifactId = "coma" (퍼블리싱할 라이브러리 이름)
                version = "1.0.2" (퍼블리싱 버전) 
                
                // Mostly self-explanatory metadata
                pom {
                    name.set("coma")
                    description.set("Compose MVI Android")
                    url.set("https://github.com/plz-no-anr/coma")
                    licenses { // 라이센스가 있다면 추가
                        license {
                            name.set("MIT license")
                            url.set("https://opensource.org/license/mit")
                        }
                    }
                    developers { 개발자 정보
                        developer {
                            id.set("plz-no-anr")
                            name.set("SanggunPark")
                            email.set("psgxxx@naver.com")
                        }
                    }
                    // Version control info
                    scm { // 깃허브 정보 (나중에 라이브러리 검색시 이동할 링크입니다.)
                        connection.set("scm:git:github.com/plz-no-anr/coma.git")
                        developerConnection.set("scm:git:ssh://github.com/plz-no-anr/coma.git")
                        url.set("https://github.com/plz-no-anr/coma/tree/main")
                    }
                }

            }

        }
    }
}

// local.properties 불러오기
val properties = gradleLocalProperties(rootDir)
val signingMap = mapOf(
    "signing.keyId" to properties.getProperty("signing.keyId"),
    "signing.password" to properties.getProperty("signing.password"),
    "signing.key" to properties.getProperty("signing.key")
)

signing {
    useInMemoryPgpKeys(
        signingMap["signing.keyId"],
        signingMap["signing.key"],
        signingMap["signing.password"]
    )
    sign(publishing.publications)
}

위와 같이 퍼블리싱할 gradle 정보 셋팅 후 module단의 gradle에 plugin을 추가해 줍니다.

plugins {
    androidLibrary
    kotlinAndroid
    id("publish-module-android")  // 위에서 만든 퍼블리싱 gradle
}

android {
    namespace = "plznoanr.coma"
    compileSdk = Config.compileSdkVersion

    defaultConfig {
        minSdk = Config.minSdkVersion

        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
        consumerProguardFiles("consumer-rules.pro")
    }

    buildTypes {
        release {
            isMinifyEnabled = false
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_11
        targetCompatibility = JavaVersion.VERSION_11
    }
    kotlinOptions {
        jvmTarget = JavaVersion.VERSION_11.toString()
    }
}

이때 간혹 릴리즈 옵션에 isMinifyEnabled = true를 사용하여 난독화 시 에러가 발생하는 경우가 있기 때문에 이 옵션은 false로 설정해 주거나 proguard를 통해 에러가 나는 부분을 예외 처리해 줍니다.

이제 준비는 끝났고 Task를 이용해 라이브러리를 올려줍니다.


위와 같이 publishReleasePublicationToSonatypeRepository를 클릭해 올리거나 Terminal에서 다음과 같이 커맨드를 입력해 올려줍니다.

./gradlew (모듈명):publishReleasePublicationToSonatypeRepository

빌드가 성공하면 배포 준비는 끝입니다.

5. 배포


https://s01.oss.sonatype.org/#stagingRepositories 에서 위와 같이 라이브러리가 올라간 것을 확인할 수 있는데 배포할 라이브러리 선택 후 Close - Confirm 을 클릭합니다.

잠시후 Refresh 버튼을 누르면 Release 버튼이 활성화 되는데 누르면 배포가 완료됩니다.

배포가 완료된 라이브러리는 여기서 확인이 가능합니다.

번외

Github ReadMe에 배포한 라이브러리 뱃지 추가하는 법

[![Maven Central](https://img.shields.io/maven-central/v/그룹아이디.유저아이디/아티팩트-이름.svg)](https://central.sonatype.com/artifact/그룹아이디.유저아이디/아티팩트-이름)

Ex

[![Maven Central](https://img.shields.io/maven-central/v/io.github.plz-no-anr/coma.svg)](https://central.sonatype.com/artifact/io.github.plz-no-anr/coma)


Reference

profile
배우고 제때 익히니 즐겁지 아니한가

0개의 댓글