软件包库中的 Maven 包

在项目的软件包库中发布 Maven 产物。然后,在需要将它们用作依赖项时安装它们。

对于 Maven 软件包管理器客户端使用的特定 API 端点的文档,请查阅 Maven API 文档

支持的客户端:

  • mvn。学习如何构建 Maven 包。
  • gradle。学习如何构建 Gradle 包。
  • sbt

发布到极狐GitLab 软件包库

软件包仓库认证

您需要一个令牌来发布软件包。根据您尝试实现的不同,有不同的令牌可用。有关令牌的指导,请参阅令牌指南

创建令牌并在后续过程中使用它。

不要使用未在文档中描述的认证方法。未在文档中描述的认证方法可能在未来被删除。

编辑客户端配置

更新您的配置并使用 HTTP 对 Maven 仓库进行认证。

自定义 HTTP 标头

您必须为您的客户端配置文件添加认证详细信息。

::Tabs

:::TabTitle mvn

令牌类型 名称必须是 令牌
个人访问令牌 Private-Token 按原样粘贴令牌,或者定义一个环境变量来存储该令牌。
部署令牌 Deploy-Token 按原样粘贴令牌,或者定义一个环境变量来存储该令牌。
CI 作业令牌 Job-Token ${CI_JOB_TOKEN}
note <name> 字段必须命名以匹配您选择的令牌。

将如下内容添加到您的 settings.xml 文件中:

<settings>
  <servers>
    <server>
      <id>gitlab-maven</id>
      <configuration>
        <httpHeaders>
          <property>
            <name>REPLACE_WITH_NAME</name>
            <value>REPLACE_WITH_TOKEN</value>
          </property>
        </httpHeaders>
      </configuration>
    </server>
  </servers>
</settings>

:::TabTitle gradle

令牌类型 名称必须是 令牌
个人访问令牌 Private-Token 按原样粘贴令牌,或者定义一个环境变量来存储该令牌。
部署令牌 Deploy-Token 按原样粘贴令牌,或者定义一个环境变量来存储该令牌。
CI 作业令牌 Job-Token System.getenv("CI_JOB_TOKEN")
note <name> 字段必须命名以匹配您选择的令牌。

您的 GRADLE_USER_HOME 目录 中,创建一个包含以下内容的文件 gradle.properties:

gitLabPrivateToken=REPLACE_WITH_YOUR_TOKEN

添加 repositories 部分到您的 build.gradle 文件:

  • 在 Groovy DSL 中:

    repositories {
        maven {
            url "https://gitlab.example.com/api/v4/groups/<group>/-/packages/maven"
            name "GitLab"
            credentials(HttpHeaderCredentials) {
                name = 'REPLACE_WITH_NAME'
                value = gitLabPrivateToken
            }
            authentication {
                header(HttpHeaderAuthentication)
            }
        }
    }
    
  • 在 Kotlin DSL 中:

    repositories {
        maven {
            url = uri("https://gitlab.example.com/api/v4/groups/<group>/-/packages/maven")
            name = "GitLab"
            credentials(HttpHeaderCredentials::class) {
                name = "REPLACE_WITH_NAME"
                value = findProperty("gitLabPrivateToken") as String?
            }
            authentication {
                create("header", HttpHeaderAuthentication::class)
            }
        }
    }
    

::EndTabs

Basic HTTP 认证

您还可以使用 basic HTTP 认证来和 Maven 软件包仓库进行认证。

::Tabs

:::TabTitle mvn

令牌类型 名称必须是 令牌
个人访问令牌 Private-Token 按原样粘贴令牌,或者定义一个环境变量来存储该令牌。
部署令牌 Deploy-Token 按原样粘贴令牌,或者定义一个环境变量来存储该令牌。
CI 作业令牌 gitlab-ci-token ${CI_JOB_TOKEN}

将如下内容添加到您的 settings.xml 文件中:

