Packaging And Releasing With JReleaser

Prerequisites

include::./_includes/prerequisites.adoc[]* GitHub 帐户和 GitHub 个人访问令牌

Bootstrapping the project

首先,我们需要一个定义 CLI 应用程序的项目。我们建议使用 PicoCLI扩展。这可以通过使用以下命令来完成:

CLI
quarkus create cli {create-cli-group-id}:{create-cli-artifact-id} \
    --no-code
cd {create-cli-artifact-id}

要创建一个 Gradle 项目,添加 --gradle--gradle-kotlin-dsl 选项。 有关如何安装和使用 Quarkus CLI 的详细信息,请参见 Quarkus CLI 指南。

Maven
mvn {quarkus-platform-groupid}:quarkus-maven-plugin:{quarkus-version}:create \
    -DprojectGroupId={create-cli-group-id} \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId={create-cli-artifact-id} \
    -DnoCode \
    -Dextensions='picocli'
cd {create-cli-artifact-id}

要创建一个 Gradle 项目,添加 -DbuildTool=gradle-DbuildTool=gradle-kotlin-dsl 选项。

此命令将初始化项目中的文件结构和最低必需的文件集:

.
├── README.md
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
    └── main
        ├── docker
        │   ├── Dockerfile.jvm
        │   ├── Dockerfile.legacy-jar
        │   └── Dockerfile.native
        ├── java
        │   └── org
        │       └── acme
        │           └── GreetingCommand.java
        └── resources
            └── application.properties

它还将在 pom.xml 中配置 picocli 扩展:

    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-picocli</artifactId>
    </dependency>

Preparing the project for GitHub releases

在继续之前该项目必须在一个 GitHub 仓库中托管。可以通过登录你的 GitHub 账户,创建一个新仓库,并将新创建的源添加到仓库来完成此任务。选择 main 分支作为默认分支以利用惯例,从而在 pom.xml 中做更少的配置。

您还需要一个 GitHub 个人访问令牌才能将版本发布到您刚刚创建的存储库。请遵循 creating a personal access token 的官方说明。将新创建的令牌存储在安全的地方,以便将来参考。接下来,您可以选择将令牌配置为名为 JRELEASER_GITHUB_TOKEN 的环境变量,以便工具可以读取它。或者,您可以使用 .yml.toml.json.properties 文件将令牌存储在您选择的安全位置。默认位置是 ~/.jreleaser/config[format]。例如,使用 .yml 格式,此文件可能如下所示:

~/.jreleaser/config.yml
JRELEASER_GITHUB_TOKEN: <github-token-value>

好的。添加所有源并创建一个首次提交。你可以选择自己的提交消息惯例,但是如果你按照 Conventional Commits 规范进行操作,那么在使用 JReleaser 时会获得更好的效果。使用以下消息“build:添加初始源”进行首次提交。

Packaging as a Native Image distribution

Quarkus 已经知道如何使用 GraalVM Native Image 创建一个本机可执行文件。默认设置将遵循命名约定来创建一个可执行文件。但是,JReleaser 工具期望一个发行版,即一个打包为 Zip 或 Tar 文件的传统文件结构。文件结构必须遵循此布局:

.
├── LICENSE
├── README
└── bin
    └── executable

此结构允许你添加可执行文件所需的所有支持文件,例如配置文件、shell 补全脚本、手册页、许可证、自述文件等。

Creating the distribution

我们可以利用 maven-assembly-plugin 来创建此类发行版。我们还将使用 os-maven-plugin 来正确识别此可执行文件可以运行的平台,并将该平台添加到发行版的文件名中。

首先,让我们将 os-maven-plugin 添加到 pom.xml 中。此插件用作 Maven 扩展,因此必须将其添加到文件的 <build> 部分:

  <build>
    <extensions>
      <extension>
        <groupId>kr.motd.maven</groupId>
        <artifactId>os-maven-plugin</artifactId>
        <version>1.7.1</version>
      </extension>
    </extensions>
    <!-- ... -->

