编辑此页面

使用 JReleaser 打包和发布

本指南介绍如何使用 JReleaser 工具打包和发布 CLI 应用程序。

1. 前提条件

要完成本指南,您需要

  • 大约 15 分钟

  • 一个 IDE

  • 已安装 JDK 17+ 并正确配置了 JAVA_HOME

  • Apache Maven 3.9.9

  • 如果您想使用它,可以选择 Quarkus CLI

  • 如果您想构建本机可执行文件(或者如果您使用本机容器构建,则为 Docker),可以选择安装 Mandrel 或 GraalVM 并进行适当的配置

  • 一个 GitHub 账户和一个 GitHub 个人访问令牌

2. 项目引导

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

CLI
quarkus create cli org.acme:app
cd app

要创建 Gradle 项目,请添加 --gradle--gradle-kotlin-dsl 选项。

有关如何安装和使用 Quarkus CLI 的更多信息,请参阅 Quarkus CLI 指南。

Maven
mvn io.quarkus.platform:quarkus-maven-plugin:3.24.4:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=app \
    -Dextensions='picocli'
cd app

要创建 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>

3. 为 GitHub 发布准备项目

在我们继续之前,项目必须托管在 GitHub 存储库中。可以通过登录您的 GitHub 账户、创建新存储库并将新创建的源添加到 said 存储库来完成此任务。选择 main 分支作为默认分支,以利用约定,从而在 pom.xml 中进行更少的配置。

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

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

好的。添加所有源并创建第一个提交。您可以为提交消息选择自己的约定,但如果您遵循 Conventional Commits 规范,您将从 JReleaser 中获得更多收益。使用以下消息“build: Add initial sources”创建您的第一个提交。

4. 打包为原生镜像分发

Quarkus 已经知道如何使用 GraalVM Native Image 创建原生可执行文件。默认设置将创建一个遵循命名约定的单个可执行文件。但是,JReleaser 工具需要一个分发,即一种常规文件结构,打包为 Zip 或 Tar 文件。文件结构必须遵循此布局

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

此结构允许您添加可执行文件所需的各种支持文件,例如配置文件、shell 补全脚本、man 页、许可证、README 等。

5. 创建分发

我们可以利用 maven-assembly-plugin 来创建这样的分发。我们还将使用 Nisse Maven plugin 来正确识别可执行文件运行的平台,并将 said 平台添加到分发的文件名中。

首先,我们将 Nisse Maven 插件添加到 pom.xml。此插件必须添加到文件中的 <build> 部分

  <build>
    <plugins>
      <plugin>
        <groupId>eu.maveniverse.maven.plugins</groupId>
        <artifactId>nisse-plugin3</artifactId>
        <version>0.4.0</version>
        <executions>
          <execution>
            <id>inject-properties</id>
              <goals>
                <goal>inject-properties</goal>
              </goals>
              <phase>validate</phase>
            </execution>
          </executions>
        </plugin>
    <!-- ... -->

为了让此插件生成正确的属性,我们需要确保设置了 nisse.compat.osDetector 系统属性。这可以通过添加以下 .mvn/maven.config 文件来完成

-Dnisse.compat.osDetector=true

接下来,Linux 和 macOS 平台上的原生可执行文件通常没有文件扩展名,但 Windows 可执行文件有,我们在重命名生成的​​可执行文件时需要注意这一点。我们还可以将生成的分发文件放在自己的目录中,以避免使 target 目录混乱。因此,让我们向 pom.xml 中现有的 <properties> 部分添加几个属性

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

现在我们配置 maven-assembly-plugin 来创建包含可执行文件及其执行任务所需的任何支持文件的 Zip 和 Tar 文件。请特别注意分发的名称,这是我们利用 os-detector-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 属性设置值,该属性是 assembly 描述符所必需的,如下所示

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>

这些是调用 ./mvnw -Pdist package 在 macOS 上时由 assembly 插件创建的文件

$ 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

您可以随意更新 assembly 描述符以包含其他文件,例如 LICENSE、README 或可执行文件的使用者所需的任何其他文件。在此处再次进行提交,消息为“build: Configure distribution assembly”。

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

6. 添加 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 根据我们自己的约定格式化变更日志来改变这一点。您可以手动指定模式来分类提交,但是如果您选择遵循 Conventional Commits,我们可以指示 JReleaser 执行相同的操作。将以下内容添加到 JReleaser 插件配置部分

            <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”。如果您愿意,可以再次生成变更日志,看看最新的提交已添加到文件中。

7. 将分发添加到发布

我们已经到了可以配置二进制分发的阶段。如果您运行 ./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 属性在构建验证期间立即解析,而 Mustache 模板在 JReleaser 插件目标执行期间延迟解析。每个工件都必须定义一个 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><a href="https://github.com/aalmiray/app" class="bare">https://github.com/aalmiray/app</a></homepage>
                   <documentation><a href="https://github.com/aalmiray/app" class="bare">https://github.com/aalmiray/app</a></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>https://apache.ac.cn/licenses/LICENSE-2.0.txt</url>
      <distribution>repo</distribution>
    </license>
  </licenses>

然而,我们还没有完全解决问题,因为再次调用 ./mvnw -Prelease jreleaser:config 仍然会导致另一个错误,这次的失败与缺少工件有关。这是因为我们没有组装所有必需的工件,但插件期望它们已经可用。在这里,您可以选择在其他节点上构建所需的工件,然后将它们复制到预期的位置 — 这是一项可以通过在多个节点上运行 GitHub Actions 工作流来完成的任务。或者,您可以指示 JReleaser 忽略某些工件,只选择与当前平台匹配的工件。之前我们展示了在 macOS 上创建分发时它的外观,假设我们仍在该平台,我们有正确的工件。

此时,我们可以通过调用 jreleaser:config 目标并添加一个额外的标志来指示 JReleaser 只选择与 macOS 匹配的工件:./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 用户可以轻松使用二进制分发,好吗?

8. 配置 Homebrew 作为打包器

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。好了,我们终于准备好了,让我们发布一个版本!

9. 创建发布

这是对 pom.xml 添加配置的快速浏览,但这只是为了让项目准备好进行首次发布;后续发布需要更少的配置修改。我们可以使用 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 将为我们执行以下任务

  • 根据自上次标记(如果有)以来的所有提交到最新提交生成变更日志。

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

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

  • 将资产上传到 JFrog Artifactory 或 AWS S3。我们也将跳过此步骤,因为它未配置。

  • 在选定的存储库中创建 Git 发布,并进行标记。

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

  • 创建 Homebrew 公式,发布到 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 标志,然后浏览到您的存储库,查看新创建的发布。

10. 进一步阅读

11. 参考

作为参考,这是 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>https://apache.ac.cn/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.14.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>io.quarkus.platform</quarkus.platform.group-id>
    <quarkus.platform.version>3.24.4</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>
    <plugins>
      <plugin>
        <groupId>eu.maveniverse.maven.nisse</groupId>
        <artifactId>plugin3</artifactId>
        <version>0.3.4</version>
        <executions>
          <execution>
            <id>inject-properties</id>
            <goals>
              <goal>inject-properties</goal>
            </goals>
            <phase>validate</phase>
          </execution>
        </executions>
      </plugin>
      <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>

相关内容