<settings>
  <servers>
    <server>
      <id>gitlab-maven</id>
      <username>REPLACE_WITH_NAME</username>
      <password>REPLACE_WITH_TOKEN</password>
      <configuration>
        <authenticationInfo>
          <userName>REPLACE_WITH_NAME</userName>
          <password>REPLACE_WITH_TOKEN</password>
        </authenticationInfo>
      </configuration>
    </server>
  </servers>
</settings>

:::TabTitle gradle

令牌类型 名称必须是 令牌
个人访问令牌 Private-Token 按原样粘贴令牌,或者定义一个环境变量来存储该令牌。
部署令牌 Deploy-Token 按原样粘贴令牌,或者定义一个环境变量来存储该令牌。
CI 作业令牌 gitlab-ci-token System.getenv("CI_JOB_TOKEN")

您的 GRADLE_USER_HOME 目录 中,创建一个包含以下内容的文件 gradle.properties:

gitLabPrivateToken=REPLACE_WITH_YOUR_TOKEN

添加 repositories 部分到您的 build.gradle 文件:

  • 在 Groovy DSL 中:

    repositories {
        maven {
            url "https://gitlab.example.com/api/v4/groups/<group>/-/packages/maven"
            name "GitLab"
            credentials(PasswordCredentials) {
                username = 'REPLACE_WITH_NAME'
                password = gitLabPrivateToken
            }
            authentication {
                basic(BasicAuthentication)
            }
        }
    }
    
  • 在 Kotlin DSL 中:

    repositories {
        maven {
            url = uri("https://gitlab.example.com/api/v4/groups/<group>/-/packages/maven")
            name = "GitLab"
            credentials(BasicAuthentication::class) {
                username = "REPLACE_WITH_NAME"
                password = findProperty("gitLabPrivateToken") as String?
            }
            authentication {
                create("basic", BasicAuthentication::class)
            }
        }
    }
    

:::TabTitle sbt

令牌类型 名称必须是 令牌
个人访问令牌 Private-Token 按原样粘贴令牌,或者定义一个环境变量来存储该令牌。
部署令牌 Deploy-Token 按原样粘贴令牌,或者定义一个环境变量来存储该令牌。
CI 作业令牌 gitlab-ci-token sys.env.get("CI_JOB_TOKEN").get

对于 SBT 的认证是基于 basic HTTP 认证。所以您必须提供名称和密码。

note <name> 字段必须命名以匹配您选择的令牌。

要通过使用 sbt 来从 Maven 极狐GitLab 软件包仓库安装软件包,您必须配置 Maven 解析器。如果您访问私人或内部项目或组,您需要设置凭据。 在配置解析器和认证后,您可以从项目,组或命名空间中安装软件包。

在您的 build.sbt 中,添加如下行:

resolvers += ("gitlab" at "<endpoint url>")

credentials += Credentials("GitLab Packages Registry", "<host>", "<name>", "<token>")

在此示例中:

  • <endpoint url>端点 URL。示例:https://gitlab.example.com/api/v4/projects/<project_id>/packages/maven
  • <host><endpoint url> 中的主机,不包括协议方案或端口。示例:gitlab.example.com
  • <name><token> 详见上表。

::EndTabs

名称约定

您可以使用三种端点中的一种来安装 Maven 软件包。您必须将软件包发布到项目,但是您选择的端点决定您添加到 pom.xml 文件中的设置。

三种端点是:

  • 项目级别:当您有少量 Maven 软件包时使用它,而且他们不在同一个极狐GitLab 群组中。
  • 群组级别:当您想要从相同极狐GitLab 群组的众多不同项目安装软件包时使用它。极狐GitLab 不保证群组中的软件包名称的唯一性。您可以有两个项目具有相同的软件包名称和软件包版本。因此,GitLab 为您提供最新的软件包。
  • 实例级别:当您有许多不同群组的软件包时使用它。

对于实例级别端点,请确保您 Maven pom.xml 中的相关部分如下所示:

  <groupId>group-slug.subgroup-slug</groupId>
  <artifactId>project-slug</artifactId>