接下来,Linux 和 macOS 平台上的本机可执行文件通常没有文件扩展名,但 Windows 可执行文件有,因此在重命名生成的可执行文件时我们需要处理此问题。我们还可以将生成的发布版本放置在其自己的目录中,以避免弄乱 target 目录。因此,让我们向 pom.xml 中现有的 <properties> 部分添加一些属性:

<executable-suffix/>
<distribution.directory>${project.build.directory}/distributions</distribution.directory>

现在我们配置 maven-assembly-plugin 以创建一个包含可执行文件和执行其工作可能需要的任何支持文件的 Zip 和 Tar 文件。特别注意发行版的名称,这是我们利用 os-maven-plugin 检测到的平台属性的位置。此插件在自己的配置文件中配置,其中 single 目标绑定到 package 阶段。这样做的目的是为了避免在每次调用构建时都重建发行版,因为我们只需要在准备发布时才进行此操作。

    <profile>
      <id>dist</id>
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>3.3.0</version>
            <configuration>
              <attach>false</attach>
              <appendAssemblyId>false</appendAssemblyId>
              <finalName>${project.artifactId}-${project.version}-${os.detected.classifier}</finalName>
              <outputDirectory>${distribution.directory}</outputDirectory>
              <workDirectory>${project.build.directory}/assembly/work</workDirectory>
              <descriptors>
                <descriptor>src/main/assembly/assembly.xml</descriptor>
              </descriptors>
            </configuration>
            <executions>
              <execution>
                <id>make-distribution</id>
                <phase>package</phase>
                <goals>
                  <goal>single</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
    </profile>
    <profile>
      <id>dist-windows</id>
      <activation>
        <os>
          <family>windows</family>
        </os>
      </activation>
      <properties>
        <executable-suffix>.exe</executable-suffix>
      </properties>
    </profile>

请注意,配置了两个配置文件。dist 配置文件配置了 assembly 插件,并且以这种方式配置,即必须通过将 -Pdist 作为命令标志传递来显式激活该配置。另一方面,当在 Windows 平台上运行构建时,dist-windows 配置文件会自动激活。第二个配置文件负责设置 executable-suffix 属性的值,这是装配描述符所必需的,如下所示:

src/main/assembly/assembly.xml
<assembly
        xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
    <id>dist</id>
    <formats>
        <format>tar.gz</format>
        <format>zip</format>
        <format>dir</format>
    </formats>
    <files>
        <file>
            <source>${project.build.directory}/${project.artifactId}-${project.version}-runner${executable-suffix}</source>
            <outputDirectory>./bin</outputDirectory>
            <destName>${project.artifactId}${executable-suffix}</destName>
        </file>
    </files>
</assembly>

以下是在 macOS 上调用 ./mvnw -Pdist package 时由装配插件创建的文件:

$ tree target/distributions/
target/distributions/
├── app-1.0.0-SNAPSHOT-osx-x86_64
│   └── app-1.0.0-SNAPSHOT-osx-x86_64
│       └── bin
│           └── app
├── app-1.0.0-SNAPSHOT-osx-x86_64.tar.gz
└── app-1.0.0-SNAPSHOT-osx-x86_64.zip

请随意更新装配描述符以包含其他文件,例如 LICENSE、自述文件或可执行文件使用者需要的任何其他文件。在此处进行另一次提交,提交消息为“build:配置发行版装配”。

我们已准备好进入下一阶段:配置版本。

Adding JReleaser

JReleaser 工具可以通过多种方式调用:作为 CLI 工具、作为 Docker 镜像或作为 Maven 插件。鉴于我们已经在使用 Maven,最后一个选项非常方便。让我们添加另一个包含发布配置的配置文件,因为我们再次不需要此行为一直处于活动状态,而只在准备发布版本时才需要:

    <profile>
      <id>release</id>
      <build>
        <plugins>
          <plugin>
            <groupId>org.jreleaser</groupId>
            <artifactId>jreleaser-maven-plugin</artifactId>
            <version>1.6.0</version>
          </plugin>
        </plugins>
      </build>
    </profile>

