Tout publier avec JReleaser
The quick and effortless way to release your project!
Java, Go, Node, Rust, Zig, Swift, Perl, Python, C/C++, C#, Elixir, Haskell, Ruby, Crystal, and more.
ie - Publier voter projet rapidement et sans effort.
JReleaser est un outil qui effectue les étapes les plus courantes liées à la publication de votre application.
Publier un projet ce n’est pas seulement pousser un paquet vers un dépôt centralisé. Cela peut aussi signifier signer et générer les artefacts, produire un SBOM, assembler et publier un changelog, annoncer la publication sur votre hub git favori, et même faire le dire sur Zulip, Bluesky et encore bien d’autres choses.
Dans cet article, nous nous concentrerons sur la publication d’une application Java.
Attendez, ce n’est pas juste Maven 🫘 !
Chaque gestionnaire de paquets, chaque dépôt d’artefacts a sa propre spécificité.
Comme Maven Central est le but ultime pour les développeurs Java, et comme c’est aussi l’un des dépôts les plus compliqués, c’est celui que nous examinerons dans cet article de blog. Mais bien sûr, une fois que vous aurez fait cela, tout le reste sera du gâteau 🧁 !
Pré-requis (outils ⚒️ et identifiants 🔐)
PGP
Générer votre paire de clés PGP
gpg --generate-key
Cela affichera l’invite suivante
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
gpg: /root/.gnupg/trustdb.gpg: trustdb created
gpg: directory '/root/.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/root/.gnupg/openpgp-revocs.d/4C2428BC373276273A30B9D4FA30C263300AD893.rev'
public and secret key created and signed.
pub ed25519 2025-11-18 [SC] [expires: 2028-11-17]
4C2428BC373276273A30B9D4FA30C263300AD893(1)
uid Guess who's back ? <back_again@shady.com>
sub cv25519 2025-11-18 [E] [expires: 2028-11-17]
| 1 | Ceci est votre identifiant de clé ; conservez-le quelque part. |
On vous demandera une phrase de passe pour protéger votre paire de clés. Choisissez judicieusement, et ne le dites à personne.
🤫chhhhhht!
❤️ Dave<3<3
Si vous oubliez de sauvegarder votre identifiant de clé, vous pouvez le retrouver en utilisant la
commande list-keys
# gpg --list-keys
/root/.gnupg/pubring.kbx
------------------------
pub ed25519 2025-11-18 [SC] [expires: 2028-11-17]
4C2428BC373276273A30B9D4FA30C263300AD893
uid [ultimate] Guess who's back ? <back_again@shady.com>
sub cv25519 2025-11-18 [E] [expires: 2028-11-17]
La distribuer
Il existe plusieurs serveurs de clés publics et parmi ceux-ci, les suivants sont supportés nativement: keyserver.ubuntu.com, keys.openpgp.org, pgp.mit.edu.
La commande suivante rendra votre clé publique disponible :
gpg --keyserver keyserver.ubuntu.com -send-key 4C2428BC373276273A30B9D4FA30C263300AD893(1)
| 1 | Remplacez par votre propre identifiant |
Obtenir vos identifiants Maven Central.
Connectez-vous à maven central, cliquez sur l’élément de menu en haut à droite "View User Tokens", et générez un nouveau jeton.
Vous pouvez spécifier son nom et sa date d’expiration. Personnellement, j’ai choisi de faire une folie pour celui-ci :
Installer JReleaser
Il existe de nombreuses façons d’installer JReleaser, mais mon choix pour mon environnement de dev est d’utiliser JBang :
// Télécharge, et installe localement
jbang app install jreleaser@jreleaser
// Exécuter en utilisant
jreleaser <command> [<args>]
Si vous préférez l’exécuter sans l’installer, vous pouvez aussi utiliser JBang :
// Télécharger, mettre en cache, et exécuter
jbang jreleaser@jreleaser <command> [<args>] (1)
| 1 | Si vous ne l’aviez pas compris, j’aime bien JBang |
Vérifier votre descripteur de projet
Même si JReleaser le fera pour vous, vous pouvez toujours vérifier indépendamment si votre descripteur de projet contient tous les champs obligatoires pour être publié en exécutant :
jbang pomchecker@kordamp check-maven-central
Corriger votre descripteur en conséquence et répéter l’opération jusqu’à ce que tout soit propre.
Configurer votre projet
C’est un processus en 2 étapes. Vous devez configurer JReleaser mais aussi votre processus de build pour générer tous les artefacts nécessaires à la publication (ici par exemple la javadoc DOIT être générée).
La configuration Maven
Ajoutez un profil release à votre pom.xml :
profil release
<profile>
<id>release</id>
<properties>
<altDeploymentRepository>
local::file:./target/staging-deploy (1)
</altDeploymentRepository>
</properties>
<build>
<defaultGoal>deploy</defaultGoal>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<attach>true</attach>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<attach>true</attach>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
La configuration Gradle
Si vous utilisez Gradle, je suis sûr que vous savez comment produire la configuration équivalente. Moi non.
La configuration JReleaser
Vous pouvez initialiser la configuration de votre projet avec la commande suivante :
jbang jreleaser@jreleaser init
//ou si vous l'avez installer localement
jreleaser init
Cela générera votre fichier de configuration de projet que vous devrez modifier selon vos besoins.
jreleaser.yaml
# Generated with JReleaser 1.21.0 at 2025-11-19T09:09:25.55515446Z
project:
name: app
version: 1.0.0-SNAPSHOT
description: Awesome App
longDescription: Awesome App
authors:
- Duke
license: Apache-2.0
links:
homepage: https://acme.com/app
languages:
java:
groupId: com.acme
version: 8
inceptionYear: 2025
release:
github:
owner: duke
distributions:
app:
artifacts:
- path: path/to/{{distributionName}}-{{projectVersion}}.zip
Les sections distributions et github peuvent être supprimées si vous voulez seulement un déploiement maven. Vous devrez par contre spécifier la configuration de déploiement maven en ajoutant ce qui suit à votre fichier de configuration :
signing: (1)
active: ALWAYS
armored: true
deploy: (2)
maven:
mavenCentral:
release-deploy:
active: RELEASE
url: https://central.sonatype.com/api/v1/publisher
stagingRepositories:
- target/staging-deploy (3)
nexus2:
snapshot-deploy:
active: SNAPSHOT
snapshotUrl: https://central.sonatype.com/repository/maven-snapshots/
applyMavenCentralRules: true
snapshotSupported: true
closeRepository: true
releaseRepository: true
stagingRepositories:
- target/staging-deploy (3)
| 1 | Laisse JReleaser faire la signature des artefacts pour vous |
| 2 | Quel dépôt maven utiliser pour les déploiements release et snapshot |
| 3 | Où trouver les artefacts localement. Doit correspondre à la valeur utilisée dans votre configuration de projet. |
Vous devrez spécifier quelques variables secrètes, mais pour des raisons de sécurité évidentes, PAS dans un fichier source versionné…
Spécifier les variables
La plupart des identifiants nécessaires à JReleaser seront communs à tous vos projets. Donc les définir globalement pour JReleaser est une bonne chose. Je les définis dans le dossier par défaut de JReleaser. Par défaut $HOME/.jreleaser/config.properties (les formats acceptés sont PROPERTIES, YAML, TOML et JSON)
J’ai choisi TOML et voici à quoi ressemble mon fichier :
JRELEASER_GPG_PUBLIC_KEY = """-----BEGIN PGP PUBLIC KEY BLOCK-----
<place_your_public_key_here>
-----END PGP PUBLIC KEY BLOCK-----""" (1)
JRELEASER_GPG_SECRET_KEY = """-----BEGIN PGP PRIVATE KEY BLOCK-----
<place_your_secret_key_here>
-----END PGP PRIVATE KEY BLOCK-----"""
JRELEASER_DRAFT = true (2)
JRELEASER_GPG_PASSPHRASE = "❤️ Dave<3<3"
JRELEASER_MAVENCENTRAL_RELEASE_DEPLOY_USERNAME = "redacted"
JRELEASER_MAVENCENTRAL_RELEASE_DEPLOY_TOKEN = "redacted"
JRELEASER_NEXUS2_SNAPSHOT_DEPLOY_USERNAME = "redacted"
JRELEASER_NEXUS2_SNAPSHOT_DEPLOY_TOKEN = "redacted" (3)
| 1 | TOML supporte les chaînes multilignes utilisant des triples quotes : """ |
| 2 | Je fais seulement des "draft release" depuis l’environnement de dev |
| 3 | Valeurs obtenues dans le chapitre Obtenir vos identifiants Maven Central.. Ce sont les mêmes pour maven central et nexus2_snapshot |
Une dernière chose, je préfère faire uniquement des dry run localement, mais cela ne peut pas être spécifié via un fichier pour le moment, donc j’exporte la valeur juste avant de lancer les commandes:
export JRELEASER_DRY_RUN=true && jreleaser full-release
Une fois que vous êtes satisfait, vous pouvez éventuellement désactiver la propriété dry run et relancer, mais je préfère faire la vraie publication depuis ma CI, qui est Github pour le moment.
Exécuter tout ça depuis Github 
Voici le workflow github minimal pour publier une application maven.
name: Release
on:
workflow_dispatch: (1)
inputs:
version: (2)
description: "Release version"
required: true
jobs:
build:
needs: [ precheck ]
name: 'Build artefacts'
runs-on: ubuntu-latest
steps:
- name: 'Check out repository'
uses: actions/checkout@v4
with:
ref: ${{ needs.precheck.outputs.HEAD }}
- name: 'Set up Java'
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 21
cache: 'maven'
- name: 'Build artefacts'
run: mvn -B -P release clean deploy
- name: Deploy to Central
uses: jreleaser/release-action@v2 (3)
with:
version: latest
arguments: 'full-release' (4)
env:
JRELEASER_GPG_PUBLIC_KEY: ${{ secrets.GPG_PUBLIC_KEY }}
JRELEASER_GPG_SECRET_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
JRELEASER_GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
JRELEASER_MAVENCENTRAL_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
JRELEASER_MAVENCENTRAL_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
JRELEASER_NEXUS2_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
JRELEASER_NEXUS2_TOKEN: ${{ secrets.SONATYPE_PASSWORD }} (5)
JRELEASER_PROJECT_VERSION: ${{ github.event.inputs.version }} (2)
#JRELEASER_DRAFT: true (6)
| 1 | Workflow déclenché manuellement |
| 2 | La version à publier. Elle pourrait aussi être récupérée depuis votre projet maven. |
| 3 | Utilise la github action JReleaser (Il existe aussi des intégrations avec Gitlab, Gitea et bien d’autres) |
| 4 | Exécute le workflow full-release |
| 5 | Toutes les valeurs à assigner dans les secrets de votre projet |
| 6 | Si vous voulez ou non faire des "draft releases". |
Conclusion
Nous n’avons fait qu’effleurer la surface de ce qui peut être fait avec JReleaser. Si vous voulez un exemple vraiment complet, voici comment JReleaser se publie lui-même, avec JReleaser bien sûr.
Mais au moins, vous savez comment publier vos artefacts sur Maven Central 🗻 \o/ . Ce soir ça va briller en société.
