Publicar um artefato Java no Maven Central utilizando o maven local
Published: 2021-12-26 16:49:51

Um tempo atrás precisei publicar a nova versão de uma biblioteca open source no Maven Central e o processo não foi tão trivial quanto eu esperava. Pela descentralização do processo, a documentação é distribuída. Assim, resolvi escrever os passos da jornada que, à época, considerei ser o menor caminho. Por questões corporativas eu não era administrador do repositório git, e não poderia considerar fazer isso por CI/CD. Se você está já está certo do que quer fazer, no ponto de publicar e não precisa de contextualização, pode pular os dois próximos parágrafos.

Para a maior parte das pessoas que trabalha no mercado corporativo tradicional essa é uma necessidade que nunca irá surgir. Empresas geralmente possuem seu próprio repositório de artefatos em instâncias do [JFrog Artifactory](https://jfrog.com/artifactory/) ou [Nexus](https://www.sonatype.com/products/repository-pro) em sua Intranet. De fato, não interessa que suas regras de negócio estejam acessíveis para qualquer pessoa do mundo. 

A coisa muda quando se trabalha em uma empresa em que TI é atividade fim, ou mesmo quando corporações tradicionais resolvem investir tempo em _open source_. Então, para que qualquer pessoa possa utilizar sua biblioteca ou _framework_, é necessário que ela esteja em algum repositório Maven público. E para que as pessoas consigam encontrá-lo sem precisar adicionar um novo repositório em seus arquivos settings.xml, o melhor caminho é torná-lo visível no [Maven Central](https://search.maven.org/).

O Maven Central faz espelhamento de um conjunto de repositórios. Utilizaremos o [Sonatype Central](https://central.sonatype.org/). 

## Cadastrando o artefato 
Os primeiros passos são manuais e revisados por humanos, apenas para a primeira implantação. Crie uma conta no [JIRA](https://issues.sonatype.org/) da organização e, depois de logado, abra um ticket de criação de projeto. [Este link](https://issues.sonatype.org/secure/CreateIssue.jspa?issuetype=21&pid=10134) leva ao formulário com o template já escolhido. Nesse momento você vai inserir as informações do seu projeto, das quais as mais importantes são o groupId e o artifactId, que obviamente não podem ter sido previamente utilizados no Maven Central. A documentação oficial desses passos está [aqui](https://central.sonatype.org/publish/publish-guide/).

## E se o projeto já tiver versões publicadas?
O ticket de criação do projeto não se aplica. Abra um ticket no JIRA solicitando permissão no projeto que deseja publicar e peça para que um usuário que já tem permissão comente na issue autorizando seu acesso. Em situações comuns, isso é suficiente.

De uma forma ou de outra, em até dois dias(mas normalmente horas) o processo estará revisado e você será um publicador reconhecido daquele pacote.

## Chave GPG
Para fazer o deploy a partir do seu Maven local, você precisa de um [GPG](https://www.gnupg.org/) _client_ funcionando via linha de comando e de uma chave. Isso é pré-requisito de funcionamento do [Maven GPG Plugin](https://maven.apache.org/plugins/maven-gpg-plugin/). Na [página de downloads](https://gnupg.org/download/) do projeto você encontra o adequado para o seu SO na seção "GnuPG binary releases". Depois de baixar, verifique o funcionamento digitando em seu terminal:

```
gpg -h
```

Crie sua chave com:
```
gpg --gen-key
```
As opções _default_ são adequadas. Mais detalhes em https://help.ubuntu.com/community/GnuPrivacyGuardHowto

Configurado o GPG, é hora de configurar o Maven.

No pom.xml do seu projeto, inclua a seção `distributionManagement`, como a seguir:
```
<distributionManagement>
  <snapshotRepository>
    <id>ossrh</id>
    <url>https://s01.oss.sonatype.org/content/repositories/snapshots</url>
  </snapshotRepository>
  <repository>
    <id>ossrh</id>
    <url>https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/</url>
  </repository>
</distributionManagement>
```
Note que o endereço do Nexus mudou em março de 2021. Assim, projetos criados antes devem ser apontados para https://oss.sonatype.org/.
Adicionalmente, na seção de `build`, inclua o plugin `nexus-staging-maven-plugin`:
```
<build>
  <plugins>
    <plugin>
      <groupId>org.sonatype.plugins</groupId>
      <artifactId>nexus-staging-maven-plugin</artifactId>
      <version>1.6.7</version>
      <extensions>true</extensions>
      <configuration>
        <serverId>ossrh</serverId>
        <nexusUrl>https://s01.oss.sonatype.org/</nexusUrl>
        <autoReleaseAfterClose>true</autoReleaseAfterClose>
      </configuration>
    </plugin>
    ...
  </plugins>
</build>
```

A parte `<serverId>ossrh</serverId>` vai procurar um repositório com esse id cadastrado no seu arquivo de settings. Normalmente esse arquivo fica dentro da pasta .m2 com o nome de settings.xml. Nele, inclua as informações do servidor(observe o texto a substituir entre parênteses):
```
<servers>
    <server>
      <id>ossrh</id>
      <username>(Seu usuário do JIRA)</username>
      <password>(Sua senha)</password>
    </server>
  </servers>
```
Essa é a configuração mínima. Na publicação de um projeto open source também é importante observar outras seções do pom.xml para controlar a publicação de licença, código fonte e javadoc junto com o binário. Seguimos com a publicação.

O `nexus-staging-maven-plugin` utiliza o `maven-gpg-plugin`, que por sua vez utiliza a linha de comando gpg que você instalou. Dependendo do sistema operacional e da quantidade de chaves GPG que você possui, pode ser preciso personalizar alguns parâmetros da execução do plugin. Esses detalhes podem ser vistos [aqui](https://central.sonatype.org/publish/publish-maven/#gpg-signed-components).

Para manter consistência das versões no seu deploy, recomendo utilizar o plugin [maven-release](https://maven.apache.org/maven-release/maven-release-plugin/examples/prepare-release.html). Eu utilizo da seguinte forma(supondo que seus pom.xml estejam com uma versão SNAPSHOT. Observe o texto a substituir entre parênteses):
```
mvn clean release:prepare -Dresume=false -DautoVersionSubmodules=true
git checkout tags/(tag que foi criada)
mvn deploy
```
O Maven Release Plugin fará algumas perguntas a respeito da versão fechada e da nova versão _snapshot_ que será iniciada. Assim automatizamos a gestão das versões e garantimos que o artefato fechado reflete a tag criada no repositório.
O Maven Deploy plugin pedirá a senha da sua chave GPG.

Se o processo ocorrer sem erros, seu artefato terá o upload concluído, restando a sua liberação para que de fato se torne público.
Acesse https://oss.sonatype.org/#stagingRepositories e encontre o repositório que acabou de criar com seu upload. Caso as informações estejam corretas, selecione-o, feche-o("Close") e quando for concluído o fechamento, escolha "Release".
Seu artefato imediatamente estará disponível no Sonatype Central e levará entre algumas horas e um dia para estar disponível no Maven Central.

E aí, deu certo? Precisou fazer algo diferente? Seu feedback será ótimo para melhorarmos esse guia.

Até a próxima!