此时我们可以调用一些目标,例如我们可以通过调用 ./mvnw -Prelease jreleaser:config 命令要求 JReleaser 打印其当前配置。该工具将输出它关于该项目知道的所有信息。我们还可以通过调用 ./mvnw -Prelease jreleaser:changelog 来生成变更日志。将把包含变更日志的文件放置在 target/jreleaser/release/CHANGELOG.md 中,此时应如下所示:

target/jreleaser/release/CHANGELOG.md
## Changelog

8ef3307 build: Configure distribution assembly
5215200 build: Add initial sources

不太令人兴奋,但是我们可以通过指示 JReleaser 按照我们自己的约定格式化变更日志来更改此内容。你可以手动指定模式来对提交进行分类,但是如果你选择遵循约定提交规范,我们可以指示 JReleaser 执行相同的操作。将以下内容添加到 JRelaser 插件配置部分:

            <configuration>
              <jreleaser>
                <release>
                  <github>
                    <changelog>
                      <formatted>ALWAYS</formatted>
                      <preset>conventional-commits</preset>
                    </changelog>
                  </github>
                </release>
              </jreleaser>
            </configuration>

再次运行以前的 Maven 命令并检查生成的变更日志,现在它应该如下所示:

target/jreleaser/release/CHANGELOG.md
## Changelog

## 🛠  Build
- 8ef3307 Configure distribution assembly (Andres Almiray)
- 5215200 Add initial sources (Andres Almiray)


## Contributors
We'd like to thank the following people for their contributions:
Andres Almiray

可能还有其他可以应用的格式选项,但目前这些选项就足够了。让我们立即进行另一项提交,将“build: Configure JReleaser plugin”作为提交消息。如果您愿意,您可以再次生成变更日志,并看到将此最新提交添加到文件中。

Adding distributions to the release

我们已经达到了可以配置二进制分发的阶段。如果您运行 ./mvnw -Prelease jreleaser:config 命令,您会注意到没有提及我们在之前的步骤中配置的任何分发文件。这是因为该工具没有它们的隐式知识,我们必须告诉 JReleaser 我们想要发布哪些文件。这样,可以将创建分发与发布资产分离,因为您可能希望随意添加或删除文件。对于这个特定案例,我们将为 macOS 和 Windows 配置 Zip 文件,为 Linux 配置 Tar 文件。这些文件必须添加到 JReleaser 插件配置部分,如下所示:

            <configuration>
              <jreleaser>
                <release>
                  <github>
                    <changelog>
                      <formatted>ALWAYS</formatted>
                      <preset>conventional-commits</preset>
                    </changelog>
                  </github>
                </release>
                <distributions>
                  <app>
                    <type>BINARY</type>
                    <artifacts>
                      <artifact>
                        <path>${distribution.directory}/{{distributionName}}-{{projectVersion}}-linux-x86_64.tar.gz</path>
                        <platform>linux-x86_64</platform>
                      </artifact>
                      <artifact>
                        <path>${distribution.directory}/{{distributionName}}-{{projectVersion}}-windows-x86_64.zip</path>
                        <platform>windows-x86_64</platform>
                      </artifact>
                      <artifact>
                        <path>${distribution.directory}/{{distributionName}}-{{projectVersion}}-osx-x86_64.zip</path>
                        <platform>osx-x86_64</platform>
                      </artifact>
                    </artifacts>
                  </app>
                </distributions>
              </jreleaser>
            </configuration>

