본문 바로가기

SW 아키텍처 이야기

오픈소스 라이브러리 Maven Central Repository에 배포하기 (#3)

첫 글을 통해 Maven Repository와 Central Repository에 대해 간단히 알아봤다. 

2020/11/08 - [SW 아키텍처 이야기] - 오픈소스 라이브러리 Maven Central Repository에 배포하기 (#1)

두 번째 글에서는 OSSRH(Open Source SW Repository Hosting)을 통해 Maven Central Repository에 배포하기 위한 준비 과정을 살펴봤다.

2020/11/14 - [SW 아키텍처 이야기] - 오픈소스 라이브러리 Maven Central Repository에 배포하기 (#2)

이제 준비가 되었으니 본격적인 배포를 시작해 보자.

 

6. Distribution 설정

JIRA issue를 등록하고 사용하고자 하는 GroupId에 대하여 소유를 증명하면, 해당 issue에 다음과 같은 Sonatype 설정이 완료되었다는 안내 comment가 등록된다. 

Deploy를 위한 repository URL 정보들이 안내되어 있는데, 추후 설정에 필요한 정보다. 아울러, 첫 번째 릴리즈를 완료되면 해당 내용에 issue(ticket)에 남겨 달라는 안내도 있다. 실제로 나중에 "릴리즈"를 하더라도 Sonatype에서 별도의 설정을 추가해 줘야 OSSRH와 Maven Central Repository가 동기화되기 때문에 잊지 않도록 한다.

이제 pom.xml 상에 deploy 설정을 추가해야 하는데, 2가지 방법이 있다. 일반적으로 내부 Nexus 서버에 배포를 위해 많이 사용되는 Maven Deploy Plugin를 사용하는 방법과, Sonatype에서 제공하는 Nexus Staging Maven Plugin을 사용하는 방법이다. 

6.1 Maven Deploy Plugin 설정

pom.xml에 다음과 같은 <distributionManagement> 설정을 추가하고 계정 정보를 Maven의 settings.xml 상에 추가하면 된다.

<distributionManagement>
	<snapshotRepository>
		<id>ossrh</id>
		<url>https://oss.sonatype.org/content/repositories/snapshots</url>
	</snapshotRepository>
	<repository>
		<id>ossrh</id>
		<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
	</repository>
</distributionManagement>

 Snapshot Repository URL과 일반 Repository URL은 JIRA에 등록된 comment 정보의 URL들이다. 그리고 이를 접근하기 위한 Sonatype 계정 정보(JIRA 계정)는 pom.xml이 아닌 settings.xml에 다음과 같이 등록한다.

<servers>
    <server>
        <id>ossrh</id>
        <username>${env.MAVEN_REPO_USERNAME}</username>
        <password>${env.MAVEN_REPO_PASSWORD}</password>
    </server>
</servers>

여기서 server의 id는 <distirubtionManagement>에 등록된 repository의 id와 같아야 하며, username과 password는 직접 지정하는 것도 가능하지만 되도록 환경 변수를 통해 처리하는 것이 좋다.

참고로, 여기서는 별도 <plugin> 설정을 추가하지 않더라고 "deploy" 단계(phase)에서 처리된다.

6.2 Nexus Staging Maven Plugin 설정

다음으로 사용할 수 있는 plugin은 sonatype에서 제공하는 Nexus Staging Maven Plugin이다. Maven의 Deploy Plugin보다 이 Plugin 사용을 권장한다. 이유는 다음과 같다.

  • Maven Deploy Plugin은 artifact들이 push 될 때마다 분산 처리되는 일부 CI 환경에서 오류가 발생한다. (artifact jar, javadoc jar 등이 별도의 upload로 분리되면서 각 처리가 다른 IP로 처리되기 때문에 OSSRH가 모든 jar 파일이 등록되지 않았다고 판단함)
  • "First release" 수동 처리 이후 Nexus Plugin은 자동으로 릴리즈 처리를 지원한다.

따라서 OSSRH를 사용하기 위해서는 특별한 이유가 없다면 Nexus Plugin을 사용하면 된다. 설정은 다음과 같은 plugin 설정과 Maven Deploy Plugin과 마찬가지로 settings.xml에 계정 정보를 추가하면 된다.

<plugin>
	<groupId>org.sonatype.plugins</groupId>
	<artifactId>nexus-staging-maven-plugin</artifactId>
	<version>1.6.8</version>
	<extensions>true</extensions>
	<configuration>
		<serverId>ossrh</serverId>
		<nexusUrl>https://oss.sonatype.org/</nexusUrl>
		<autoReleaseAfterClose>true</autoReleaseAfterClose>
	</configuration>
</plugin>

 

<distributionManagement>에서 복잡하게 지정했던 URL들은 여기서는 간단하게 nexusUrl에 서버 주소만 등록하면 된다. 그리고 "deploy"가 아닌 "verify" 단계(phase)에 동작한다는 차이가 있다. 

autoReleaseAfterClose 설정을 추후 설명하겠지만, 자동으로 Release Repository로 옮기는 처리를 제공한다.

계정 정보는 settings.xml에 다음과 같이 Maven Deploy Plugin과 같이 지정한다.

<servers>
    <server>
        <id>ossrh</id>
        <username>${env.MAVEN_REPO_USERNAME}</username>
        <password>${env.MAVEN_REPO_PASSWORD}</password>
    </server>
</servers>

 

7. Staging Repository 배포

7.1 Deploy 처리

이제 실제로 maven deploy 명령을 통해 실제 OSSRH에 배포를 해보자. 특별한 문제가 없다면 다음과 같이 정상적으로 oss.sonatype.org에 배포되는 것을 확인할 수 있다.

혹, 오류가 발생한다면 다음과 같이 나타난다.

이 경우는 pom.xml에 프로젝트에 대한 URL 정보가 등록되지 않았다는 오류로 배포가 거절된 경우이다. 이런 경우 "mvn nexus-staging:drop" 명령을 통해 Staging Repository에서 삭제를 해주는 것이다.

[릴리즈 처리 과정]

릴리즈가 처리되는 과정을 좀 더 살펴보면 다음과 같다.

Staging Repository에 upload가 된 이후, 수동 또는 자동 설정(autoReleaseAfterClose 설정)에 의해 Central Repository 등록 가능한지 validation 단계를 거친다. (예를 들면 pom.xml에 최소한의 정보가 등록되었는지, javadoc / sources jar도 등록되는지 등)

7.2 Artifact 확인 (w/ autoReleaseAfterClose)

정상적으로 릴리즈까지 되었다면 https://oss.sonatype.org/에서 다음과 같이 검색을 통해 배포를 확인할 수 있다.

  

7.3 Artifact 확인 (w/o autoReleaseAfterClose)

autoReleaseAfterClose 설정이 되지 않은 경우라면 Staging Repository에만 배포가 되었기 때문에 Relase Repository에서는 조회가 되지 않는다. 이 경우 검색 화면 왼쪽 하단에 있는 "Staging Repsitories" 링크를 클릭하면 다음과 같이 Staging에 배포된 artifact를 확인할 수 있다.

최근 항목을 클릭하면 배포된 콘텐츠들을 확인할 수 있다.

그리고 아직 릴리즈 처리가 되지 않았기 때문에 "Close" 및 "Release" 처리를 수동으로 해야 한다.

 

8. "First" 릴리즈

정상적으로 릴리즈 처리가 되었다면, JIRA issue(ticket)에 다음과 같이 comment를 등록하면 된다. 그래야 Central Repository와의 동기화가 설정된다.

다만, 처음부터 autoRelaseAfterClose가 설정되었다면 별도 comment 등록 없이도 다음과 같은 안내 comment가 몇 분 후에 등록된다.

10분 안에 Central로 배포되고, 2시간 후에는 search.maven.org에서 반영된다는 내용이다.

그리고 2시간 후에 https://search.maven.org 검색 사이트를 통해 다음과 같이 확인을 할 수 있다.

    

9. CI 적용

이제 CI에 적용해 볼 차례다. 우선 CI 적용 시에 고려사항들을 먼저 생각해 보자.

추가된 plugin이 많아 실제 배포가 아닌 경우에는 대부분 불필요하게 되고, 이는 매 빌드마다 속도가 문제가 될 수 있다.

다음으로 문제는 GPG 보안 키(Secret Key) 대한 패스워드(passphrase) Sonatype 인증 정보가 CI 환경으로 배포되어야 한다는 것이다.

이에 대해서는 다음 글을 통해 더 알아보자.

Written with by Vincent Han