仅和项目具有相同路径的软件包 能够通过实例级端点暴露。

项目 软件包 可用的实例级别的端点
foo/bar foo/bar/1.0-SNAPSHOT Yes
gitlab-org/gitlab foo/bar/1.0-SNAPSHOT No
gitlab-org/gitlab gitlab-org/gitlab/1.0-SNAPSHOT Yes

端点 URL

端点 pom.xml 的端点 URL 额外信息
项目 https://gitlab.example.com/api/v4/projects/<project_id>/packages/maven gitlab.example.com 替换为您的域名名称。 用您的群组 ID 替换 <group_id>,可以在项目概览页面上找到。
群组 https://gitlab.example.com/api/v4/groups/<group_id>/-/packages/maven gitlab.example.com 替换为您的域名名称。用您的群组 ID 替换 <group_id>,可以在群组主页上找到 ID。
示例 https://gitlab.example.com/api/v4/packages/maven gitlab.example.com 替换为您的域名名称。

编辑发布用的配置文件

您必须为您的客户端配置文件添加认证详细信息。

::Tabs

:::TabTitle mvn

不管你选择哪个端点,你必须有:

  • distributionManagement 部分中有一个项目指定的 URL。
  • 一个 repositorydistributionManagement 部分。

Maven pom.xml 中相关 repository 部分的内容如下:

<repositories>
  <repository>
    <id>gitlab-maven</id>
    <url><your_endpoint_url></url>
  </repository>
</repositories>
<distributionManagement>
  <repository>
    <id>gitlab-maven</id>
    <url>https://gitlab.example.com/api/v4/projects/<project_id>/packages/maven</url>
  </repository>
  <snapshotRepository>
    <id>gitlab-maven</id>
    <url>https://gitlab.example.com/api/v4/projects/<project_id>/packages/maven</url>
  </snapshotRepository>
</distributionManagement>
  • id 是您在 settings.xml 中定义的 ID。
  • <your_endpoint_url> 依赖于您选择的 端点
  • gitlab.example.com 替换为您的域名。

:::TabTitle gradle

要使用 Gradle 发布软件包:

  1. 将 Gradle 插件 maven-plugin 添加到插件部分:

    • 在 Groovy DSL 中:

      plugins {
          id 'java'
          id 'maven-publish'
      }
      
    • 在 Kotlin DSL 中:

      plugins {
          java
          `maven-publish`
      }
      
  2. 添加 publishing 部分:

    • 在 Groovy DSL 中:

      publishing {
          publications {
              library(MavenPublication) {
                  from components.java
              }
          }
          repositories {
              maven {
                  url "https://gitlab.example.com/api/v4/projects/<PROJECT_ID>/packages/maven"
                  credentials(HttpHeaderCredentials) {
                      name = "REPLACE_WITH_TOKEN_NAME"
                      value = gitLabPrivateToken // the variable resides in $GRADLE_USER_HOME/gradle.properties
                  }
                  authentication {
                      header(HttpHeaderAuthentication)
                  }
              }
          }
      }
      
    • 在 Kotlin DSL 中:

      publishing {
          publications {
              create<MavenPublication>("library") {
                  from(components["java"])
              }
          }
          repositories {
              maven {
                  url = uri("https://gitlab.example.com/api/v4/projects/<PROJECT_ID>/packages/maven")
                  credentials(HttpHeaderCredentials::class) {
                      name = "REPLACE_WITH_TOKEN_NAME"
                      value =
                          findProperty("gitLabPrivateToken") as String? // the variable resides in $GRADLE_USER_HOME/gradle.properties
                  }
                  authentication {
                      create("header", HttpHeaderAuthentication::class)
                  }
              }
          }
      }
      

::EndTabs

发布软件包

caution 使用 DeployAtEnd 选项可以导致上传被拒绝 400 bad request {"message":"Validation failed: Name has already been taken"}

在您设置认证选择发布端点后,发布 Maven 软件包到您的项目。

::Tabs

