如何使用 Gitlab CI 构建 JavaMaven 项目?

我一直在尝试无论如何都没有成功,我正在运行一个 Gitlab 托管在 Linux 上,并试图让我的头围绕 CI 功能。

根据 Gitlab 文档,您只需要创建一个 .gitlab-ci.yml文件,即 Travis-CI 的 Gitlab 实现。现在,从外观上看,您可以使用 .gitlab-ci.yml完成很多工作,但是很多文档都引用了 Ruby 和其他语言。没有提到如何构建 JavaMaven 项目。

如何用 Java 构建一个简单的应用程序?我是否可以使用共享运行程序,或者应该使用特定的运行程序,在这种情况下,我应该选择什么或哪种运行程序实现: ssh、 docker 还是 shell?然后,我应该放什么在 .gitlab-ci.yml文件至少建立与 Maven 的项目?

110776 次浏览

文档描述了用于控制构建的 YAML 语法:

那么你为什么不试着从以下几点开始呢:

job1:
script: "mvn package"

据推测,这只有在 Maven 已经安装的情况下才能正常工作,因此您需要一个支持这一点的 跑步者

我还没有使用 GitLab,但是 文件建议您可以进一步定制它,使用 Maven Docker 的官方形象来执行构建。看起来很有趣,但我同意文档缺少一个 Java 示例。

注册一个 Docker runner 并使用 Maven Docker 的官方照片中的一个,例如,在 .gitlab-ci.yml文件中使用 maven:3-jdk-11:

image: maven:3-jdk-11


build:
script: "mvn install -B"

请注意 -B 旗帜,它推荐用于非交互式使用。

据我所知,跑步者是共享的还是特定的并不重要。

我使用这个命令,但是一般来说,关于 java/maven 构建的文档似乎很少

maven-package:
script: "mvn install -B"

我想在这里补充一点信息,伙计们。首先,让我们澄清一些关于共享和特定运行程序的混淆。

共享跑者: 顾名思义,共享运行程序是构建过程流实例,它可以用来执行已安装的 gitlab 实例中启用 允许共享的运行程序选项的每个项目的作业。当然,要做到这一点,你需要行政权。根据当前的 gitlab 文档,只有具有管理权限的用户才能定义共享运行程序。

这种类型的运行程序只执行一个项目的作业。

另外,在为你的项目选择跑步者时,这几点也是需要记住的。

  1. Shared Runners 对于具有 类似的需求,在多个项目之间的作业非常有用。您可以使用单个或少量的运行程序来处理多个项目,而不是让多个运行程序在许多项目中处于空闲状态。这使得维护和更新常见项目集的运行程序变得更加容易。
  2. 特定的跑步者 对于具有 特殊要求或有特殊要求的项目的工作是有用的。如果一项工作有一定的要求,你可以在设置特定的跑步者时考虑到这一点,而不必为所有的跑步者这样做。例如,如果希望部署某个项目,可以设置特定的运行程序,使其具有相应的凭据。

现在要为项目选择合适的执行者,我们必须鸟瞰所有可用的 gitlab 运行程序执行者。Gitlab 在 给你上提供了很好的文档,解释了不同的执行者会提供哪些不同的选项,从而使我们的工作变得容易。

如果你想更多地了解跑步者和不同的执行者,我建议你从这篇文章开始, Gitlab Runner

我花了相当多的时间在 Gitlab CI 上设置我们的 Java 项目。我成功地把它修好了。正如 Rolve 所提到的,最直接的解决方案是使用来自官方回购的图像: https://hub.docker.com/_/maven

但是,我们有一个公司代理,它导致我的构建在获取项目的依赖项时获得超时请求。我尝试了很多解决方案,最后发现了这篇文章: https://gitlab.com/gitlab-org/gitlab-ce/issues/15167

帖子本身是关于建立 maven 来缓存本地回购中下载的依赖关系,这些依赖关系可以在构建中访问。其思想是您可以在 . gitlab-ci. yml中编写一个本地 maven 配置文件来设置您的缓存目录和代理。

before_script:
-echo '<settings
xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
https://maven.apache.org/xsd/settings-1.0.0.xsd">
<localRepository>/cache/.m2</localRepository>
<proxies>
<proxy>
<active>true</active>
<protocol>'$PROXY_PROTOCOL'</protocol>
<host>'$PROXY_HOST'</host>
<port>'$PROXY_PORT'</port>
</proxy>
</proxies>
</settings>' > $HOME/.m2/settings.xml


