JReleaser’s Release

It should be no surprise that JReleaser relies on itself to create its releases.

The following configuration file is used to create both release and snapshot releases:

jreleaser.yml
# Define properties we'll use later in this file
environment:
  properties:
    jdkPathPrefix: 'apps/jreleaser/build/jdks'
    jdkFilePrefix: 'zulu17.50.19-ca-jdk17.0.11'
    graalFilePrefix: 'graalvm-community-openjdk-22.0.1+8.1'
    nativeImageDir: out/jreleaser/assemble/jreleaser-native/native-image
    jpackageDir: out/jreleaser/assemble/jreleaser-installer/jpackage
    javaArchiveDir: out/jreleaser/assemble/jreleaser/java-archive

# General information about this project
project:
  name: jreleaser
  description: Release projects quickly and easily with JReleaser
  longDescription: |
    JReleaser is a release automation tool. Its goal is to simplify creating releases and
    publishing artifacts to multiple package managers while providing customizable options.

    JReleaser takes inputs from popular builds tools (Ant, Maven, Gradle) such as JAR files,
    binary distributions (.zip, .tar), jlink images, or any other file that you’d like to
    publish as a Git release on popular Git services such as GitHub, GitLab, or Gitea.
    Distribution files may additionally be published to be consumed by popular package managers
    such as Homebrew, Chocolatey, Snapcraft, or get ready to be launched via JBang. Releases
    may be announced in a variety of channels such as Twitter, Zulip, SDKMAN!, and more.
  links:
    homepage: https://jreleaser.org
    faq: https://{{repoHost}}/{{repoOwner}}/{{repoName}}/discussions
    donation: https://opencollective.com/jreleaser
    documentation: https://jreleaser.org/guide/latest
  authors:
    - Andres Almiray
  license: Apache-2.0
  inceptionYear: 2020
  stereotype: CLI
  screenshots:
    - url: https://jreleaser.org/images/app-full-release-command.png
      caption: JReleaser in action
  icons:
    - url: https://raw.githubusercontent.com/jreleaser/jreleaser/main/src/media/icon_256x256.png
      width: 256
      height: 256
  java:
    groupId: org.jreleaser
    version: 8
    multiProject: true
    mainClass: org.jreleaser.cli.Main
  tags:
    - 'jreleaser'
    - 'release'
    - 'tool'
    - 'java'
    - 'git'

platform:
  replacements:
    # Replace matching platforms in filenames of assembled artifacts
    aarch_64: aarch64

release:
  github:
    overwrite: true
    sign: true
    discussionCategoryName: Announcements
    issues:
      enabled: true
    changelog:
      formatted: ALWAYS
      preset: conventional-commits
      contributors:
        format: '- {{contributorName}}{{#contributorUsernameAsLink}} ({{.}}){{/contributorUsernameAsLink}}'
      contentTemplate: 'src/jreleaser/changelog.tpl'
      extraProperties:
        categorizeScopes: true
      labelers:
        - label: 'i18n'
          title: 'regex:^(?:i18n(?:\(.*\))?!?):\s.*'
          order: 120
        - label: 'dependencies'
          title: 'regex:^(?:deps(?:\(.*\))?!?):\s.*'
          order: 130
        - label: 'allcontributors1'
          title: 'regex:^docs: update .all-contributorsrc.*'
          order: -1
        - label: 'allcontributors2'
          title: 'regex:^docs: update CONTRIBUTORS.md.*'
          order: -2
      categories:
        - title: '🌐 Translation'
          key: 'i18n'
          order: 70
          labels:
            - 'i18n'
        - title: '⚙️  Dependencies'
          key: 'dependencies'
          order: 80
          labels:
            - 'dependencies'
        - title: 'allcontributors'
          order: 59
          labels:
            - 'allcontributors1'
            - 'allcontributors2'
      hide:
        categories:
          - 'merge'
          - 'allcontributors'
        contributors:
          - 'GitHub'
          - 'allcontributors'
          - 'dependabot'
      replacers:
        - search: 'i18n: '
        - search: 'deps: '

# File signing is always active
signing:
  active: ALWAYS
  armored: true

catalog:
  # Generate SBOMs for all distributions and files
  sbom:
    syft:
      active: ALWAYS
      pack:
        enabled: true
  # Configure SWID tag with defaults
  swid:
    swid-tag:
      active: ALWAYS

# Deploy JARs and POMs to Maven Central
deploy:
  maven:
    nexus2:
      maven-central:
        active: RELEASE
        url: https://s01.oss.sonatype.org/service/local
        closeRepository: true
        releaseRepository: true
        stagingRepositories:
          - build/repos/local/release