:::TabTitle mvn

要使用 Maven 发布软件包:

mvn deploy

如果部署成功,构建成功消息应显示为:

...
[INFO] BUILD SUCCESS
...

消息应该显示软件包已成功发布到正确的位置:

Uploading to gitlab-maven: https://example.com/api/v4/projects/PROJECT_ID/packages/maven/com/mycompany/mydepartment/my-project/1.0-SNAPSHOT/my-project-1.0-20200128.120857-1.jar

:::TabTitle gradle

运行发布任务:

gradle publish

前往您项目的 软件包和仓库 页面并查看发布的软件包。

:::TabTitle sbt

在您的 build.sbt 文件中配置 publishTo 设置:

publishTo := Some("gitlab" at "<endpoint url>")

确保正确引用了凭据。查看sbt 文档了解更多信息。

使用 sbt 来发布软件包:

sbt publish

如果部署成功,构建成功消息应显示为:

[success] Total time: 1 s, completed Jan 28, 2020 12:08:57 PM

检查成功消息以确保软件包已成功发布到正确的位置:

[info]  published my-project_2.12 to https://gitlab.example.com/api/v4/projects/PROJECT_ID/packages/maven/com/mycompany/my-project_2.12/0.1.1-SNAPSHOT/my-project_2.12-0.1.1-SNAPSHOT.pom

::EndTabs

安装软件包

要从极狐GitLab 软件包仓库安装软件包,您必须配置远程和认证。当完成这些后,您就可以从项目、群组或命名空间安装软件包了。

如果多个包具有相同的名称和版本,当您安装包时,最近发布的包将被检索。

为了以防没有足够的权限来读取最近发布的包从而导致 403 Forbidden 返回。

::Tabs

:::TabTitle mvn

使用 mvn install 来安装软件包:

  1. 手动添加依赖到您项目的 pom.xml 文件中。要添加早前创建的示例,XML 如下所示:

    <dependency>
      <groupId>com.mycompany.mydepartment</groupId>
      <artifactId>my-project</artifactId>
      <version>1.0-SNAPSHOT</version>
    </dependency>
    
  2. 在您的项目中,运行如下内容:

    mvn install
    

消息应该展示软件包正在从软件包库下载:

Downloading from gitlab-maven: http://gitlab.example.com/api/v4/projects/PROJECT_ID/packages/maven/com/mycompany/mydepartment/my-project/1.0-SNAPSHOT/my-project-1.0-20200128.120857-1.pom

您还可以使用 Maven dependency:get 命令 直接安装软件包。

  1. 在您项目的目录中运行:

    mvn dependency:get -Dartifact=com.nickkipling.app:nick-test-app:1.1-SNAPSHOT -DremoteRepositories=gitlab-maven::::<gitlab endpoint url>  -s <path to settings.xml>
    
    • <gitlab endpoint url> is the URL of the GitLab endpoint.
    • <path to settings.xml> is the path to the settings.xml file that contains the authentication details.
    • <gitlab endpoint url> 是极狐GitLab 的端点 URL
note 命令(gitlab-maven)和 settings.xml 文件中的仓库 ID 必须匹配。

The message should show that the package is downloading from the package registry:

Downloading from gitlab-maven: http://gitlab.example.com/api/v4/projects/PROJECT_ID/packages/maven/com/mycompany/mydepartment/my-project/1.0-SNAPSHOT/my-project-1.0-20200128.120857-1.pom

:::TabTitle gradle

通过使用 gradle 来安装软件包:

  1. 在依赖部分,将依赖添加到 build.gradle 中:

    • 在 Groovy DSL 中:

      dependencies {
          implementation 'com.mycompany.mydepartment:my-project:1.0-SNAPSHOT'
      }
      
    • 在 Kotlin DSL 中:

      dependencies {
          implementation("com.mycompany.mydepartment:my-project:1.0-SNAPSHOT")
      }
      
  2. 在您的项目中,运行如下命令:

    gradle install
    

:::TabTitle sbt