build_debug1:
stage: build
script: "echo $PROXY_HOST"


build_debug2:
stage: build
script: "cat $HOME/.m2/settings.xml"


build_maven:
stage: build
script: "mvn $MAVEN_CLI_OPTS package"
artifacts:
paths:
- target/*.jar


deploy_debug1:
stage: package
script: "ls target/"

注意,构建调试作业仅用于查看是否正确注入了代理设置。您可以使用 Gitlab 将代理环境变量设置为机密,方法是进入 Project-> Settings-> CI/CD Pipes-> Secret Variables。

最后一个 deploy_debug作业是查看在目标目录中生成了什么。

如何使用 GitLab CI/CD 将 Maven 项目部署到 ArtiFactory的帮助下

您可以通过将一个 .gitlab-ci.yml文件添加到存储库的根目录来编译 java maven 项目,该文件包含以下内容:

image: maven:latest


variables:
MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"


cache:
paths:
- .m2/repository/
- target/


build:
stage: build
script:
- mvn compile

这里有几个问题。

我要开始回答 Java 构建的问题,然后是跑步者的。

Java 编译

我将从最基本的 Java 构建配置开始,逐步添加特性。

1. 基本 Java 构建

这个配置有望运行 Maven 构建(并且只运行构建,显式地排除单元测试) :

stages:
- build


java-build:
# select the most appropriate image for your project
image: maven:3.8-openjdk-11
stage: build
script:
- mvn package -DskipTests=true

使用工件、缓存和推荐的 Maven 选项

新版本:

  • 将 Maven 构建输出声明为 GitLab 工件(供以后在下游管道中使用) ,
  • 利用 GitLab 的缓存缓存本地 Maven 存储库(在 .m2/repository中) ,
  • 还强制执行一些推荐的 Maven 选项,以便在 CI/CD 上下文中使用。
stages:
- build


variables:
# This will suppress any download for dependencies and plugins or upload messages which would clutter the console log.
# `showDateTime` will show the passed time in milliseconds. You need to specify `--batch-mode` to make this work.
MAVEN_OPTS: >-
-Dhttps.protocols=TLSv1.2
-Dmaven.repo.local=.m2/repository
-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN
-Dorg.slf4j.simpleLogger.showDateTime=true
-Djava.awt.headless=true
# As of Maven 3.3.0 instead of this you may define these options in `.mvn/maven.config` so the same config is used
# when running from the command line.
# `installAtEnd` and `deployAtEnd` are only effective with recent version of the corresponding plugins.
MAVEN_CLI_OPTS: >-
--batch-mode
--errors
--fail-at-end
--show-version
-DinstallAtEnd=true
-DdeployAtEnd=true


java-build:
# select the most appropriate image for your project
image: maven:3.8-openjdk-11
stage: build
# Cache downloaded dependencies and plugins between builds.
# The key here separates one cache per branch/tag ($CI_COMMIT_REF_SLUG)
cache:
key: "maven-$CI_COMMIT_REF_SLUG"
paths:
- .m2/repository
script:
- mvn $MAVEN_CLI_OPTS package -DskipTests=true
artifacts:
name: "Maven artifacts from $CI_PROJECT_NAME on $CI_COMMIT_REF_SLUG"
paths:
- "**/target"

3. 使用单元测试

在将单元测试集成到 CI/CD 管道中时,有两种选择:

  1. 在与构建相同的作业中运行它们
  2. 让他们分开工作

关于管道执行速度和绿色 IT 考虑,我当然更喜欢选项1,但我承认人们可能更喜欢第二个。

下面是 .gitlab-ci.yml文件的新版本,也实现了 GitLab 单元测试集成:

stages:
- build


variables:
# This will suppress any download for dependencies and plugins or upload messages which would clutter the console log.
# `showDateTime` will show the passed time in milliseconds. You need to specify `--batch-mode` to make this work.
MAVEN_OPTS: >-
-Dhttps.protocols=TLSv1.2
-Dmaven.repo.local=.m2/repository
-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN
-Dorg.slf4j.simpleLogger.showDateTime=true
-Djava.awt.headless=true
# As of Maven 3.3.0 instead of this you may define these options in `.mvn/maven.config` so the same config is used
# when running from the command line.
# `installAtEnd` and `deployAtEnd` are only effective with recent version of the corresponding plugins.
MAVEN_CLI_OPTS: >-
--batch-mode
--errors
--fail-at-end
--show-version
-DinstallAtEnd=true
-DdeployAtEnd=true