我们可以看到一个名为 app 的分发(为了方便起见,与项目的 artifactId 相同),其中配置了 3 个工件。请注意,使用 Maven 属性和 Mustache 模板来定义路径。如果您愿意,可以使用显式值,或依靠属性对配置进行参数化。在构建验证期间,Maven 属性会急切解析,而在执行 JReleaser 插件目标期间,Mustache 模板会延时解析。每个工件必须定义一个 platform 属性,以便唯一标识它们。如果我们运行 ./mvnw -Prelease jreleaser:config ,我们将很快收到一个错误,因为现在存在已配置的分发,该插件期望项目提供更多元数据:

[ERROR] == JReleaser ==
[ERROR] project.copyright must not be blank
[ERROR] project.description must not be blank
[ERROR] project.website must not be blank
[ERROR] project.docsUrl must not be blank
[ERROR] project.license must not be blank
[ERROR] project.authors must not be blank

可以通过两种方式提供此元数据:作为 JReleaser 插件配置的一部分或使用标准 POM 元素。如果您选择前一个选项,则插件的配置可能如下所示:

            <configuration>
              <jreleaser>
                <project>
                 <description>app - Sample Quarkus CLI application</description>
                 <links>
                   <homepage>[role="bare"]https://github.com/aalmiray/app</homepage>
                   <documentation>[role="bare"]https://github.com/aalmiray/app</documentation>
                 </links>
                 <license>APACHE-2.0</license>
                 <authors>Andres Almiray</authors>
                 <copyright>2021 Kordamp</copyright>
                </project>
                <!-- ... -->

如果您选择使用标准 POM 元素,则您的 pom.xml 至少必须包含这些条目,当然要将值调整为您自己的值:

  <name>app</name>
  <description>app -- Sample Quarkus CLI application</description>
  <inceptionYear>2021</inceptionYear>
  <url>https://github.com/aalmiray/app</url>
  <developers>
    <developer>
      <id>aalmiray</id>
      <name>Andres Almiray</name>
    </developer>
  </developers>
  <licenses>
    <license>
      <name>Apache-2.0</name>
      <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
      <distribution>repo</distribution>
    </license>
  </licenses>

然而,我们还没有脱离困境,再次调用 ./mvnw -Prelease jreleaser:config 仍然会导致另一个错误,这次失败与丢失的工件有关。这是因为我们还没有组装所有必需的工件,但是该插件期望它们很容易获得。在这里,您可以选择在其他节点上构建必需的工件,然后将它们复制到各自的预期位置——这是一项可以通过在多个节点上运行 GitHub Actions 工作流来执行的任务。或者,您可以指示 JReleaser 忽略某些工件,并只选择与您当前平台匹配的工件。之前我们展示了在 macOS 上创建分发时的分发样子,假设我们仍然在该平台上,我们拥有正确的工件。

此时,我们可以指示 JReleaser 仅选择与 macOS 匹配的工件,方法是使用附加标志调用 jreleaser:config 目标: ./mvnw -Prelease jreleaser:config -Djreleaser.select.current.platform 。这次该命令将成功并打印出模型。请注意,只有 macOS 工件的路径已被完全解析,而其他 2 个路径保持不变。

让我们在此处进行一次提交,以“build: Configure distribution artifacts”作为消息。我们可以通过调用不同的目标立即创建发布: ./mvnw -Prelease jreleaser:release -Djreleaser.select.current.platform 。这将在所选存储库中创建一个 Git 发布,其中包括为存储库添加标签、上传变更日志、所有分发工件及其作为发布资产的校验和。

但在我们这样做之前,让我们添加一个附加功能,让我们创建一个 Homebrew 配方,这将使用户更轻松地在 macOS 上使用二进制分发,好吗?

Configuring Homebrew as a packager

Homebrew 是 macOS 用户用来安装和管理二进制文件的流行选择。本质上,Homebrew 包是一个 Ruby 文件(称为配方),在目标环境中执行以安装或升级特定二进制文件。JReleaser 可以从二进制分发(例如我们已经配置的那个)创建配方。