通过使用 sbt 来安装软件包:

  1. 内联依赖 添加到 build.sbt:

    libraryDependencies += "com.mycompany.mydepartment" % "my-project" % "8.4"
    
  2. 在您的项目中,运行如下命令:

    sbt update
    

::EndTabs

Maven 软件包的 CI/CD 集成

您可以使用 CI/CD 来自动化构建、测试和发布 Maven 软件包。此部分中的示例涵盖了诸如下面情况下的场景:

  • 多模块项目
  • 版本化发布
  • 条件发布
  • 代码质量和安全扫描的集成

您可以根据您的特定项目需求适配和组合这些示例。

记得根据项目需求调整 Maven 版本、Java 版本以及其他相关版本。此外,确保您正确配置了发布到极狐GitLab 软件包库所需的凭据和设置。

基本的 Maven 软件包发布和构建

如下的示例配置了一个构建和发布 Maven 软件包的流水线:

image: maven:3.8.5-openjdk-17

variables:
  MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode"
  MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"

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

stages:
  - build
  - test
  - publish

build:
  stage: build
  script:
    - mvn $MAVEN_CLI_OPTS compile

test:
  stage: test
  script:
    - mvn $MAVEN_CLI_OPTS test

publish:
  stage: publish
  script:
    - mvn $MAVEN_CLI_OPTS deploy
  rules:
    - if: $CI_COMMIT_BRANCH == "main"

具有并行作业的多模块 Maven 项目

对于具有多模块的大型项目,您可以使用并行作业来加速构建过程:

image: maven:3.8.5-openjdk-17

variables:
  MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode"
  MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"

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

stages:
  - build
  - test
  - publish

build:
  stage: build
  script:
    - mvn $MAVEN_CLI_OPTS compile

test:
  stage: test
  parallel:
    matrix:
      - MODULE: [module1, module2, module3]
  script:
    - mvn $MAVEN_CLI_OPTS test -pl $MODULE

publish:
  stage: publish
  script:
    - mvn $MAVEN_CLI_OPTS deploy
  rules:
    - if: $CI_COMMIT_BRANCH == "main"

使用标签来版本化发布

下面的示例演示了当标签发布时,创建版本化发布:

image: maven:3.8.5-openjdk-17

variables:
  MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode"
  MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"

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

stages:
  - build
  - test
  - publish
  - release

build:
  stage: build
  script:
    - mvn $MAVEN_CLI_OPTS compile

test:
  stage: test
  script:
    - mvn $MAVEN_CLI_OPTS test

publish:
  stage: publish
  script:
    - mvn $MAVEN_CLI_OPTS deploy
  only:
    - main

release:
  stage: release
  script:
    - mvn versions:set -DnewVersion=${CI_COMMIT_TAG}
    - mvn $MAVEN_CLI_OPTS deploy
  rules:
    - if: $CI_COMMIT_TAG

基于变更进行条件化发布

下面的示例演示了仅当特定文件变更时,发布软件包:

image: maven:3.8.5-openjdk-17

variables:
  MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode"
  MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"

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

stages:
  - build
  - test
  - publish

build:
  stage: build
  script:
    - mvn $MAVEN_CLI_OPTS compile

test:
  stage: test
  script:
    - mvn $MAVEN_CLI_OPTS test

publish:
  stage: publish
  script:
    - mvn $MAVEN_CLI_OPTS deploy
  only:
    - main
  rules:
    - changes:
      - pom.xml
      - src/**/*

集成代码质量和安全扫描

下面的示例演示了将代码质量检查和安全扫描集成到流水线中:

image: maven:3.8.5-openjdk-17

variables:
  MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode"
  MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"

include:
  - template: Security/SAST.gitlab-ci.yml
  - template: Code-Quality.gitlab-ci.yml

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

stages:
  - build
  - test
  - quality
  - publish

build:
  stage: build
  script:
    - mvn $MAVEN_CLI_OPTS compile