# Announcing a release only occurs when it's not snapshot
announce:
  bluesky:
    active: RELEASE
    statusTemplate: src/jreleaser/bluesky.tpl
  twitter:
    active: RELEASE
    statusTemplate: src/jreleaser/twitter.tpl
  mastodon:
    active: RELEASE
    host: https://fosstodon.org
    statusTemplate: src/jreleaser/mastodon.tpl
  openCollective:
    active: RELEASE
    message: '{{#f_md2html}}🚀 JReleaser {{projectVersion}} has been released! [{{releaseNotesUrl}}]({{releaseNotesUrl}}){{/f_md2html}}'
  http:
    noticeable:
      active: RELEASE
      url: https://api.noticeable.io/graphql
      authorization: BEARER
      bearerKeyword: Apikey
      method: POST
      headers:
        Accept: application/json
        Content-Type: application/json

assemble:
  # Configure the universal Java binary distribution
  javaArchive:
    jreleaser:
      active: ALWAYS
      formats:
        - ZIP
        - TAR
      fileSets:
        - input: '.'
          includes:
            - NOTICE
            - LICENSE
        - input: licenses
          output: licenses
      mainJar:
        path: 'plugins/jreleaser/build/libs/jreleaser-{{projectVersion}}.jar'
      jars:
        - pattern: 'plugins/jreleaser/build/dependencies/flat/*.jar'
      swid:
        tagRef: swid-tag

  # Configure a cross-platform Jlink assembly
  jlink:
    jreleaser-standalone:
      active: ALWAYS
      java:
        version: 17
      imageName: '{{distributionName}}-{{projectEffectiveVersion}}'
      executable: jreleaser
      fileSets:
        - input: '.'
          includes:
            - NOTICE
            - LICENSE
        - input: licenses
          output: licenses
      jdeps:
        multiRelease: base
        ignoreMissingDeps: true
      additionalModuleNames:
        - 'java.security.sasl'
        - 'java.security.jgss'
        - 'jdk.crypto.cryptoki'
        - 'jdk.crypto.ec'
        - 'jdk.localedata'
        - 'jdk.net'
        - 'jdk.security.auth'
        - 'jdk.security.jgss'
      targetJdks:
        - path: '{{jdkPathPrefix}}/zulu17Osx/{{jdkFilePrefix}}-macosx_x64/zulu-17.jdk/Contents/Home'
          platform: 'osx-x86_64'
        - path: '{{jdkPathPrefix}}/zulu17OsxArm/{{jdkFilePrefix}}-macosx_aarch64/zulu-17.jdk/Contents/Home'
          platform: 'osx-aarch_64'
        - path: '{{jdkPathPrefix}}/zulu17Linux/{{jdkFilePrefix}}-linux_x64'
          platform: 'linux-x86_64'
        - path: '{{jdkPathPrefix}}/zulu17LinuxArm/{{jdkFilePrefix}}-linux_aarch64'
          platform: 'linux-aarch_64'
        - path: '{{jdkPathPrefix}}/zulu17LinuxMusl/{{jdkFilePrefix}}-linux_musl_x64'
          platform: 'linux_musl-x86_64'
        - path: '{{jdkPathPrefix}}/zulu17LinuxMuslArm/{{jdkFilePrefix}}-linux_musl_aarch64'
          platform: 'linux_musl-aarch_64'
        - path: '{{jdkPathPrefix}}/zulu17Windows/{{jdkFilePrefix}}-win_x64'
          platform: 'windows-x86_64'
        - path: '{{jdkPathPrefix}}/zulu17WindowsArm/{{jdkFilePrefix}}-win_aarch64'
          platform: 'windows-aarch_64'
      mainJar:
        path: 'plugins/jreleaser/build/libs/jreleaser-{{projectVersion}}.jar'
      jars:
        - pattern: 'plugins/jreleaser/build/dependencies/flat/*.jar'
      swid:
        tagRef: swid-tag

  # Configure platform specific installers
  jpackage:
    jreleaser-installer:
      active: ALWAYS
      jlink: jreleaser-standalone
      attachPlatform: true
      applicationPackage:
        appName: jreleaser
        appVersion: '{{projectVersionNumber}}'
        vendor: JReleaser
      osx:
        types: [pkg]
        appName: JReleaser
        packageName: JReleaser
        packageIdentifier: org.jreleaser.cli
        icon: 'src/media/jreleaser.icns'
        resourceDir: 'src/jpackage/osx'
      linux:
        types: [deb,rpm]
        maintainer: jreleaser@kordamp.org
        icon: 'src/media/icon_256x256.png'
      windows:
        types: [msi]
        console: true
        dirChooser: true
        icon: 'src/media/jreleaser.ico'
        resourceDir: 'src/jpackage/windows'

  # Configure native executables
  nativeImage:
    jreleaser-native:
      active: ALWAYS
      java:
        version: 17
      imageName: '{{distributionName}}-{{projectEffectiveVersion}}'
      executable: jreleaser
      fileSets:
        - input: '.'
          includes:
            - NOTICE
            - LICENSE
        - input: licenses
          output: licenses
      mainJar:
        path: 'apps/jreleaser/build/libs/jreleaser-{{projectVersion}}.jar'
      jars:
        - pattern: 'apps/jreleaser/build/dependencies/flat/*.jar'
        - pattern: 'plugins/jreleaser/build/dependencies/graalvm/*.jar'
      graalJdks:
        - path: '{{jdkPathPrefix}}/graal22Osx/{{graalFilePrefix}}/Contents/Home'
          platform: 'osx-x86_64'
        - path: '{{jdkPathPrefix}}/graal22OsxArm/{{graalFilePrefix}}/Contents/Home'
          platform: 'osx-aarch_64'
        - path: '{{jdkPathPrefix}}/graal22Linux/{{graalFilePrefix}}'
          platform: 'linux-x86_64'
        - path: '{{jdkPathPrefix}}/graal22Windows/{{graalFilePrefix}}'
          platform: 'windows-x86_64'
      upx:
        active: ALWAYS
        version: '3.96'
      args:
        - '-Duser.language=en'
        - '-H:IncludeLocales=en,ca,de,es,fr,hi,it,ja,nl,pt_BR,zh_TW,ru'
        - '-H:Optimize=2'
        - '-H:+RemoveUnusedSymbols'
      swid:
        tagRef: swid-tag

