如何使用 Gitlab CI 构建 Java Maven 项目?
Posted
技术标签:
【中文标题】如何使用 Gitlab CI 构建 Java Maven 项目?【英文标题】:How to use Gitlab CI to build a Java Maven project? 【发布时间】:2016-01-30 13:18:12 【问题描述】:我一直在尝试但没有成功,我正在运行一个托管在 Linux 上的 Gitlab,并试图了解 CI 功能。
根据 Gitlab 文档,您只需要创建一个.gitlab-ci.yml
文件,即 Travis-CI 的 Gitlab 实现。现在从它的外观来看,您可以使用.gitlab-ci.yml
完成很多工作,但是很多文档都引用了 Ruby 和其他语言。没有提及如何构建 Java Maven 项目。
如何在 Java 中构建一个简单的应用程序?我可以使用共享运行器,还是应该使用特定的运行器,在这种情况下,我应该选择什么或哪个运行器实现:ssh、docker 或 shell?那么,我应该在.gitlab-ci.yml
文件中至少放入什么来使用 Maven 构建项目?
【问题讨论】:
【参考方案1】:这里有几个问题。
我将开始回答 Java 构建问题,然后是 Runners 问题。
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
2。带有工件、缓存和推荐的 Maven 选项
这个新版本:
将 Maven 构建输出声明为 GitLab 工件(供以后在下游管道中使用), 利用GitLab's cache 缓存本地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 管道中集成单元测试时有两种选择:
-
在与构建相同的作业中运行它们
在单独的作业中运行它们
出于管道执行速度和绿色 IT 考虑,我绝对更喜欢选项 1,但我承认人们可能更喜欢第二个。
这是.gitlab-ci.yml
文件的新版本,同样实现了GitLab unit tests integration:
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。走得更远
从这一步开始,构建作业仍然可以进一步增强,例如代码覆盖率计算和integration,但这需要更多代码。
另一种以更少工作量实现最先进管道的方法是使用 GitLab CI/CD 模板。例如:
GitLab's Maven template 或to-be-continuous templateto be continuous 是一个开源项目,它提供了一系列即用型、可配置、可扩展、可组合的模板。
关于跑步者
GitLab 架构非常通用,具有Runners 的概念。 Runners 是基本的executors pool,可以执行 GitLab CI/CD 作业。
关于跑步者需要了解的 2 件事
1。你可以让你的跑步者专业化
使用 GitLab,您可以注册多种跑步者,用于特殊和互补目的。
为了隔离它们,GitLab 支持Tags 的概念。注册跑步者时,应将它们与 functional 标签名称相关联,这将有助于开发人员在其.gitlab-ci.yml
文件中选择最合适的名称。
例如,假设您有 4 名跑步者:
# | Description | Proposed Tags |
---|---|---|
1 | Linux-based general purpose runners for building code, running tests, ... with transparent access to the internet |
linux , general , internet you should also allow this one to run untagged jobs (makes it kind of default runner) |
2 | Microsoft-based general purpose runners for building your .NET code |
windows , general , internet
|
3 | compute-optimized runners, made for - say - training super-secret neural networks with no access to the internet |
linux , compute , ml (for machine learning) |
4 | runners located behind your DMZ in your on-premises datacenter, used to perform code/infrastructure deployments |
linux , deploy , datacenter
|
通过此设置,具有 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。跑步者有不同的范围
引用official documentation:
根据您想要访问的人,可以使用跑步者:
Shared runners 可用于 GitLab 实例中的所有组和项目。 Group runners 可用于组中的所有项目和子组。 Specific runners 与特定项目相关联。通常,特定的跑步者一次用于一个项目。
【讨论】:
【参考方案2】:Register a Docker runner 并在您的.gitlab-ci.yml
文件中使用official Maven Docker images 之一,例如maven:3-jdk-11
:
image: maven:3-jdk-11
build:
script: "mvn install -B"
注意-B
flag,建议用于非交互式使用。
据我了解,跑步者是共享的还是特定的并不重要。
【讨论】:
所以当被问到是在注册跑步者时运行shell、ssh还是docker时,我应该选择docker对吗? 谢谢,就像一个魅力!只是一个问题:当我们在.gitlab-ci.yml
文件中指定图像时,gitlab-runner
创建期间指定的图像会被忽略吗?例如我用图像 ubuntu:latest 创建了一个跑步者,并在 yml 文件中使用 maven:3-jdk-7 运行作业
@jeanMarcAssin 关于这方面的文档有点稀疏,但本节:doc.gitlab.com/ce/ci/docker/… 和以下两个建议您在.gitlab-ci.yml
文件中指定的图像将覆盖 i> 运行器配置的图像。
这张图片现在有点老了,由于缺乏对 NPM 下载的 EC 支持,我遇到了问题。在 JDK 11 (maven:3.6-jdk-11) 中使用更新的 docker 映像对我来说效果更好。见***.com/a/63027888/768795【参考方案3】:
在How to deploy Maven projects to Artifactory with GitLab CI/CD的帮助下
您只需将.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
【讨论】:
.m2/repository 位于执行运行器的服务器路径中?【参考方案4】:我花了相当多的时间尝试在 Gitlab CI 上设置我们的 Java 项目。我得到了一定程度的成功。正如 rolve 所说,最直接的解决方案是使用官方 repo 中的图像:https://hub.docker.com/_/maven
但是,我们有一个公司代理,导致我的构建在获取项目的依赖项时收到超时请求。我尝试了很多解决方案,最后看到了这个帖子:https://gitlab.com/gitlab-org/gitlab-ce/issues/15167。
这篇文章本身是关于设置 maven 以将下载的依赖项缓存在本地 repo 中,该 repo 可以在构建之间访问。这个想法是你可以通过在 .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 将代理环境变量设置为机密,方法是转到项目 -> 设置 -> CI/CD 管道 -> 机密变量。
最后一个deploy_debug
工作是查看目标目录中生成的内容。
【讨论】:
【参考方案5】:文档描述了用于控制构建的 YAML 语法:
https://gitlab.com/help/ci/yaml/README.md那么你为什么不尝试从以下开始呢?:
job1:
script: "mvn package"
大概只有在已经安装了 Maven 的情况下这才有效,所以你需要一个支持这个的runner。
我没有使用 GitLab,但 documentation 建议您可以进一步自定义它以使用 official Maven Docker image 执行构建。看起来很有趣,但我同意文档缺少 Java 示例。
【讨论】:
【参考方案6】:我想在这里补充一点信息。首先让我们澄清一些关于共享和特定跑步者的困惑。
共享跑步者: 顾名思义,共享运行器是构建流程实例,可用于在启用了 Allowed Shared runners 选项的已安装 gitlab 实例中执行每个项目的作业。当然,要做到这一点,您需要管理权限。根据当前的 gitlab 文档,只有使用管理权限才能定义共享运行器。
特定的跑步者这种跑步者只执行一个项目的工作。
此外,在为您的项目选择跑步者时,请牢记以下几点。
-
Shared Runners对于在多个项目之间具有相似要求的工作很有用。您可以让一个或少量的跑步者处理多个项目,而不是让多个跑步者闲置在许多项目中。这使得维护和更新常见项目的运行器变得更加容易。
特定跑步者对于具有特殊要求的工作或具有特定需求的项目很有用。如果工作有一定的要求,你可以考虑到这一点来设置特定的跑步者,而不必对所有跑步者都这样做。例如,如果您想部署某个项目,您可以设置一个特定的运行器以获得正确的凭据。
现在要为项目选择正确的执行器,重要的是我们对 gitlab runner 的所有可用执行器有鸟瞰图。 Gitlab 在here 上提供了很好的文档,解释了使用不同的执行器可以获得哪些不同的选项,从而使我们的工作变得轻松。
如果您想了解更多关于 runner 和不同 executor 的信息,我建议您从这篇文章开始, Gitlab Runner
【讨论】:
【参考方案7】:我使用这个命令,但一般来说关于 java/maven 构建的文档似乎很少见
maven-package:
script: "mvn install -B"
【讨论】:
以上是关于如何使用 Gitlab CI 构建 Java Maven 项目?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用GitLab和Rancher构建CI/CD流水线 – Part 2
如何在 .gitlab-ci.yml 中指定通配符工件子目录?
Linux云计算 --中国三大电商大厂都在使用的《 GitLab与Jenkins结合构建持续集成(CI)环境》是如何排列