为此,我们只需要在 JReleaser 插件配置中启用 Homebrew,如下所示:

                <distributions>
                  <app>
                    <type>BINARY</type>
                    <brew>
                      <active>ALWAYS</active>
                    </brew>
                    <artifacts>
                      <artifact>
                        <path>${distribution.directory}/{{distributionName}}-{{projectVersion}}-linux-x86_64.tar.gz</path>
                        <platform>linux-x86_64</platform>
                      </artifact>
                      <artifact>
                        <path>${distribution.directory}/{{distributionName}}-{{projectVersion}}-windows-x86_64.zip</path>
                        <platform>windows-x86_64</platform>
                      </artifact>
                      <artifact>
                        <path>${distribution.directory}/{{distributionName}}-{{projectVersion}}-osx-x86_64.zip</path>
                        <platform>osx-x86_64</platform>
                      </artifact>
                    </artifacts>
                  </app>
                </distributions>

最后一点:发布非快照版本时,建议发布 Homebrew 配方,因此将项目的版本从 1.0.0-SNAPSHOT 变成 1.0.0.Alpha1 或直接变为 1.0.0 ,由您决定。进行最后一次提交,大功告成:以 feat: Add Homebrew packager configuration 作为提交消息。好了,我们终于准备好了,让我们发布吧!

Creating a release

pom.xml 中添加配置的 whirlwind 之旅已经尘埃落定,但这只是为了让项目准备好进行首次发布;后续发布对配置的修改较少。我们可以使用 jreleaser:full-release 目标创建 Git 发布和 Homebrew 配方,但如果您仍然对事情的发展方式心存疑虑,则可以以干运行模式调用该目标,即让 JReleaser 执行所需的所有本地操作,而不会影响远程资源,如 Git 存储库。它看起来如下所示:

# because we changed the project's version
./mvnw -Dnative,dist package
./mvnw -Prelease jreleaser:full-release -Djreleaser.select.current.platform -Djreleaser.dry.run=true

[INFO] --- jreleaser-maven-plugin:1.6.0:full-release (default-cli) @ app ---
[INFO] JReleaser 1.6.0
[INFO]   - basedir set to /tmp/app
[INFO]   - outputdir set to /tmp/app/target/jreleaser
[WARNING] Platform selection is in effect
[WARNING] Artifacts will be filtered by platform matching: [osx-x86_64]
[INFO] git-root-search set to false
[INFO] Loading variables from /Users/aalmiray/.jreleaser/config.toml
[INFO] Validating configuration
[INFO] Strict mode set to false
[INFO] Project version set to 1.0.0.Alpha1
[INFO] Release is not snapshot
[INFO] Timestamp is 2023-04-27T15:06:34.289907+02:00
[INFO] HEAD is at 73603ac
[INFO] Platform is osx-x86_64
[INFO] dry-run set to true
[INFO] Generating changelog
[INFO] Storing changelog: target/jreleaser/release/CHANGELOG.md
[INFO] Cataloging artifacts
[INFO]   [sbom] Cataloging is not enabled. Skipping
[INFO] Calculating checksums for distributions and files
[INFO]   [checksum] target/distributions/app-1.0.0.Alpha1-osx-x86_64.zip.sha256
[INFO] Signing distributions and files
[INFO]   [sign] Signing is not enabled. Skipping
[INFO] Deploying Maven artifacts
[INFO]   [maven] Deploying is not enabled. Skipping
[INFO] Uploading distributions and files
[INFO]   [upload] Uploading is not enabled. Skipping
[INFO] Releasing to https://github.com/aalmiray/app@main
[INFO]  - uploading app-1.0.0.Alpha1-osx-x86_64.zip
[INFO]  - uploading checksums_sha256.txt
[INFO] Preparing distributions
[INFO]   - Preparing app distribution
[INFO]     [brew] preparing app distribution
[INFO] Packaging distributions
[INFO]   - Packaging app distribution
[INFO]     [brew] packaging app distribution
[INFO] Publishing distributions
[INFO]   - Publishing app distribution
[INFO]     [brew] publishing app distribution
[INFO]     [brew] setting up repository aalmiray/homebrew-tap
[INFO] Announcing release
[INFO]   [announce] Announcing is not enabled. Skipping
[INFO] Writing output properties to target/jreleaser/output.properties
[INFO] JReleaser succeeded after 0.620 s

