使用 Jenkins 到 Artifactory 在 GitLab 中构建和发布 Scala/Jav

一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / Java 学习路线 / 一对一提问 / 学习打卡/ 赠书活动

目前,正在 星球 内带小伙伴们做第一个项目:全栈前后端分离博客项目,采用技术栈 Spring Boot + Mybatis Plus + Vue 3.x + Vite 4手把手,前端 + 后端全栈开发,从 0 到 1 讲解每个功能点开发步骤,1v1 答疑,陪伴式直到项目上线,目前已更新了 204 小节,累计 32w+ 字,讲解图:1416 张,还在持续爆肝中,后续还会上新更多项目,目标是将 Java 领域典型的项目都整上,如秒杀系统、在线商城、IM 即时通讯、权限管理等等,已有 870+ 小伙伴加入,欢迎点击围观

我将详细展示如何定期构建您的项目,然后如何进行发布构建。它涉及许多工具的协作,我发现这些工具很难正确设置,这就是我写这篇文章的原因。

目标

我将向您展示如何实现以下两个场景。第一个是如何进行常规开发非发布构建:

  1. 实施一些东西,提交并将其推送到 GitLab。
  2. 通过 GitLab 的网络挂钩触发 Jenkins 构建。
  3. 构建、测试、组装然后将二进制 JAR 发布到 Artifactory 存储库。

第二个也是更有趣的目标是当您想要构建发布版本时:

  1. 运行使用 Gradle 发布插件的参数化 Jenkins 构建来:
    1. 验证项目是否满足要发布的特定条件。
    2. 使用发布版本号创建 Git 标签。
    3. 修改 Gradle 项目版本以允许进一步开发。
    4. 提交此更改并将其推送到 GitLab。
  2. 触发另一个通用参数 Jenkins 构建以将发布工件发布到 Artifactory。

情况

我将演示描述我使用 Gradle 构建的真实 Scala 项目的过程 构建服务器是 Jenkins 。二进制工件发布到运行免费版 Artifactory 的服务器。版本控制系统是 GitLab 的免费社区版。我相信对于任何 Java 应用程序,您都可以遵循本指南。为了本指南的清晰起见,我们假设您的网址如下:

  • GitLab 存储库 (SSH) = git@gitlab.local:com.buransky/release-example.git
  • 詹金斯服务器 = http://jenkins/
  • Artifactory 服务器 = http://artifactory/

项目结构

不需要什么特别的。我使用通用的目录结构:


 <project root>
  + build (build output)
  + gradle (Gradle wrapper)
  + src (source code)
  + main
    + scala
  + test
    + scala
  - build.gradle
  - gradle.properties
  - gradlew
  - gradlew.bat
  - settings.gradle

摇篮项目

我使用 Gradle wrapper 这只是一个方便的工具来下载和安装 Gradle 本身,如果它没有安装在机器上的话。这不是必需的。但是你需要有这三个文件:

settings.gradle – 多项目的通用 Gradle 设置,对我们来说并不是真正需要的


 <project root>
  + build (build output)
  + gradle (Gradle wrapper)
  + src (source code)
  + main
    + scala
  + test
    + scala
  - build.gradle
  - gradle.properties
  - gradlew
  - gradlew.bat
  - settings.gradle

gradle.properties – 包含组名、项目名和版本


 <project root>
  + build (build output)
  + gradle (Gradle wrapper)
  + src (source code)
  + main
    + scala
  + test
    + scala
  - build.gradle
  - gradle.properties
  - gradlew
  - gradlew.bat
  - settings.gradle

build.gradle – 主要的 Gradle 项目定义


 <project root>
  + build (build output)
  + gradle (Gradle wrapper)
  + src (source code)
  + main
    + scala
  + test
    + scala
  - build.gradle
  - gradle.properties
  - gradlew
  - gradlew.bat
  - settings.gradle

添加以下内容以生成带有源的 JAR 文件:


 <project root>
  + build (build output)
  + gradle (Gradle wrapper)
  + src (source code)
  + main
    + scala
  + test
    + scala
  - build.gradle
  - gradle.properties
  - gradlew
  - gradlew.bat
  - settings.gradle

让我们测试一下。从外壳运行:


 <project root>
  + build (build output)
  + gradle (Gradle wrapper)
  + src (source code)
  + main
    + scala
  + test
    + scala
  - build.gradle
  - gradle.properties
  - gradlew
  - gradlew.bat
  - settings.gradle

现在您应该在 build/libs 目录中有两个 JAR 文件:

  • 发布示例 1.0.0-SNAPSHOT.jar
  • 发布示例 1.0.0-SNAPSHOT-sources.jar