java-build-and-test:
# select the most appropriate image for your project
image: maven:3.8-openjdk-11
stage: build
# Cache downloaded dependencies and plugins between builds.
# The key here separates one cache per branch/tag ($CI_COMMIT_REF_SLUG)
cache:
key: "maven-$CI_COMMIT_REF_SLUG"
paths:
- .m2/repository
script:
# the 'verify' goal is definitely the most appropriate here
- mvn $MAVEN_CLI_OPTS verify
artifacts:
name: "Maven artifacts from $CI_PROJECT_NAME on $CI_COMMIT_REF_SLUG"
paths:
- "**/target"
reports:
# declare the JUnit reports (recursive pattern for multi-module projects)
junit:
- "**/target/*-reports/TEST-*.xml"

4. 更进一步

从这一步开始,构建作业仍然可以得到进一步的增强,例如代码覆盖率计算和 整合,但是这需要更多的代码。

另一种实现最先进的流水线的方法是使用 GitLab CI/CD 模板,这种方法的工作量要小得多:

连续 是一个开放源码项目,它提供了一系列现成的、可配置的、可扩展的、可组合的模板。

关于跑步者

GitLab 体系结构非常灵活,带有 跑步者的概念。 跑步者是基本的 遗嘱执行人池,它使得 GitLab CI/CD 作业的执行成为可能。

关于跑步者的两件有趣的事情

1. 你可以专门训练你的跑步者

使用 GitLab,您可以注册几种跑步者,这些跑步者是为特殊和互补目的而制作的。

为了使它们成为 隔离,GitLab 支持 标签的概念。当注册您的跑步者时,您应该将他们与 功能性的标记名相关联,这将帮助开发人员在他们的 .gitlab-ci.yml文件中选择最合适的一个。

例如,假设你有4个跑步者:

# 描述 建议标签
1 基于 Linux 的通用运行程序,用于构建代码、运行测试... ... 以及对互联网的透明访问 linuxgeneralinternet < br > 您还应该允许这一个运行未标记的作业(使其类似于 默认跑步机)
2 基于 Microsoft 的用于构建.NET 代码的通用运行程序 windowsgeneralinternet
3 计算优化的跑步者,为了训练超级秘密的神经网络而不接入互联网 linuxcomputeml(对于 机器学习)
4 位于内部数据中心 DMZ 后面的运行程序,用于执行代码/基础设施部署 linuxdeploydatacenter

通过这种设置,同时使用 Java 和.NET 代码的 monorepo 项目可以声明以下 .gitlab-ci.yml文件:

stages:
- build
- test
- deploy


# this job declares no tag: will be executed by default runner (#1)
java-build:
image: maven:3.8-openjdk-11
stage: build
script:
- Java build code here


dotnet-build:
image: mcr.microsoft.com/dotnet/sdk:5.0
stage: build
tags:
- windows
- general
script:
- .NET build code here


# this job declares no tag: will be executed by default runner (#1)
java-test:
image: maven:3.8-openjdk-11
stage: test
script:
- Java test code here


dotnet-test:
image: mcr.microsoft.com/dotnet/sdk:5.0
stage: test
tags:
- windows
- general
script:
- .NET test code here


deploy:
stage: deploy
tags:
- deploy
- datacenter
script:
- deployment code here

2. 跑步者有不同的视野

引用 正式文件的话:

跑步者可以根据你想要接触的人选选择:

只是检查它是否被允许,或者在 mvn build/test 命令之后添加步骤。我正在检查是否有一个选项来运行脚本后,不管构建状态。

像下面这样的东西。无论 mvn 测试状态如何,我都要在其中运行。有什么想法吗?我知道一种方法可以把它作为后期脚本运行。但是尽量避免这种情况。

build:
stage: build
script:
- mvn test
- ./extract_data.sh
#-----------Base image that contains required maven and jdk--------#
image: basebuildimage
variables:
MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode"
stages:
- build
#----------Build code-----------#
build:
stage: build
script:
- mvn $MAVEN_CLI_OPTS clean install