JReleaser 将为我们执行以下任务:

  • 根据从上一次标签(如果有)到最新提交的所有提交生成 changelog。

  • 为所有输入文件计算 SHA256(默认)校验和。

  • 使用 GPG 对所有文件进行签名。在我们的案例中,我们没有配置此步骤,因此跳过了此步骤。

  • 将资产上传到 JFrog Artifactory 或 AWS S3。由于未进行配置,我们也跳过此步骤。

  • 在所选存储库中创建一个 Git 发布,并为其添加标签。

  • 上传所有的资产,包括校验和。

  • 创建 Homebrew 公式,发布到“[role="bare"]https://github.com/aalmiray/homebrew-tap”。

当然没有远程存储库受到影响,因为我们可以赞赏“-Djreleaser.dry.run=true”属性的有效性。如果您有这方面的倾向,请检查“target/jreleaser/package/app/brew/Formula/app.rb”的内容,它定义了要发布的 Homebrew 公式。它看起来应该如下所示:

app.rb
# Generated with JReleaser 1.6.0 at 2023-04-27T15:06:34.289907+02:00
class App < Formula
  desc "app -- Sample Quarkus CLI application"
  homepage "pass:[https://github.com/aalmiray/app]"
  url "pass:[https://github.com/aalmiray/app/releases/download/v1.0.0.Alpha1/app-1.0.0.Alpha1-osx-x86_64.zip]"
  version "1.0.0.Alpha1"
  sha256 "85c9918b23e3ac4ef64d5dd02714e241231d3f1358afdba09d3fd0b9a889e131"
  license "Apache-2.0"


  def install
    libexec.install Dir["*"]
    bin.install_symlink "#{libexec}/bin/app" => "app"
  end

  test do
    output = shell_output("#{bin}/app --version")
    assert_match "1.0.0.Alpha1", output
  end
end

准备就绪后,通过从命令行中简单地删除“-Djreleaser.dry.run”标志,这次为真创建版本,然后浏览您的存储库,看看新创建的版本。

Further reading

Reference

作为参考,这里有“pom.xml”的完整内容:

