简体   繁体   English

如何使用 Gitlab CI 构建 Java Maven 项目?

[英]How to use Gitlab CI to build a Java Maven project?

I have been experimenting with no success whatsoever, I am running a Gitlab hosted on Linux, and trying to get my head around the CI functionality.我一直在尝试没有任何成功,我正在运行一个托管在 Linux 上的 Gitlab,并试图了解 CI 功能。

According to the Gitlab documentation you only need to create a .gitlab-ci.yml file, the Gitlab implementation of Travis-CI.根据 Gitlab 文档,您只需要创建一个.gitlab-ci.yml文件,即 Travis-CI 的 Gitlab 实现。 Now from the looks of it you can accomplish a lot with the .gitlab-ci.yml , but a lot of the documentation is referencing Ruby and other languages.现在从外观上看,您可以使用.gitlab-ci.yml完成很多工作,但是很多文档都引用了 Ruby 和其他语言。 Nothing is said about how to build Java Maven projects.没有提及如何构建 Java Maven 项目。

How can I build a simple application in Java?如何在 Java 中构建一个简单的应用程序? Can I use the shared runner, or should I be using a specific runner, in that case what or which runner implementation should I choose: ssh, docker, or shell?我可以使用共享运行器,还是应该使用特定的运行器,在这种情况下,我应该选择什么或哪个运行器实现:ssh、docker 或 shell? Then, what should I put in the .gitlab-ci.yml file at least to build the project with Maven?那么,我至少应该在.gitlab-ci.yml文件中放入什么来使用 Maven 构建项目?

Register a Docker runner and use one of the official Maven Docker images , eg, maven:3-jdk-11 in your .gitlab-ci.yml file: 注册一个 Docker 运行器并使用官方 Maven Docker 映像之一,例如maven:3-jdk-11在您的.gitlab-ci.yml文件中:

image: maven:3-jdk-11

build:
  script: "mvn install -B"

Note the -B flag , which is recommended for non-interactive use.注意-B 标志,建议用于非交互式使用。

As far as I understand, it does not matter whether the runner is shared or specific.据我了解,跑步者是共享的还是特定的都没有关系。

Several questions here.这里有几个问题。

I'll start answering the Java build question, then the Runners one.我将开始回答 Java 构建问题,然后是 Runners 问题。

Java build Java 构建

I'll start from the most basic Java build configuration, and progressively add features.我将从最基本的 Java 构建配置开始,逐步添加功能。

1. basic Java build 1.基本Java构建

This configuration will hopefully run your Maven build (and only the build, explicitly excluding the unit tests):此配置有望运行您的 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. with artifacts, cache and recommended Maven options 2. 带有工件、缓存和推荐的 Maven 选项

This new version:这个新版本:

  • declares Maven build output as GitLab artifacts (for later use in the downstream pipeline),将 Maven 构建输出声明为 GitLab 工件(供以后在下游管道中使用),
  • takes benefit of GitLab's cache to cache local Maven repository (in .m2/repository ),利用GitLab 的缓存来缓存本地 Maven 存储库(在.m2/repository中),
  • also enforces some recommended Maven options to use in CI/CD context.还强制一些推荐的 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. with unit tests 3. 有单元测试

There are two options when integrating you unit tests in your CI/CD pipeline:在 CI/CD 管道中集成单元测试时有两种选择:

  1. run them in the same job as the build在与构建相同的作业中运行它们
  2. run them in a separate job在单独的工作中运行它们

As a matter of pipeline execution speed and green-IT considerations, I definitely prefer option 1, but I admit people could prefer the second one.作为管道执行速度和绿色 IT 考虑的问题,我绝对更喜欢选项 1,但我承认人们可能更喜欢第二种。

Here is the new version of the .gitlab-ci.yml file, also implementing GitLab unit tests integration :这是.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. going further 4. 更进一步

From this step, the build job could still be enhanced further, for instance with code coverage computation and integration , but that requires a little more code.从这一步开始,构建工作仍然可以进一步增强,例如代码覆盖率计算和集成,但这需要更多的代码。

Another way of implementing state-of-the-art pipeline with much less efforts is using GitLab CI/CD template.另一种以更少努力实现最先进管道的方法是使用 GitLab CI/CD 模板。 For example:例如:

to be continuous is an open-source project that provides a collection of ready-to-use, configurable, extensible, composable templates. to be Continuous是一个开源项目,它提供了一系列即用型、可配置、可扩展、可组合的模板。

About Runners关于跑步者