# Configure 5 distributions
distributions:
  # Distribution 1 is of type JAVA_BINARY
  jreleaser:
    flatpak:
      active: ALWAYS
      componentId: org.jreleaser.cli
      developerName: JReleaser
      runtime: FREEDESKTOP
      runtimeVersion: 21.08
      finishArgs:
        - --share=network
        - --filesystem=host
      categories:
        - Developer Tools
      skipReleases:
        - '.*-RC.*'
        - '.*-M.*'
      repository:
        active: RELEASE
        owner: flathub
        name: org.jreleaser.cli
        branch: master
        branchPush: '{{projectName}}-{{tagName}}'
    chocolatey:
      active: ALWAYS
      remoteBuild: true
      title: JReleaser
      iconUrl: 'https://rawcdn.githack.com/jreleaser/jreleaser/0934fa1fa3f0bd09c0c8c39fbdeb5df2ce507457/src/media/icon_128x128.png'
      bucket:
        active: RELEASE
    jbang:
      active: ALWAYS
    macports:
      active: ALWAYS
      categories:
        - devel
        - java
      maintainers:
        - '@aalmiray'
      repository:
        active: RELEASE
        name: jreleaser-macports
    scoop:
      active: ALWAYS
      bucket:
        active: RELEASE
    sdkman:
      active: RELEASE
      continueOnError: true
    snap:
      active: ALWAYS
      remoteBuild: true
      base: core18
      architectures:
        - buildOn: [ amd64, arm64 ]
      plugs:
        - name: dot-config-files
          attributes:
            interface: personal-files
          writes:
            - $HOME/.jreleaser
          reads:
            - $HOME/.gnupg
            - $HOME/.gitconfig
            - $HOME/.config/jgit
      localPlugs:
        - network
        - home
        - dot-config-files
    spec:
      active: ALWAYS
      repository:
        active: RELEASE
        name: jreleaser-copr
    artifacts:
      # Transform the artifact name
      - path: '{{javaArchiveDir}}/{{distributionName}}-{{projectVersion}}.zip'
        transform: '{{distributionName}}/{{distributionName}}-{{projectEffectiveVersion}}.zip'
        extraProperties:
          skipSpec: true
      - path: '{{javaArchiveDir}}/{{distributionName}}-{{projectVersion}}.tar'
        transform: '{{distributionName}}/{{distributionName}}-{{projectEffectiveVersion}}.tar'
        extraProperties:
          skipFlatpak: true

  # Distribution 2 is of type SINGLE_JAR
  jreleaser-tool-provider:
    type: SINGLE_JAR
    artifacts:
      # Transform the artifact name
      - path: apps/{{distributionName}}/build/libs/{{distributionName}}-{{projectVersion}}.jar
        transform: '{{distributionName}}/{{distributionName}}-{{projectEffectiveVersion}}.jar'

  # Distribution 3 is of type JLINK
  # Name matches the assembled jlink distribution
  jreleaser-standalone:
    appImage:
      active: ALWAYS
      componentId: org.jreleaser.cli
      developerName: JReleaser
      categories:
        - Development
      repository:
        active: RELEASE
        name: jreleaser-appimage
        commitMessage: 'jreleaser {{tagName}}'
    brew:
      active: ALWAYS
      formulaName: jreleaser
      multiPlatform: true
      tap:
        active: RELEASE
        commitMessage: 'jreleaser {{tagName}}'
    docker:
      # inherited by specs
      active: ALWAYS
      repository:
        active: RELEASE
        commitMessage: 'jreleaser {{tagName}}'
      # inherited by specs
      registries:
        - serverName: DEFAULT
          username: jreleaser
      # inherited by specs
      labels:
        'org.opencontainers.image.title': 'jreleaser'
      # inherited by specs
      postCommands:
        - 'VOLUME /workspace'
      # configure 2 specs
      specs:
        slim:
          imageNames:
            - 'jreleaser/jreleaser-{{dockerSpecName}}:{{tagName}}'
            - 'jreleaser/jreleaser-{{dockerSpecName}}:latest'
          # match by platform
          matchers:
            platform: 'linux-x86_64'
          preCommands:
            - 'ARG DEBIAN_FRONTEND=noninteractive'
            - 'ENV TZ=Europe/Zurich'
            - 'RUN apt-get update && apt-get install -y unzip binutils fakeroot rpm'
        alpine:
          imageNames:
            - 'jreleaser/jreleaser-{{dockerSpecName}}:{{tagName}}'
            - 'jreleaser/jreleaser-{{dockerSpecName}}:latest'
          # match by platform
          matchers:
            platform: 'linux_musl-x86_64'
          preCommands:
            - 'RUN apk add unzip binutils fakeroot rpm'

  # Distribution 4 is of type NATIVE_PACKAGE
  # Name matches the assembled jpackage distribution
  jreleaser-installer:
    type: NATIVE_PACKAGE
    winget:
      active: RELEASE
      package:
        name: jreleaser
      repository:
        active: ALWAYS
        name: jreleaser-winget
        commitMessage: 'jreleaser {{tagName}}'
    executable:
      name: jreleaser
      windowsExtension: exe
    artifacts:
      # Transform the artifact name
      - path: '{{jpackageDir}}/JReleaser-{{projectVersionNumber}}-osx-x86_64.pkg'
        transform: '{{distributionName}}/{{distributionName}}-{{projectEffectiveVersion}}-osx-x86_64.pkg'
        platform: 'osx-x86_64'
      - path: '{{jpackageDir}}/JReleaser-{{projectVersionNumber}}-osx-aarch64.pkg'
        transform: '{{distributionName}}/{{distributionName}}-{{projectEffectiveVersion}}-osx-aarch64.pkg'
        platform: 'osx-aarch_64'
      - path: '{{jpackageDir}}/jreleaser_{{projectVersionNumber}}-1_amd64.deb'
        transform: '{{distributionName}}/{{distributionName}}_{{projectEffectiveVersion}}-1_amd64.deb'
        platform: 'linux-x86_64'
      - path: '{{jpackageDir}}/jreleaser-{{projectVersionNumber}}-1.x86_64.rpm'
        transform: '{{distributionName}}/{{distributionName}}-{{projectEffectiveVersion}}-1.x86_64.rpm'
        platform: 'linux-x86_64'
      - path: '{{jpackageDir}}/jreleaser-{{projectVersionNumber}}-windows-x86_64.msi'
        transform: '{{distributionName}}/{{distributionName}}-{{projectEffectiveVersion}}-windows-x86_64.msi'
        platform: 'windows-x86_64'

  # Distribution 5 is of type BINARY
  # Name matches the assembled nativeImage distribution
  jreleaser-native:
    artifacts:
      - path: '{{nativeImageDir}}/{{distributionName}}-{{projectEffectiveVersion}}-osx-aarch64.zip'
        platform: 'osx-aarch_64'
      - path: '{{nativeImageDir}}/{{distributionName}}-{{projectEffectiveVersion}}-osx-x86_64.zip'
        platform: 'osx-x86_64'
      - path: '{{nativeImageDir}}/{{distributionName}}-{{projectEffectiveVersion}}-linux-x86_64.zip'
        platform: 'linux-x86_64'
      - path: '{{nativeImageDir}}/{{distributionName}}-{{projectEffectiveVersion}}-windows-x86_64.zip'
        platform: 'windows-x86_64'