<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.acme</groupId>
  <artifactId>app</artifactId>
  <version>1.0.0.Alpha1</version>
  <name>app</name>
  <description>app -- Sample Quarkus CLI application</description>
  <inceptionYear>2021</inceptionYear>
  <url>https://github.com/aalmiray/app</url>
  <developers>
    <developer>
      <id>aalmiray</id>
      <name>Andres Almiray</name>
    </developer>
  </developers>
  <licenses>
    <license>
      <name>Apache-2.0</name>
      <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
      <distribution>repo</distribution>
    </license>
  </licenses>
  <properties>
    <executable-suffix/>
    <distribution.directory>${project.build.directory}/distributions</distribution.directory>
    <compiler-plugin.version>3.13.0</compiler-plugin.version>
    <maven.compiler.parameters>true</maven.compiler.parameters>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
    <quarkus.platform.group-id>{quarkus-platform-groupid}</quarkus.platform.group-id>
    <quarkus.platform.version>{quarkus-version}</quarkus.platform.version>
    <surefire-plugin.version>3.0.0</surefire-plugin.version>
  </properties>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>${quarkus.platform.group-id}</groupId>
        <artifactId>${quarkus.platform.artifact-id}</artifactId>
        <version>${quarkus.platform.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-picocli</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-arc</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-junit5</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <build>
    <extensions>
      <extension>
        <groupId>kr.motd.maven</groupId>
        <artifactId>os-maven-plugin</artifactId>
        <version>1.7.1</version>
      </extension>
    </extensions>
    <plugins>
      <plugin>
        <groupId>${quarkus.platform.group-id}</groupId>
        <artifactId>quarkus-maven-plugin</artifactId>
        <version>${quarkus.platform.version}</version>
        <extensions>true</extensions>
        <executions>
          <execution>
            <goals>
              <goal>build</goal>
              <goal>generate-code</goal>
              <goal>generate-code-tests</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>${compiler-plugin.version}</version>
        <configuration>
          <parameters>${maven.compiler.parameters}</parameters>
        </configuration>
      </plugin>
      <plugin>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>${surefire-plugin.version}</version>
        <configuration>
          <systemPropertyVariables>
            <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
            <maven.home>${maven.home}</maven.home>
          </systemPropertyVariables>
        </configuration>
      </plugin>
    </plugins>
  </build>
  <profiles>
    <profile>
      <id>native</id>
      <activation>
        <property>
          <name>native</name>
        </property>
      </activation>
      <properties>
        <skipITs>false</skipITs>
        <quarkus.native.enabled>true</quarkus.native.enabled>
      </properties>
    </profile>
    <profile>
      <id>dist</id>
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>3.3.0</version>
            <configuration>
              <attach>false</attach>
              <appendAssemblyId>false</appendAssemblyId>
              <finalName>${project.artifactId}-${project.version}-${os.detected.classifier}</finalName>
              <outputDirectory>${distribution.directory}</outputDirectory>
              <workDirectory>${project.build.directory}/assembly/work</workDirectory>
              <descriptors>
                <descriptor>src/main/assembly/assembly.xml</descriptor>
              </descriptors>
            </configuration>
            <executions>
              <execution>
                <id>make-distribution</id>
                <phase>package</phase>
                <goals>
                  <goal>single</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
    </profile>
    <profile>
      <id>dist-windows</id>
      <activation>
        <os>
          <family>windows</family>
        </os>
      </activation>
      <properties>
        <executable-suffix>.exe</executable-suffix>
      </properties>
    </profile>
    <profile>
      <id>release</id>
      <build>
        <plugins>
          <plugin>
            <groupId>org.jreleaser</groupId>
            <artifactId>jreleaser-maven-plugin</artifactId>
            <version>1.6.0</version>
            <configuration>
              <jreleaser>
                <!--project>
                 <description>app - Sample Quarkus CLI application</description>
                 <website>https://github.com/aalmiray/app</website>
                 <docsUrl>https://github.com/aalmiray/app</docsUrl>
                 <license>APACHE-2.0</license>
                 <authors>Andres Almiray</authors>
                 <copyright>2021 Kordamp</copyright>
                </project-->
                <release>
                  <github>
                    <changelog>
                      <formatted>ALWAYS</formatted>
                      <preset>conventional-commits</preset>
                    </changelog>
                  </github>
                </release>
                <distributions>
                  <app>
                    <type>BINARY</type>
                    <brew>
                      <active>ALWAYS</active>
                    </brew>
                    <artifacts>
                      <artifact>
                        <path>${distribution.directory}/{{distributionName}}-{{projectVersion}}-linux-x86_64.tar.gz</path>
                        <platform>linux-x86_64</platform>
                      </artifact>
                      <artifact>
                        <path>${distribution.directory}/{{distributionName}}-{{projectVersion}}-windows-x86_64.zip</path>
                        <platform>windows-x86_64</platform>
                      </artifact>
                      <artifact>
                        <path>${distribution.directory}/{{distributionName}}-{{projectVersion}}-osx-x86_64.zip</path>
                        <platform>osx-x86_64</platform>
                      </artifact>
                    </artifacts>
                  </app>
                </distributions>
              </jreleaser>
            </configuration>
          </plugin>
        </plugins>
      </build>
    </profile>
  </profiles>
</project>