好的,所以如果这有效,让我们尝试发布它:


 <project root>
  + build (build output)
  + gradle (Gradle wrapper)
  + src (source code)
  + main
    + scala
  + test
    + scala
  - build.gradle
  - gradle.properties
  - gradlew
  - gradlew.bat
  - settings.gradle

因为我没有使用所需参数运行发布任务,所以构建是交互式的,首先要求我输入(或确认)发布版本,即 1.0.0。然后它再次要求我输入插件自动建议为 1.0.1-SNAPSHOT 的下一个工作版本。我没有输入任何内容,我只是按回车键确认了默认值。

查看 Git 历史记录,您应该会在本地存储库和 GitLab 中看到一个名为 v1.0.0 的标签。同时打开 gradle.properties 文件,您应该会看到版本已更改为 version=1.0.1-SNAPSHOT。

发布任务需要很多东西。例如,您的工作目录不得包含未提交的更改。或者您所有的项目依赖项都必须是发布版本(它们不能是快照)。或者您当前的分支必须是 master。此外,您必须有权推送到 GitLab 中的 master 分支,因为发布插件将执行 git push。

设置 Artifactory

在 Artifactory 方面没有什么特别需要做的。我假设它在 http://artifactory/ 处启动并运行。当然,您的 URL 可能不同。默认安装已经有两个我们将发布到的存储库:

  • libs-release-local
  • 库快照本地

Jenkins Artifactory 插件

这个插件将 Jenkins 与 Artifactory 集成在一起,可以从 Jenkins 构建中发布工件。安装插件,转到 Jenkins 配置,在 Artifactory 部分添加新的 Artifactory 服务器并设置以下内容:

  • URL = http://artifactory/(你的不一样)
  • 默认部署者凭证
    • 为有权部署的现有 Artifactory 用户提供用户名和密码

单击测试连接按钮以确保这部分工作正常。

持续集成 Jenkins 构建

这是在每次提交到 master 分支并推送到 GitLab 之后运行的构建。将其创建为一个新的自由式项目,并为其命名。以下是此构建的步骤和设置列表:

  • 源代码管理——Git
    • 存储库 URL = git@gitlab.local:com.buransky/release-example.git(你的不一样)
    • Credentials = none(至少我不需要)
    • 要构建的分支,分支说明符 = */master
  • 构建触发器
    • 轮询 SCM(这是必需的,以便 GitLab 的 webhook 工作)
  • 搭建环境
    • Gradle-Artifactory 集成(需要 Artifactory 插件)
  • 人工配置
    • Artifactory server = http://artifactory/ (你的不一样)
    • Publishing repository = libs-snapshot-local(我们要发布快照)
    • 捕获和发布构建信息
    • 将工件发布到 Artifactory
      • 发布 Maven 描述符
    • 使用 Maven 兼容模式
      • ivy pattern = [organisation]/[module]/ivy-[revision].xml
      • 工件模式 = [组织]/[模块]/[修订版]/[工件]-[修订版](-[分类器]).[ext]
  • 构建——调用 Gradle 脚本
    • 使用 Gradle 包装器
    • 从根构建脚本目录
    • 任务 = 干净测试

运行构建,然后到 Artifactory 检查快照是否已成功发布。我使用树浏览器导航到 libs-snapshot-local/com/buransky/release-example/1.0.1-SNAPSHOT。在那里你应该找到:

  • 二进制 JAR
  • 源 JAR
  • POM文件

每次运行此构建时,都会在此处添加三个新文件。您可以将 Artifactory 配置为删除旧快照以节省空间。我只保留 5 张最新的快照。

从 GitLab 触发 Jenkins 构建

我们懒得手动运行我们刚刚创建的持续集成 Jenkins 构建。我们可以将 GitLab 配置为在每次推送后自动为我们完成。转到您的 GitLab 项目设置,Web Hooks 部分。输入以下内容,然后单击“添加 Web 挂钩”按钮:

  • URL = http://jenkins/git/notifyCommit?url=git@gitlab.local:com.buransky/release-example.git
    • 嘿!思考。您的网址不同,但模式应该相同。
  • 触发器 = 推送事件

如果您尝试测试此挂钩并单击“测试挂钩”按钮,您可能会惊讶于没有触发构建。原因(经常)可能是该机制非常智能,如果没有新提交,则构建不会运行。因此,对您的源代码进行更改、提交、推送,然后应该触发 Jenkins 构建。

休息一下,给自己泡杯咖啡

这已经是很多工作了。我们现在可以做很多事情。服务器工作并相互交谈。我希望您可能需要在各个机器之间设置 SSH,但这超出了本文的讨论范围。准备好继续了吗?让我们释放这个 sh*t。

Generic Jenkins Build 发布到 Artifactory

我们即将创建一个参数化的 Jenkins 构建,它从 git 中检出版本修订,构建它并将工件部署到 Artifactory。此构建是通用的,因此可以将其重复用于各个项目。让我们从新的自由式 Jenkins 项目开始,然后设置以下内容:

  • 项目名称 = 发布发布到 Artifactory
  • 此构建已参数化
    • 字符串参数
      • 名称 = GIT_REPOSITORY_URL
    • Git 参数
      • 名称 = GIT_RELEASE_TAG
      • 参数类型 = 标签
      • 标记过滤器 = *
    • 字符串参数
      • 名称 = GRADLE_TASKS
      • 默认值 = 干净组装
  • 源代码管理——Git
    • 存储库 URL = $GIT_REPOSITORY_URL
    • 要构建的分支,分支说明符 = */tags/${GIT_RELEASE_TAG}
  • 搭建环境
    • 在构建开始之前删除工作区
    • Gradle-Artifactory 集成
  • 人工配置
    • Artifactory server = http://artifactory/ (你的不一样)
    • Publishing repository = libs-release-local(我们要发布一个release)
    • 捕获和发布构建信息
    • 将工件发布到 Artifactory
      • 发布 Maven 描述符
    • 使用 Maven 兼容模式
      • ivy pattern = [organisation]/[module]/ivy-[revision].xml
      • 工件模式 = [组织]/[模块]/[修订版]/[工件]-[修订版](-[分类器]).[ext]
  • 构建——调用 Gradle 脚本
    • 使用 Gradle 包装器
    • 从根构建脚本目录
    • 任务 = $GRADLE_TASKS

通用 Jenkins 构建以发布 Gradle 项目

我们还需要一个可重用的参数化 Jenkins 构建,它使用提供的参数运行 Gradle 发布插件,然后触发我们已经创建的通用发布 Jenkins 构建。

  • 项目名称 = 发布 Gradle 项目
  • 此构建已参数化
    • 字符串参数
      • 名称 = GIT_REPOSITORY_URL
    • 字符串参数
      • 名称 = RELEASE_VERSION
    • 字符串参数
      • 名称 = NEW_VERSION
  • 源代码管理——Git
    • 存储库 URL = $GIT_REPOSITORY_URL
    • 要构建的分支,分支说明符 = */master
  • 额外的行为
    • 查看特定的本地分支机构
      • 分支名称 = master
  • 构建——调用 Gradle 脚本
    • 使用 Gradle 包装器
    • 从根构建脚本目录
    • 开关 = -Prelease.useAutomaticVersion=true -PreleaseVersion=$RELEASE_VERSION -PnewVersion=$NEW_VERSION
    • 任务=发布
  • 触发器/调用建立在另一个项目上(需要参数化触发器插件)
    • 要构建的项目 = 将版本发布到 Artifactory
    • 预定义参数
      • GIT_RELEASE_TAG=v$RELEASE_VERSION
      • GIT_REPOSITORY_URL=$GIT_REPOSITORY_URL

最终发布版本

现在我们终于准备好为我们的项目创建一个构建版本,它将创建一个版本。它只会调用之前创建的通用构建。最后一次,创建新的自由式 Jenkins 项目,然后:

  • 项目名称 = 示例发布
  • 此构建已参数化
    • 字符串参数
      • 名称 = RELEASE_VERSION
    • 字符串参数
      • 名称 = NEW_VERSION
  • 准备运行环境
    • 保留 Jenkins 环境变量
    • 保留 Jenkins 构建变量
    • 属性内容
      • GIT_REPOSITORY_URL=git@gitlab.local:com.buransky/release-example.git
  • 源代码管理——Git
    • 使用另一个项目的 SCM
      • 模板项目 = 发布 Gradle 项目
  • 搭建环境
    • 在构建开始之前删除工作区
  • 建造
    • 使用来自另一个项目的构建器
      • 模板项目 = 发布 Gradle 项目

让我们尝试发布我们的示例项目。如果您按照我的步骤操作,那么该项目目前应该是 1.0.1-SNAPSHOT 版本。将发布版本 1.0.1 并将当前项目版本推进到下一个开发版本,即 1.0.2-SNAPSHOT。所以只需运行示例发布构建并设置:

  • RELEASE_VERSION = 1.0.1
  • NEW_VERSION = 1.0.2-快照

使用的工具

结论

我敢肯定本指南中一定有一些错误,也许我也忘了提到一个关键步骤。如果您遇到任何问题,请告诉我,我会尽力解决。它在我的机器上工作,所以必须有一种方法可以让它在你的机器上工作。