test:
  stage: test
  script:
    - mvn $MAVEN_CLI_OPTS test

code_quality:
  stage: quality

sast:
  stage: quality

publish:
  stage: publish
  script:
    - mvn $MAVEN_CLI_OPTS deploy
  rules:
    - if: $CI_COMMIT_BRANCH == "main"

有用的提示

发布具有相同名称和版本的软件包

当您发布和既有软件包具有相同名称和版本的软件包,新的软件包文件会被添加到既有软件包。您还可以使用 UI 或 API 来访问并查看既有软件包的旧文件。

要删除旧软件包版本,请考虑使用软件包 API 或 UI。

不允许重复的 Maven 软件包

  • 在极狐GitLab 15.0 中,所需角色从开发者改为维护者。
  • 在极狐GitLab 17.0 中,所需角色从维护者改为所有者。

要阻止用户发布重复的 Maven 软件包,您可以使用 GraphQl API 或 UI。

在 UI 上:

  1. 在左侧导航栏,选择 搜索或前往 并找到您的群组。
  2. 选择 设置 > 软件包与镜像库
  3. Maven 行中的 允许重复软件包,关闭 允许重复 开关。
  4. 可选的。在 例外 文本框中,输入与您要允许的包的名称和/或版本匹配的正则表达式 pattern。

您的更改将自动保存。

请求转发至 Maven Central

  • 在极狐GitLab 17.0 中,所需角色从维护者改为所有者。
默认情况下,此功能在私有化部署上不可用。要启用此功能,管理员可以启用名称为 maven_central_request_forwarding功能标志。此功能在 JihuLab.com 上不可用。

当在软件包仓库中未发现 Maven 软件包,请求会转发到 Maven Central

当启用功能标志时,管理员可以在持续集成设置中禁用此行为。

Maven 转发被限制到项目级别和群组级别端点。实例级端点具有命名限制,阻止它用于不遵循该约定的包,并且还为供应链式攻击引入了过多的安全风险。

针对 mvn 的额外信息

当使用 mvn 时,有很多种方法来配置您的 Maven 项目,以便它从极狐GitLab 请求 Maven Central 中的包。Maven 仓库按特定顺序查询。默认情况下,Maven Center 通常会先通过 Super POM 进行检查,所以需要配置极狐GitLab 在 maven-central 之前被查询。

要确保所有的软件包请求被发送到极狐GitLab 而不是 Maven Central,您可以通过在 settings.xml 中添加 <mirror> 部分来覆盖 Maven Central 作为中央仓库:

<settings>
  <servers>
    <server>
      <id>central-proxy</id>
      <configuration>
        <httpHeaders>
          <property>
            <name>Private-Token</name>
            <value><personal_access_token></value>
          </property>
        </httpHeaders>
      </configuration>
    </server>
  </servers>
  <mirrors>
    <mirror>
      <id>central-proxy</id>
      <name>GitLab proxy of central repo</name>
      <url>https://gitlab.example.com/api/v4/projects/<project_id>/packages/maven</url>
      <mirrorOf>central</mirrorOf>
    </mirror>
  </mirrors>
</settings>

使用极狐GitLab CI/CD 创建 Maven 软件包

当您配置您的仓库使用 Maven 软件包仓库时,您可以配置极狐GitLab CI/CD 来自动化构建新的软件包。

::Tabs

:::TabTitle mvn