GitLab architecture is very versatile, with the notion of Runners . GitLab 架构非常通用,具有Runners的概念。 Runners are the basic executors pool that make it possible to execute GitLab CI/CD jobs. Runners 是基本的执行器池,可以执行 GitLab CI/CD 作业。

2 things of interest to know about runners关于跑步者需要了解的 2 件事

1. you can specialise your runners 1.你可以让你的跑步者专业化

With GitLab, you can register several kind of runners, made for special and complementary purpose.使用 GitLab,您可以注册多种跑步者,用于特殊和互补目的。

In order to segregate them, GitLab supports the notion of Tags .为了隔离它们,GitLab 支持标签的概念。 When registering your runners, you shall associate them with functional tag names, that will help developers select the most appropriate one in their .gitlab-ci.yml file.注册跑步者时,应将它们与功能标签名称相关联,这将有助于开发人员在其.gitlab-ci.yml文件中选择最合适的名称。

For example, let's imagine you have 4 runners:例如,假设您有 4 个跑步者:

# # Description描述 Proposed Tags建议的标签
1 1 Linux-based general purpose runners for building code, running tests, ... with transparent access to the internet基于 Linux 的通用运行程序,用于构建代码、运行测试等,可透明访问互联网 linux , general , internet linux , general , internet
you should also allow this one to run untagged jobs (makes it kind of default runner )您还应该允许这个运行未标记的作业(使其成为一种默认运行器)
2 2 Microsoft-based general purpose runners for building your .NET code基于 Microsoft 的通用运行程序,用于构建您的 .NET 代码 windows , general , internet windows , general , internet
3 3 compute-optimized runners, made for - say - training super-secret neural networks with no access to the internet计算优化的跑步者,用于训练无法访问互联网的超级秘密神经网络 linux , compute , ml (for machine learning ) linuxcomputeml (用于机器学习
4 4 runners located behind your DMZ in your on-premises datacenter, used to perform code/infrastructure deployments位于本地数据中心内 DMZ 后面的运行器,用于执行代码/基础架构部署 linux , deploy , datacenter linux , deploy , datacenter

With this setup, a monorepo project with both Java and .NET code may declare the following .gitlab-ci.yml file:通过此设置,具有 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. runners have different scopes 2. 跑步者有不同的范围

Quoting the official documentation :引用官方文档

Runners are available based on who you want to have access:跑步者可根据您想要访问的人提供:

  • Shared runners are available to all groups and projects in a GitLab instance. 共享运行器可用于 GitLab 实例中的所有组和项目。
  • Group runners are available to all projects and subgroups in a group. 运行器可用于组中的所有项目和子组。
  • Specific runners are associated with specific projects. 特定的跑步者与特定的项目相关联。 Typically, specific runners are used for one project at a time.通常,特定的跑步者一次用于一个项目。

I would like to add bit of information here guys.我想在这里添加一些信息。 First let's clear out some confusion regarding shared and specific runner.首先让我们澄清一些关于共享和特定跑步者的困惑。

Shared Runner: As its name sound, shared runners are the build process flow instances which can be used to execute jobs of every single project in your installed gitlab instance having Allowed Shared runners option enabled. Shared Runner:顾名思义,shared runners 是构建流程实例,可用于在已安装的 gitlab 实例中执行每个项目的作业,并启用Allowed Shared runners选项。 To do that of-course you would need administrative rights.当然,要做到这一点,您需要管理权限。 As per current gitlab documentation, only use with administrative rights is able to define shared runner.根据当前的 gitlab 文档,只有使用管理权限才能定义共享运行器。

specific runner This kind of runner executes jobs of only one project.特定的跑步者这种跑步者只执行一个项目的工作。

Also, these are few important points to keep in mind when choosing runner for your projects.此外,在为您的项目选择跑步者时,这些是需要牢记的几个要点。

  1. Shared Runners are useful for jobs that have similar requirements, between multiple projects . Shared Runners对于在多个项目之间具有相似要求的工作很有用。 Rather than having multiple runners idling for many projects, you can have a single or a small number of runners that handle multiple projects.您可以让一个或少量的跑步者处理多个项目,而不是让多个跑步者闲置在许多项目中。 This makes it easier to maintain and update runners for common set of projects.这使得维护和更新通用项目的运行器变得更加容易。
  2. Specific runners are useful for jobs that have special requirements or for projects with a specific demand .特定的跑步者对于有特殊要求的工作或有特定需求的项目很有用 If a job has certain requirements, you can set up the specific runner with this in mind, while not having to do this for all runners.如果某项工作有一定的要求,您可以考虑到这一点来设置特定的跑步者,而不必对所有跑步者都这样做。 For example, if you want to deploy a certain project, you can setup a specific runner to have the right credentials for this.例如,如果你想部署某个项目,你可以设置一个特定的运行器来获得正确的凭据。

Now to select right executor for project, its very important that we have bird view on all the available executors for gitlab runner.现在要为项目选择正确的执行器,我们对 gitlab runner 的所有可用执行器有鸟瞰图非常重要。 Gitlab has made this job easy for us by providing nice documentation over here explaining what are the different options you will get with different executors. Gitlab 在这里提供了很好的文档,解释了使用不同的执行器可以获得哪些不同的选项,从而使这项工作对我们来说很容易。

If you would like to know more about runners and different executors, I would suggest you start with this article, Gitlab Runner如果您想了解更多关于 runner 和不同 executor 的信息,我建议您从这篇文章开始, Gitlab Runner

I spent a fair amount of time trying to set up our Java projects on Gitlab CI.我花了相当多的时间尝试在 Gitlab CI 上设置我们的 Java 项目。 I got it working with some degree of success.我得到了一定程度的成功。 As mentioned by rolve, the most straight forward solution is to use an image from the official repo: https://hub.docker.com/_/maven正如 rolve 所提到的,最直接的解决方案是使用来自官方 repo 的图像: https ://hub.docker.com/_/maven

However, we have a corporate proxy which was causing my builds to get timeout requests when fetching the project's dependencies.但是,我们有一个公司代理,导致我的构建在获取项目的依赖项时收到超时请求。 I tried many solutions and finally came across this post: https://gitlab.com/gitlab-org/gitlab-ce/issues/15167 .我尝试了很多解决方案,最后看到了这篇文章: https ://gitlab.com/gitlab-org/gitlab-ce/issues/15167。

The post itself is about setting up maven to cache downloaded dependencies in a local repo which can be accessed among builds.这篇文章本身是关于设置 maven 以在本地 repo 中缓存下载的依赖项,该 repo 可以在构建之间访问。 The idea is that you can write a local maven configuration file by in .gitlab-ci.yml to set up your cache directory and your proxy.这个想法是你可以通过在.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/"

Notice the build debug jobs are only to see whether the proxy settings were being correctly injected.请注意,构建调试作业只是为了查看代理设置是否被正确注入。 You can set the proxy environment variables as secrets using Gitlab by going to Project -> Settings -> CI/CD Pipelines -> Secret Variables.您可以使用 Gitlab 将代理环境变量设置为秘密,方法是转到项目 -> 设置 -> CI/CD 管道 -> 秘密变量。

The last deploy_debug job is to see what was generated in your target directory.最后一个deploy_debug作业是查看目标目录中生成的内容。

The documentation describes the YAML syntax used to control builds:该文档描述了用于控制构建的 YAML 语法:

So why don't you try starting with the following?:那么为什么不尝试从以下开始呢?:

job1:
  script: "mvn package"

Presumably this will only work if Maven is already installed, so you'll need a runner that supports this.据推测,这仅在已安装 Maven 的情况下才有效,因此您需要一个支持此功能的运行器。

I have not used GitLab but the documentation suggests you could further customize it to use the official Maven Docker image to perform the builds.我没有使用 GitLab,但文档建议您可以进一步自定义它以使用官方 Maven Docker 映像来执行构建。 Looks very interesting, but I'd agree documentation is missing a Java example.看起来很有趣,但我同意文档缺少 Java 示例。

I use this command but in general the documentation on java/maven builds seems quite rare我使用这个命令,但一般来说,关于 java/maven 构建的文档似乎很少见

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

With the help of How to deploy Maven projects to Artifactory with GitLab CI/CD借助如何使用 GitLab CI/CD 将 Maven 项目部署到 Artifactory

You can compile your java maven project by just adding a .gitlab-ci.yml file to your repository's root directory with the following content:您只需将.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

Just checking if it is allowed or to add steps after mvn build/test command.只需检查是否允许或在 mvn build/test 命令之后添加步骤。 I am checking if there is an option to run script after build irrespective of build status.我正在检查是否有在构建后运行脚本的选项,而不管构建状态如何。

some thing like below.像下面这样的东西。 where I want to run irrespective of mvn test state.无论 mvn 测试状态如何,我都想在哪里运行。 any thoughts?有什么想法吗? I know one way to run it as after-script.我知道一种将其作为后脚本运行的方法。 but trying to avoid that.但试图避免这种情况。

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    

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM