软件包仓库中的 Maven 软件包
- Tier: 基础版,专业版,旗舰版
- Offering: JihuLab.com,私有化部署
发布 Maven 产物到项目的软件包仓库。然后,随时安装这些软件包以便将它们作为依赖使用。
有关 Maven 软件包管理器客户端使用的特定 API 端点的文档,请参阅 Maven API 文档。
支持的客户端:
发布到极狐GitLab软件包仓库
身份验证到软件包仓库
您需要一个令牌来发布软件包。根据您的目标,有不同的令牌可用。有关更多信息,请查看 令牌的指南。
创建一个令牌并保存以便在流程中使用。
不要使用这里未记录的身份验证方法。未记录的身份验证方法可能会在将来被删除。
编辑客户端配置
更新配置以使用 HTTP 验证到 Maven 存储库。
自定义 HTTP 头
您必须将身份验证详细信息添加到客户端的配置文件中。
| 令牌类型 | 名称必须是 | 令牌 |
|---|---|---|
| 个人访问令牌 | Private-Token | 直接粘贴令牌,或定义环境变量来保存令牌 |
| 部署令牌 | Deploy-Token | 直接粘贴令牌,或定义环境变量来保存令牌 |
| CI 作业令牌 | Job-Token | ${CI_JOB_TOKEN} |
将如下内容添加到您的 settings.xml 文件中。
xml1<settings> 2 <servers> 3 <server> 4 <id>gitlab-maven</id> 5 <configuration> 6 <httpHeaders> 7 <property> 8 <name>REPLACE_WITH_NAME</name> 9 <value>REPLACE_WITH_TOKEN</value> 10 </property> 11 </httpHeaders> 12 </configuration> 13 </server> 14 </servers> 15</settings>
基本 HTTP 身份验证
您还可以使用基本 HTTP 身份验证来验证到 Maven 软件包仓库。
| 令牌类型 | 名称必须是 | 令牌 |
|---|---|---|
| 个人访问令牌 | 用户的用户名 | 直接粘贴令牌,或定义环境变量来保存令牌 |
| 部署令牌 | 部署令牌的用户名 | 直接粘贴令牌,或定义环境变量来保存令牌 |
| CI 作业令牌 | gitlab-ci-token | ${CI_JOB_TOKEN |
将如下内容添加到 settings.xml 文件中。
xml1<settings> 2 <servers> 3 <server> 4 <id>gitlab-maven</id> 5 <username>REPLACE_WITH_NAME</username> 6 <password>REPLACE_WITH_TOKEN</password> 7 <configuration> 8 <authenticationInfo> 9 <userName>REPLACE_WITH_NAME</userName> 10 <password>REPLACE_WITH_TOKEN</password> 11 </authenticationInfo> 12 </configuration> 13 </server> 14 </servers> 15</settings>
命名约定
您可以使用三个端点之一安装 Maven 软件包。您必须将软件包发布到项目,但您选择的端点决定了您在 pom.xml 文件中添加的用于发布的设置。
这三个端点是:
- 项目级:当您有一些 Maven 软件包且它们不在同一个极狐GitLab群组中时使用。
- 群组级:当您想要安装来自同一个极狐GitLab群组中许多不同项目的软件包时使用。极狐GitLab不保证群组内的软件包名称的唯一性。您可以有两个项目具有相同的软件包名称和软件包版本。因此,极狐GitLab提供最新的软件包。
- 实例级:当您有许多软件包在不同的极狐GitLab群组或它们自己的命名空间中时使用。
对于实例级端点,请确保相关部分在您的 Maven 中 pom.xml 看起来像这样:
xml<groupId>group-slug.subgroup-slug</groupId> <artifactId>project-slug</artifactId>
只有与项目路径相同的软件包 才能通过实例级端点访问。
| Project | Package | Instance-level endpoint available |
|---|---|---|
| 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
| Endpoint | Endpoint URL for pom.xml | Additional information |
|---|---|---|
| Project | https://gitlab.example.com/api/v4/projects/<project_id>/packages/maven | Replace gitlab.example.com with your domain name. Replace <project_id> with your project ID, found on your project overview page. |
| Group | https://gitlab.example.com/api/v4/groups/<group_id>/-/packages/maven | Replace gitlab.example.com with your domain name. Replace <group_id> with your group ID, found on your group's homepage. |
| Instance | https://gitlab.example.com/api/v4/packages/maven | Replace gitlab.example.com with your domain name. |
编辑发布的配置文件
您必须将发布详细信息添加到客户端的配置文件中。
No matter which endpoint you choose, you must have:
- A project-specific URL in the distributionManagement section.
- A repository and distributionManagement section.
The relevant repository section of your pom.xml in Maven should look like this:
xml1<repositories> 2 <repository> 3 <id>gitlab-maven</id> 4 <url><your_endpoint_url></url> 5 </repository> 6</repositories> 7<distributionManagement> 8 <repository> 9 <id>gitlab-maven</id> 10 <url>https://gitlab.example.com/api/v4/projects/<project_id>/packages/maven</url> 11 </repository> 12 <snapshotRepository> 13 <id>gitlab-maven</id> 14 <url>https://gitlab.example.com/api/v4/projects/<project_id>/packages/maven</url> 15 </snapshotRepository> 16</distributionManagement>
- The id is what you defined in settings.xml.
- The <your_endpoint_url> depends on which endpoint you choose.
- Replace gitlab.example.com with your domain name.
发布软件包
在您设置好身份验证 并选择发布端点后, 将 Maven 软件包发布到您的项目。
使用 Maven 发布软件包:
安装软件包
要从极狐GitLab软件包仓库中安装软件包,您必须配置 远程并进行身份验证。完成后,您可以从项目、群组或命名空间中安装软件包。
如果多个软件包具有相同的名称和版本,则在安装软件包时,检索最近发布的软件包。
如果没有足够的权限读取最近发布的软件包,则返回 403 Forbidden。
要通过使用 mvn install 安装软件包:
-
手动将依赖添加到项目的 pom.xml 文件中。要添加之前创建的示例,XML 内容如下:
xml<dependency> <groupId>com.mycompany.mydepartment</groupId> <artifactId>my-project</artifactId> <version>1.0-SNAPSHOT</version> </dependency> -
在项目中运行以下命令:
shellmvn install
消息应显示软件包正在从软件包仓库下载:
shellDownloading 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 软件包的代理下载
History
- 引入于极狐GitLab 17.8。
极狐GitLab Maven 软件包仓库使用远程包含校验和。当您下载文件时,仓库代理文件并在单个请求中将文件及其相关校验和发送给 Maven 客户端。
使用最新的 Maven 客户端使用远程包含校验和:
- 减少客户端到极狐GitLab Maven 软件包仓库的网络请求数量。
- 减少极狐GitLab实例的负载。
- 改善客户端命令执行时间。
由于技术限制,当您使用对象存储时,Maven 软件包仓库会忽略对象存储配置中的 代理下载 设置。相反,Maven 软件包仓库下载始终启用代理下载。
Maven 软件包的 CI/CD 集成
您可以使用 CI/CD 自动构建、测试和发布 Maven 软件包。本节中的示例涵盖以下场景:
- 多模块项目
- 版本发布
- 条件发布
- 与代码质量和安全扫描集成
您可以根据项目需要调整和组合这些示例。
请记得根据项目要求调整 Maven 版本、Java 版本以及其他细节。此外,请确保您已正确配置发布到极狐GitLab软件包仓库所需的凭证和设置。
基本 Maven 软件包构建和发布
此示例配置了构建和发布 Maven 软件包的流水线:
yaml1default: 2 image: maven:3.8.5-openjdk-17 3 cache: 4 paths: 5 - .m2/repository/ 6 - target/ 7 8variables: 9 MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode" 10 MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository" 11 12stages: 13 - build 14 - test 15 - publish 16 17build: 18 stage: build 19 script: 20 - mvn $MAVEN_CLI_OPTS compile 21 22test: 23 stage: test 24 script: 25 - mvn $MAVEN_CLI_OPTS test 26 27publish: 28 stage: publish 29 script: 30 - mvn $MAVEN_CLI_OPTS deploy 31 rules: 32 - if: $CI_COMMIT_BRANCH == "main"
具有并行作业的多模块 Maven 项目
对于具有多个模块的大型项目,您可以使用并行作业来加快构建过程:
yaml1default: 2 image: maven:3.8.5-openjdk-17 3 cache: 4 paths: 5 - .m2/repository/ 6 - target/ 7 8variables: 9 MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode" 10 MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository" 11 12stages: 13 - build 14 - test 15 - publish 16 17build: 18 stage: build 19 script: 20 - mvn $MAVEN_CLI_OPTS compile 21 22test: 23 stage: test 24 parallel: 25 matrix: 26 - MODULE: [module1, module2, module3] 27 script: 28 - mvn $MAVEN_CLI_OPTS test -pl $MODULE 29 30publish: 31 stage: publish 32 script: 33 - mvn $MAVEN_CLI_OPTS deploy 34 rules: 35 - if: $CI_COMMIT_BRANCH == "main"
使用标签的版本化发布
此示例在推送标签时创建版本化发布:
yaml1default: 2 image: maven:3.8.5-openjdk-17 3 cache: 4 paths: 5 - .m2/repository/ 6 - target/ 7 8variables: 9 MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode" 10 MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository" 11 12stages: 13 - build 14 - test 15 - publish 16 - release 17 18build: 19 stage: build 20 script: 21 - mvn $MAVEN_CLI_OPTS compile 22 23test: 24 stage: test 25 script: 26 - mvn $MAVEN_CLI_OPTS test 27 28publish: 29 stage: publish 30 script: 31 - mvn $MAVEN_CLI_OPTS deploy 32 rules: 33 - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH 34 35release: 36 stage: release 37 script: 38 - mvn versions:set -DnewVersion=${CI_COMMIT_TAG} 39 - mvn $MAVEN_CLI_OPTS deploy 40 rules: 41 - if: $CI_COMMIT_TAG
基于更改的条件发布
此示例仅在某些文件更改时发布软件包:
yaml1default: 2 image: maven:3.8.5-openjdk-17 3 cache: 4 paths: 5 - .m2/repository/ 6 - target/ 7 8variables: 9 MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode" 10 MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository" 11 12stages: 13 - build 14 - test 15 - publish 16 17build: 18 stage: build 19 script: 20 - mvn $MAVEN_CLI_OPTS compile 21 22test: 23 stage: test 24 script: 25 - mvn $MAVEN_CLI_OPTS test 26 27publish: 28 stage: publish 29 script: 30 - mvn $MAVEN_CLI_OPTS deploy 31 rules: 32 - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH 33 changes: 34 - pom.xml 35 - src/**/*
与代码质量和安全扫描集成
此示例将代码质量检查和安全扫描集成到流水线中:
yaml1default: 2 image: maven:3.8.5-openjdk-17 3 cache: 4 paths: 5 - .m2/repository/ 6 - target/ 7 8variables: 9 MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode" 10 MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository" 11 12include: 13 - template: Security/SAST.gitlab-ci.yml 14 - template: Code-Quality.gitlab-ci.yml 15 16stages: 17 - build 18 - test 19 - quality 20 - publish 21 22build: 23 stage: build 24 script: 25 - mvn $MAVEN_CLI_OPTS compile 26 27test: 28 stage: test 29 script: 30 - mvn $MAVEN_CLI_OPTS test 31 32code_quality: 33 stage: quality 34 35sast: 36 stage: quality 37 38publish: 39 stage: publish 40 script: 41 - mvn $MAVEN_CLI_OPTS deploy 42 rules: 43 - if: $CI_COMMIT_BRANCH == "main"
有用的提示
发布具有相同名称或版本的软件包
当您发布与现有软件包具有相同名称和版本的软件包时,新软件包文件会添加到现有软件包中。您仍然可以使用 UI 或 API 访问和查看现有软件包的旧资产。
要删除旧版软件包,请考虑使用软件包 API 或 UI。
不允许重复的 Maven 软件包
History
- 在极狐GitLab 15.0 中,所需角色从开发者更改为维护者。
- 在极狐GitLab 17.0 中,所需角色从维护者更改为所有者。
为了防止用户发布重复的 Maven 软件包,您可以使用 GraphQl API 或 UI。
在 UI 中:
- 在左侧边栏中,选择 搜索或转到 并找到您的群组。
- 选择 设置 > 软件包和仓库。
- 在 重复软件包 表的 Maven 行中,关闭 允许重复 切换。
- 可选。在 例外 文本框中,输入一个正则表达式以匹配要允许的软件包名称和版本。
您的更改会自动保存。
请求转发到 Maven Central
History
- 引入于极狐GitLab 15.4,使用名为 maven_central_request_forwarding 的功能标志。默认禁用。
- 在极狐GitLab 17.0 中,需要的角色从维护者更改为所有者。
当软件包仓库中找不到 Maven 软件包时,请求会被转发到 Maven Central。
启用功能标志时,管理员可以在 持续集成设置 中禁用此行为。
Maven 转发仅限于项目级和群组级 端点。实例级端点有命名限制,无法用于不遵循该约定的软件包,并且还会引入供应链样式攻击的安全风险。
mvn 的附加配置
使用 mvn 时,有许多方法可以配置您的 Maven 项目,以便从极狐GitLab请求 Maven Central 中的软件包。Maven 仓库以特定顺序查询。默认情况下,Maven Central 通常通过 Super POM 首先检查,因此需要配置极狐GitLab以便在 maven-central 之前查询。
为了确保所有软件包请求都发送到极狐GitLab而不是 Maven Central,您可以通过在 settings.xml 中添加 <mirror> 部分来覆盖 Maven Central 作为中央仓库:
xml1<settings> 2 <servers> 3 <server> 4 <id>central-proxy</id> 5 <configuration> 6 <httpHeaders> 7 <property> 8 <name>Private-Token</name> 9 <value><personal_access_token></value> 10 </property> 11 </httpHeaders> 12 </configuration> 13 </server> 14 </servers> 15 <mirrors> 16 <mirror> 17 <id>central-proxy</id> 18 <name>GitLab proxy of central repo</name> 19 <url>https://gitlab.example.com/api/v4/projects/<project_id>/packages/maven</url> 20 <mirrorOf>central</mirrorOf> 21 </mirror> 22 </mirrors> 23</settings>
使用极狐GitLab CI/CD 创建 Maven 软件包
在您已将存储库配置为使用 Maven 的软件包存储库后,您可以配置极狐GitLab CI/CD 自动构建新软件包。
您可以在默认分支更新时创建新软件包。
-
创建一个 ci_settings.xml 文件,作为 Maven 的 settings.xml 文件。
-
使用您在 pom.xml 文件中定义的相同 ID 添加 server 部分。例如,使用 gitlab-maven 作为 ID:
xml1<settings xmlns="http://maven.apache.org/SETTINGS/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 2 xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd"> 3 <servers> 4 <server> 5 <id>gitlab-maven</id> 6 <configuration> 7 <httpHeaders> 8 <property> 9 <name>Job-Token</name> 10 <value>${CI_JOB_TOKEN}</value> 11 </property> 12 </httpHeaders> 13 </configuration> 14 </server> 15 </servers> 16</settings> -
确保您的 pom.xml 文件包括以下内容。您可以让 Maven 使用 预定义的 CI/CD 变量,如本示例所示,或者可以硬编码服务器的主机名和项目的 ID。
xml1<repositories> 2 <repository> 3 <id>gitlab-maven</id> 4 <url>${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/maven</url> 5 </repository> 6</repositories> 7<distributionManagement> 8 <repository> 9 <id>gitlab-maven</id> 10 <url>${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/maven</url> 11 </repository> 12 <snapshotRepository> 13 <id>gitlab-maven</id> 14 <url>${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/maven</url> 15 </snapshotRepository> 16</distributionManagement> -
在您的 .gitlab-ci.yml 文件中添加一个 deploy 作业:
yaml1deploy: 2 image: maven:3.6-jdk-11 3 script: 4 - 'mvn deploy -s ci_settings.xml' 5 rules: 6 - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH -
将这些文件推送到您的存储库。
下次 deploy 作业运行时,它会将 ci_settings.xml 复制到用户的主目录。在此示例中:
- 用户是 root,因为作业在 Docker 容器中运行。
- Maven 使用配置的 CI/CD 变量。
版本验证
版本字符串使用以下正则表达式进行验证。
ruby\A(?!.*\.\.)[\w+.-]+\z
您可以在这个正则表达式编辑器上试验正则表达式并尝试您的版本字符串。
对快照和发布部署使用不同的设置
要对快照和发布使用不同的 URL 或设置:
- 在 pom.xml 文件的 <distributionManagement> 部分中定义单独的 <repository> 和 <snapshotRepository> 元素。
有用的 Maven 命令行选项
在使用极狐GitLab CI/CD 执行任务时,您可以使用一些 Maven 命令行选项。
-
文件传输进度可能会使 CI 日志难以阅读。选项 -ntp,--no-transfer-progress 在 3.6.1 中添加。或者,查看 -B,--batch-mode 或较低级别的日志记录更改。
-
指定 pom.xml 文件的位置 (-f,--file):
yamlpackage: script: - 'mvn --no-transfer-progress -f helloworld/pom.xml package' -
指定用户设置的位置 (-s,--settings) 而不是默认位置。还有一个 -gs,--global-settings 选项:
yamlpackage: script: - 'mvn -s settings/ci.xml package'
支持的 CLI 命令
极狐GitLab Maven 仓库支持以下 CLI 命令:
- mvn deploy: 将您的软件包发布到软件包仓库。
- mvn install: 安装在您的 Maven 项目中指定的软件包。
- mvn dependency:get: 安装特定的软件包。
故障排除
在极狐GitLab中使用 Maven 软件包时,您可能会遇到问题。要解决许多常见问题,请尝试以下步骤:
- 验证身份验证 - 确保您的身份验证令牌正确且未过期。
- 检查权限 - 确认您有发布或安装软件包的必要权限。
- 验证 Maven 设置 - 重新检查您的 settings.xml 文件的正确配置。
- 查看极狐GitLab CI/CD 日志 - 对于 CI/CD 问题,仔细检查作业日志中的错误消息。
- 确保正确的端点 URL - 确认您使用的是项目或群组的正确端点 URL。
- 使用 mvn 命令的 -s 选项 - 始终使用 -s 选项运行 Maven 命令,例如 mvn package -s settings.xml。没有此选项,身份验证设置不会应用,Maven 可能无法找到软件包。
清除缓存
为了提高性能,客户端缓存与软件包相关的文件。如果遇到问题,请使用以下命令清除缓存:
shellrm -rf ~/.m2/repository
查看网络跟踪日志
如果您在使用 Maven 仓库时遇到问题,您可能需要查看网络跟踪日志。查看网络跟踪日志提供了更多详细的错误消息,而 Maven 客户端默认情况下不包含这些信息。
例如,尝试使用 PAT 令牌在本地运行 mvn deploy 并使用以下选项:
shellmvn 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
验证您的 Maven 设置
如果您在 CI/CD 中遇到与 settings.xml 文件相关的问题,请尝试添加一个附加脚本任务或作业以验证有效设置。
帮助插件还可以提供系统属性,包括环境变量:
yaml1mvn-settings: 2 script: 3 - 'mvn help:effective-settings' 4 5package: 6 script: 7 - 'mvn help:system' 8 - 'mvn package'
尝试发布软件包时的 "401 Unauthorized" 错误
这通常表示身份验证问题。检查以下内容:
- 您的身份验证令牌有效且未过期。
- 您使用的是正确的令牌类型(个人访问令牌、部署令牌或 CI 作业令牌)。
- 令牌具有必要的权限(api、read_api 或 read_repository)。
- 对于 Maven 项目,使用 -s 选项与 mvn 命令(例如,mvn deploy -s settings.xml)。如果没有这个选项,Maven 将不会应用 settings.xml 文件中的认证设置,从而导致未经授权的错误。
"400 Bad Request" 错误,消息为 "Validation failed: Version is invalid"
极狐GitLab 对版本字符串有特定要求。确保您的版本符合以下格式:
plaintext^(?!.*\.\.)(?!.*\.$)[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." 是无效的。
403 Forbidden 错误,当尝试发布软件包时
403 Forbidden 错误,消息为 Authorization failed 通常表示认证或权限问题。检查以下内容:
- 您正在使用正确的令牌类型(个人访问令牌、部署令牌或 CI/CD 作业令牌)。有关更多信息,请参阅认证到软件包仓库。
- 令牌具有必要的权限。只有具有开发者角色或更高权限的用户才能发布软件包。有关更多信息,请参阅极狐GitLab 权限。
- 您正在发布的软件包没有被推送保护规则保护。有关软件包保护规则的更多信息,请参阅如何保护软件包。
发布时出现 "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 设置文件。
- 验证您的流水线是否有访问所有必要仓库的权限。