每次当默认分支更新时,您都可以创建一个新软件包。

  1. 创建 ci_settings.xml 文件,该文件作为 Maven 的 settings.xml 文件。

  2. 使用您在 pom.xml 文件中定义的相同 ID 来添加 server 部分。例如,使用 gitlab-maven 作为 ID:

    <settings xmlns="http://maven.apache.org/SETTINGS/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd">
      <servers>
        <server>
          <id>gitlab-maven</id>
          <configuration>
            <httpHeaders>
              <property>
                <name>Job-Token</name>
                <value>${CI_JOB_TOKEN}</value>
              </property>
            </httpHeaders>
          </configuration>
        </server>
      </servers>
    </settings>
    
  3. 确保您的 pom.xml 文件包含如下内容。您可以让 Maven 使用预定义的 CI/CD 变量,如此示例所示,或者您可以硬编码您服务器的主机名和项目 ID。

    <repositories>
      <repository>
        <id>gitlab-maven</id>
        <url>${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/maven</url>
      </repository>
    </repositories>
    <distributionManagement>
      <repository>
        <id>gitlab-maven</id>
        <url>${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/maven</url>
      </repository>
      <snapshotRepository>
        <id>gitlab-maven</id>
        <url>${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/maven</url>
      </snapshotRepository>
    </distributionManagement>
    
  4. 在您的 .gitlab-ci.yml 文件中添加 deploy 作业:

    deploy:
      image: maven:3.6-jdk-11
      script:
        - 'mvn deploy -s ci_settings.xml'
      rules:
        - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
    
  5. 将这些文件推送到仓库。

下次 deploy 作业运行时,它将 ci_settings.xml 复制到用户的 home 目录中。在此示例中:

  • 用户是 root,因为作业在 Docker 容器中运行。
  • Maven 使用配置的 CI/CD 变量。

:::TabTitle gradle

每当默认分支更新时,您都可以创建一个软件包。

  1. 在 Gradle 中使用 CI 作业令牌进行认证。

  2. 在您的 .gitlab-ci.yml 文件中添加 deploy 作业:

    deploy:
      image: gradle:6.5-jdk11
      script:
        - 'gradle publish'
      rules:
        - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
    
  3. 提交文件到您的仓库。

当流水线成功时,Maven 软件包就会被创建。

::EndTabs

版本验证

通过使用如下正则表达式来验证版本字符串。

\A(?!.*\.\.)[\w+.-]+\z

为快照和版本部署使用不同的设置

要为快照和发布使用不同的 URL 或设置:

  • pom.xml<distributionManagement> 部分,定义 <repository><snapshotRepository> 元素。

有用的 Maven 命令行选项

当使用极狐GitLab CI/CD 执行任务时,您可以使用一些有用的 Maven 命令行选项。

  • 文件转移进度使得 CI 日志难以阅读。在 3.6.1 中添加了选项 -ntp,--no-transfer-progress。另外,可以查看 -B,--batch-mode 或更低级的日志更改。

  • 指定找到 pom.xml 文件 (-f,--file)的位置:

    package:
      script:
        - 'mvn --no-transfer-progress -f helloworld/pom.xml package'
    
  • 指定找到用户设置(-s,--settings)的位置而不是默认位置。还有一个 -gs,--global-settings 选项:

    package:
      script:
        - 'mvn -s settings/ci.xml package'
    

支持的 CLI 命令

极狐GitLab Maven 仓库支持如下的 CLI 命令:

::Tabs

:::TabTitle mvn

  • mvn deploy:发布软件包到软件包仓库。
  • mvn install:在您的 Maven 项目中安装软件包。
  • mvn dependency:get:安装特定的软件包。

:::TabTitle gradle

  • gradle publish:发布您的软件包到软件包仓库。
  • gradle install:在您的 Gradle 项目中安装软件包。

::EndTabs

故障排查

当使用极狐GitLab Maven 软件包仓库时,您可能会遇到问题。为了解决常见的问题,尝试这些步骤:

  • 验证认证 - 确保您的认证令牌正确且未过期。
  • 检查权限 - 确保您有发布或安装软件包的必要权限。
  • 验证 Maven 设置 - 确保您的 settings.xml 文件配置正确。
  • 查看极狐GitLab CI/CD 日志 - 对于 CI/CD 问题,请仔细检查作业日志中的错误消息。
  • 确保正确的端点 URL - 确保您使用正确的项目或组的端点 URL。
  • 使用 -s 选项进行 mvn 命令 - 永远使用 -s 选项,例如,mvn package -s settings.xml。没有该选项,认证设置可能无法应用,Maven 可能无法找到软件包。

清楚缓存

要改善性能,客户端缓存文件与软件包相关联。如果您遇到问题,请使用这些命令清除缓存:

::Tabs

:::TabTitle mvn

rm -rf ~/.m2/repository

:::TabTitle gradle

rm -rf ~/.gradle/caches # Or replace ~/.gradle with your custom GRADLE_USER_HOME

::EndTabs

查看网络跟踪日志

如果您遇到了 Maven 仓库相关的问题,您可能想要查看网络跟踪日志。

比如,使用个人访问令牌运行 mvn deploy 本地并使用这些选项:

mvn deploy \
-Dorg.slf4j.simpleLogger.log.org.apache.maven.wagon.providers.http.httpclient=trace \
-Dorg.slf4j.simpleLogger.log.org.apache.maven.wagon.providers.http.httpclient.wire=trace
caution 当您设置这些选项时,所有网络请求都被记录,并生成大量输出。

验证您的 Maven 设置

如果您在 CI/CD 中遇到了与 settings.xml 文件相关的问题,尝试添加一个额外的脚本任务或作业来验证有效设置

help 插件还能够提供环境变量,包括环境变量:

mvn-settings:
  script:
    - 'mvn help:effective-settings'

package:
  script:
    - 'mvn help:system'
    - 'mvn package'

当尝试发布软件包时候遇到 “401 Unauthorized” 错误

这通常意味着认证问题。请检查:

  • 您的令牌有效且未过期。
  • 您正在使用正确的令牌类型(个人访问令牌、发布令牌或 CI/CD 作业令牌)
  • 令牌具有必要的权限(apiread_apiread_repository)。
  • 对于 Maven 项目,您应该使用 -s 选项(例如,mvn deploy -s settings.xml)。如果没有该选项,Maven 将不会应用您的 settings.xml 文件中的认证设置,导致未授权错误。

具有 “Validation failed: Version is invalid” 消息的错误 “400 Bad Request”

极狐GitLab 有针对版本字符串的特定要求。确保您的版本符合格式:

^(?!.*\.\.)(?!.*\.$)[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*(\+[0-9A-Za-z-]+)?$

比如,”1.0.0”、”1.0-SNAPSHOT” 和 “1.0.0-alpha” 是有效的,但 “1..0” 或 “1.0.” 不是(符合标准的)。

当发布时提示 “Artifact already exists” 错误

当您尝试发布一个已经存在的软件包时,可能会遇到此错误。要解决此错误:

  • 在发布之前增加您的软件包版本。
  • 如果您使用 SNAPSHOT 版本,确保您在配置中允许覆盖 SNAPSHOT 版本。

未在 UI 中显示已发布的软件包

如果您已经发布了软件包,它可能需要几分钟才能显示。如果它仍然没有显示,则:

  • 确保您有查看软件包的权限。
  • 检查您的 CI/CD 日志或 Maven 输出是否成功发布软件包。
  • 确保您正在查看正确的项目或群组。

Maven 仓库依赖冲突

可以通过如下方法来解决依赖冲突:

  • 在您的 pom.xml 中显式定义版本。
  • 使用 Maven 的依赖管理部分来控制版本。
  • 使用 <exclusions> 标签来排除冲突的传递依赖。

“Unable to find valid certification path to requested target” 错误

这是一个典型的 SSL 证书错误。要解决此问题:

  • 确保您的 JDK 信任极狐GitLab 服务器的 SSL 证书。
  • 如果使用自签名证书,请将其添加到您的 JDK 的信任存储库。
  • 作为最后的选择,您可以在 Maven 设置中禁用 SSL 验证。不推荐在生产环境中使用。

“No plugin found for prefix” 流水线错误

这通常意味着 Maven 无法找到插件。要修复此问题:

  • 确保插件正确定义在您的 pom.xml 中。
  • 检查您的 CI/CD 配置是否使用正确的 Maven 设置文件。
  • 确保您的流水线有访问所有必要的仓库的权限。