files:
  artifacts:
    - path: VERSION
      extraProperties:
        skipChecksum: true
        skipSigning: true
        skipSbom: true
    - path: plugins/jreleaser-ant-tasks/build/distributions/jreleaser-ant-tasks-{{projectVersion}}.zip
      transform: 'jreleaser-ant-tasks/jreleaser-ant-tasks-{{projectEffectiveVersion}}.zip'

Which will create and tag a prerelease on GitHub when the project is snapshot, and a regular release when the project is not snapshot.

The release will have the following assets:

# binaries created by the Gradle build
jreleaser-ant-tasks-1.15.0.zip
jreleaser-tool-provider-1.15.0.jar

# binaries created by the Java-archive assembler
jreleaser-1.15.0.tar
jreleaser-1.15.0.zip

# binaries created by the Jlink assembler
jreleaser-standalone-1.15.0-linux-aarch64.zip
jreleaser-standalone-1.15.0-linux-x86_64.zip
jreleaser-standalone-1.15.0-linux_musl-aarch64.zip
jreleaser-standalone-1.15.0-linux_musl-x86_64.zip
jreleaser-standalone-1.15.0-osx-aarch64.zip
jreleaser-standalone-1.15.0-osx-x86_64.zip
jreleaser-standalone-1.15.0-windows-aarch64.zip
jreleaser-standalone-1.15.0-windows-x86_64.zip

# binaries created by the Jpackage assembler
jreleaser-installer-1.15.0-osx-aarch64.pkg
jreleaser-installer-1.15.0-osx-x86_64.pkg
jreleaser-installer-1.15.0-1_amd64.deb
jreleaser-installer-1.15.0-1.x86_64.rpm
jreleaser-installer-1.15.0-windows-x86_64.msi

# binaries created by the NativeImage assembler
jreleaser-native-1.15.0-osx-aarch64.zip
jreleaser-native-1.15.0-osx-x86_64.zip
jreleaser-native-1.15.0-linux-x86_64.zip
jreleaser-native-1.15.0-windows-x86_64.zip

# sbom archive
jreleaser-1.15.0-sboms.zip

# checksums
checksums_rmd160.txt
checksums_sha256.txt
jreleaser-1.15.0.zip.rmd160
jreleaser-1.15.0.zip.sha256

# signatures
checksums_rmd160.txt.asc
checksums_sha256.txt.asc
jreleaser-1.15.0-sboms.zip.asc
jreleaser-1.15.0.tar.asc
jreleaser-1.15.0.zip.asc
jreleaser-ant-tasks-1.15.0.zip.asc
jreleaser-tool-provider-1.15.0.jar.asc
jreleaser-standalone-1.15.0-linux-aarch64.zip.asc
jreleaser-standalone-1.15.0-linux-x86_64.zip.asc
jreleaser-standalone-1.15.0-linux_musl-aarch64.zip.asc
jreleaser-standalone-1.15.0-linux_musl-x86_64.zip.asc
jreleaser-standalone-1.15.0-osx-aarch64.zip.asc
jreleaser-standalone-1.15.0-osx-x86_64.zip.asc
jreleaser-standalone-1.15.0-windows-aarch64.zip.asc
jreleaser-standalone-1.15.0-windows-x86_64.zip.asc
jreleaser-installer-1.15.0-osx-aarch64.pkg.asc
jreleaser-installer-1.15.0-osx-x86_64.pkg.asc
jreleaser-installer-1.15.0-1_amd64.deb.asc
jreleaser-installer-1.15.0-1.x86_64.rpm.asc
jreleaser-installer-1.15.0-windows-x86_64.msi.asc
jreleaser-native-1.15.0-osx-x86_64.zip.asc
jreleaser-native-1.15.0-osx-aarch64.zip.asc
jreleaser-native-1.15.0-linux-x86_64.zip.asc
jreleaser-native-1.15.0-windows-x86_64.zip.asc

# additional files
VERSION

Additionally, the following repositories will be updated with new packagers:

Docker images will also be published to DockerHub:

JARs and POMs will be posted to Maven Central:

Finally, Twitter, Mastodon, Bluesky threads will be posted, as well as a news item at https://jreleaser.noticeable.news and the https://opencollective.com/jreleaser pages.