Help us learn about your current experience with the documentation. Take the survey.

GitLab 通用包仓库

  • Tier: Free, Premium, Ultimate
  • Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated

使用通用包仓库来发布和管理您项目包注册表中的通用文件,例如发布二进制文件。此功能对于存储和分发不适合特定包格式(如 npm 或 Maven)的工件特别有用。

通用包仓库提供:

  • 存储任何文件类型作为包的位置。
  • 包的版本控制。
  • 与 GitLab CI/CD 的集成。
  • 用于自动化的 API 访问。

向包注册表进行身份验证

要与包注册表交互,您必须使用以下方法之一进行身份验证:

不要使用此处未记录的身份验证方法。未记录的身份验证方法将来可能会被移除。

当您向包注册表进行身份验证时,应遵循以下最佳实践:

  • 要访问与 Developer 角色关联的权限,请使用个人访问令牌。
  • 对自动化管道使用 CI/CD 作业令牌。
  • 对外部系统集成使用部署令牌。
  • 始终通过 HTTPS 发送身份验证信息。

HTTP 基本身份验证

如果您使用的工具不支持标准身份验证方法,可以使用 HTTP 基本身份验证:

curl --user "<username>:<token>" <other options> <GitLab API endpoint>

虽然会被忽略,但您必须提供用户名。令牌是您的个人访问令牌、CI/CD 作业令牌或部署令牌。

发布包

您可以使用 API 发布包。

发布单个文件

要发布单个文件,请使用以下 API 端点:

PUT /projects/:id/packages/generic/:package_name/:package_version/:file_name

将 URL 中的占位符替换为您的特定值:

  • :id:您的项目 ID 或 URL 编码的路径
  • :package_name:您的包名称
  • :package_version:您的包版本
  • :file_name:您要上传的文件名。请参阅下面的有效包文件名格式

例如:

使用 HTTP 标头:

curl --location --header "PRIVATE-TOKEN: <personal_access_token>" \
     --upload-file path/to/file.txt \
     "https://gitlab.example.com/api/v4/projects/24/packages/generic/my_package/1.0.0/file.txt"

使用 HTTP 基本身份验证:

curl --location --user "<username>:<personal_access_token>" \
     --upload-file path/to/file.txt \
     "https://gitlab.example.com/api/v4/projects/24/packages/generic/my_package/1.0.0/file.txt"

使用 HTTP 标头:

curl --location --header  "PRIVATE-TOKEN: <project_access_token>" \
     --upload-file path/to/file.txt \
     "https://gitlab.example.com/api/v4/projects/24/packages/generic/my_package/1.0.0/file.txt"

使用 HTTP 基本身份验证:

curl --location --user "<project_access_token_username>:project_access_token" \
     --upload-file path/to/file.txt \
     "https://gitlab.example.com/api/v4/projects/24/packages/generic/my_package/1.0.0/file.txt"

使用 HTTP 标头:

curl --location --header  "DEPLOY-TOKEN: <deploy_token>" \
     --upload-file path/to/file.txt \
     "https://gitlab.example.com/api/v4/projects/24/packages/generic/my_package/1.0.0/file.txt"

使用 HTTP 基本身份验证:

curl --location --user "<deploy_token_username>:<deploy_token>" \
     --upload-file path/to/file.txt \
     "https://gitlab.example.com/api/v4/projects/24/packages/generic/my_package/1.0.0/file.txt"

<deploy_token_username> 替换为您的部署令牌用户名,将 <deploy_token> 替换为您的实际部署令牌。

这些示例适用于 .gitlab-ci.yml 文件。GitLab CI/CD 自动提供 CI_JOB_TOKEN

使用 HTTP 标头:

publish:
  stage: deploy
  script:
    - |
      curl --location --header "JOB-TOKEN: ${CI_JOB_TOKEN}" \
           --upload-file path/to/file.txt \
           "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/my_package/${CI_COMMIT_TAG}/file.txt"

使用 HTTP 基本身份验证:

publish:
  stage: deploy
  script:
    - |
      curl --location --user "gitlab-ci-token:${CI_JOB_TOKEN}" \
           --upload-file path/to/file.txt \
           "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/my_package/${CI_COMMIT_TAG}/file.txt"

每个请求都会返回一个指示成功或失败的响应。如果您的上传成功,响应状态为 201 Created

发布多个文件

要发布多个文件或整个目录,必须为每个文件进行一次 API 调用。

在向仓库发布多个文件时,您应遵循以下最佳实践:

  • 版本控制:为您的包使用一致的版本控制方案。这可以基于您的项目版本、构建号或日期。
  • 文件组织:考虑如何在包内构建您的文件。您可能需要包含一个清单文件,列出所有包含的文件及其用途。
  • 自动化:尽可能通过 CI/CD 管道自动化发布过程。这确保了一致性并减少了手动错误。
  • 错误处理:在脚本中实现错误检查。例如,检查来自 cURL 的 HTTP 响应代码,确保每个文件都成功上传。
  • 日志记录:记录上传的文件、时间和人员。这对于故障排除和审计至关重要。
  • 压缩:对于大型目录,考虑在上传前将内容压缩为单个文件。这可以简化上传过程并减少 API 调用次数。
  • 校验和:为您的文件生成并存储校验和(MD5、SHA256)。这允许用户验证下载文件的完整性。

例如:

创建一个 Bash 脚本来遍历文件并上传它们:

#!/bin/bash

TOKEN="<access_token>"
PROJECT_ID="24"
PACKAGE_NAME="my_package"
PACKAGE_VERSION="1.0.0"
DIRECTORY_PATH="./files_to_upload"

for file in "$DIRECTORY_PATH"/*; do
    if [ -f "$file" ]; then
        filename=$(basename "$file")
        curl --location --header  "PRIVATE-TOKEN: $TOKEN" \
             --upload-file "$file" \
             "https://gitlab.example.com/api/v4/projects/$PROJECT_ID/packages/generic/$PACKAGE_NAME/$PACKAGE_VERSION/$filename"
        echo "Uploaded: $filename"
    fi
done

要在 CI/CD 管道中进行自动化上传,您可以遍历文件并上传它们:

upload_package:
  stage: publish
  script:
    - |
      for file in ./build/*; do
        if [ -f "$file" ]; then
          filename=$(basename "$file")
          curl --header "JOB-TOKEN: $CI_JOB_TOKEN" \
               --upload-file "$file" \
               "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/my_package/${CI_COMMIT_TAG}/$filename"
          echo "Uploaded: $filename"
        fi
      done

保持目录结构

要保留已发布目录的结构,请在文件名中包含相对路径:

#!/bin/bash

TOKEN="<access_token>"
PROJECT_ID="24"
PACKAGE_NAME="my_package"
PACKAGE_VERSION="1.0.0"
DIRECTORY_PATH="./files_to_upload"

find "$DIRECTORY_PATH" -type f | while read -r file; do
    relative_path=${file#"$DIRECTORY_PATH/"}
    curl --location --header  "PRIVATE-TOKEN: $TOKEN" \
         --upload-file "$file" \
         "https://gitlab.example.com/api/v4/projects/$PROJECT_ID/packages/generic/$PACKAGE_NAME/$PACKAGE_VERSION/$relative_path"
    echo "Uploaded: $relative_path"
done

下载包

您可以使用 API 下载包。

下载单个文件

要下载单个包文件,请使用以下 API 端点:

GET /projects/:id/packages/generic/:package_name/:package_version/:file_name

将 URL 中的占位符替换为您的特定值:

  • :id:您的项目 ID 或 URL 编码的路径
  • :package_name:您的包名称
  • :package_version:您的包版本
  • :file_name:您要上传的文件名

例如:

使用 HTTP 标头:

curl --header "PRIVATE-TOKEN: <access_token>" \
     --location \
     "https://gitlab.example.com/api/v4/projects/1/packages/generic/my_package/0.0.1/file.txt" \
     --output file.txt

使用 HTTP 基本身份验证:

curl --user "<username>:<access_token>" \
     --location \
     "https://gitlab.example.com/api/v4/projects/1/packages/generic/my_package/0.0.1/file.txt" \
     --output file.txt

使用 HTTP 标头:

curl --header "PRIVATE-TOKEN: <project_access_token>" \
     --location \
     "https://gitlab.example.com/api/v4/projects/1/packages/generic/my_package/0.0.1/file.txt" \
     --output file.txt

使用 HTTP 基本身份验证:

curl --user "<project_access_token_username>:<project_access_token>" \
     --location \
     "https://gitlab.example.com/api/v4/projects/1/packages/generic/my_package/0.0.1/file.txt" \
     --output file.txt

使用 HTTP 标头:

curl --header "DEPLOY-TOKEN: <deploy_token>" \
     --location \
     "https://gitlab.example.com/api/v4/projects/1/packages/generic/my_package/0.0.1/file.txt" \
     --output file.txt

使用 HTTP 基本身份验证:

curl --user "<deploy_token_username>:<deploy_token>" \
     --location \
     "https://gitlab.example.com/api/v4/projects/1/packages/generic/my_package/0.0.1/file.txt" \
     --output file.txt

这些示例适用于 .gitlab-ci.yml 文件。GitLab CI/CD 自动提供 CI_JOB_TOKEN

使用 HTTP 标头:

download:
  stage: test
  script:
    - |
      curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" \
           --location \
           --output file.txt \
           "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/my_package/${CI_COMMIT_TAG}/file.txt"

使用 HTTP 基本身份验证:

download:
  stage: test
  script:
    - |
      curl --user "gitlab-ci-token:${CI_JOB_TOKEN}" \
           --location \
           --output file.txt \
           "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/my_package/${CI_COMMIT_TAG}/file.txt"

每个请求都会返回一个指示成功或失败的响应。如果您的上传成功,响应状态为 201 Created

下载多个文件

要下载多个文件或整个目录,必须为每个文件进行一次 API 调用,或使用其他工具。

在从仓库下载多个文件时,您应遵循以下最佳实践:

  • 版本控制:始终指定要下载的包的确切版本以确保一致性。
  • 目录结构:下载时保持包的原始目录结构以保留文件组织。
  • 自动化:将包下载集成到您的 CI/CD 管道或构建脚本中以实现自动化工作流。
  • 错误处理:实施检查以确保所有文件都成功下载。您可以验证 HTTP 状态代码或在下载后检查文件是否存在。
  • 缓存:对于常用的包,考虑实现缓存机制以减少网络使用并提高构建时间。
  • 并行下载:对于包含许多文件的大型包,您可能需要实现并行下载以加快处理速度。
  • 校验和:如果可用,使用包发布者提供的校验和验证下载文件的完整性。
  • 增量下载:对于经常变化的大型包,考虑实现仅下载自上次下载以来已更改文件的机制。

例如:

创建一个 bash 脚本来下载多个文件:

#!/bin/bash

TOKEN="<access_token>"
PROJECT_ID="24"
PACKAGE_NAME="my_package"
PACKAGE_VERSION="1.0.0"
OUTPUT_DIR="./downloaded_files"

# 如果输出目录不存在则创建
mkdir -p "$OUTPUT_DIR"

# 要下载的文件数组
files=("file1.txt" "file2.txt" "subdirectory/file3.txt")

for file in "${files[@]}"; do
    curl --location --header  "PRIVATE-TOKEN: $TOKEN" \
         --output "$OUTPUT_DIR/$file" \
         --create-dirs \
         "https://gitlab.example.com/api/v4/projects/$PROJECT_ID/packages/generic/$PACKAGE_NAME/$PACKAGE_VERSION/$file"
    echo "Downloaded: $file"
done

要在 CI/CD 管道中进行自动化下载:

download_package:
  stage: build
  script:
    - |
      FILES=("file1.txt" "file2.txt" "subdirectory/file3.txt")
      for file in "${FILES[@]}"; do
        curl --location --header  "JOB-TOKEN: $CI_JOB_TOKEN" \
             --output "$file" \
             --create-dirs \
             "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/my_package/${CI_COMMIT_TAG}/$file"
        echo "Downloaded: $file"
      done

下载整个包

要下载包中的所有文件,请使用 GitLab API 列出包内容,然后下载每个文件:

TOKEN="<access_token>"
PROJECT_ID="24"
PACKAGE_ID="1234"
PACKAGE_NAME="my_package"
PACKAGE_VERSION="1.0.0"
OUTPUT_DIR="./downloaded_package"

# 创建输出目录
mkdir -p "$OUTPUT_DIR"

# 获取包中的文件列表
files=$(curl --location --header  "PRIVATE-TOKEN: $TOKEN" \
     "https://gitlab.example.com/api/v4/projects/$PROJECT_ID/packages/$PACKAGE_ID/package_files" \
     | jq -r '.[].file_name')

# 下载每个文件
for file in $files; do
    curl --location --header  "PRIVATE-TOKEN: $TOKEN" \
         --output "$OUTPUT_DIR/$file" \
         --create-dirs \
         "https://gitlab.example.com/api/v4/projects/$PROJECT_ID/packages/generic/$PACKAGE_NAME/$PACKAGE_VERSION/$file"
    echo "Downloaded: $file"
done

禁止发布重复的包名称

默认情况下,当您发布与现有包同名同版本的包时,新文件会添加到现有包中。您可以在设置中禁止发布重复文件名。

先决条件:

  • 您必须拥有 Owner 角色。

要禁止发布重复文件名:

  1. 在左侧边栏,选择搜索或转到并找到您的群组。
  2. 选择设置 > 包和注册表
  3. 重复包表的通用行中,关闭允许重复切换。
  4. 可选。在例外文本框中,输入与允许的包名称和版本匹配的正则表达式。

如果允许重复已打开,您可以在例外文本框中指定不应有重复的包名称和版本。

添加包保留策略

实施包保留策略以管理存储并维护相关版本。

为此:

您还可以使用 API 实现自定义清理脚本。

通用包示例项目

在管道中写入 CI-CD 变量项目包含一个工作示例,您可以使用它在 GitLab CI/CD 中创建、上传和下载通用包。

它还演示了如何管理通用包的语义版本:将其存储在 CI-CD 变量中,检索它,递增它,并在下载测试正常工作后将其写回 CI-CD 变量。

有效包文件名格式

有效的包文件名可以包括:

  • 字母:A-Z, a-z
  • 数字:0-9
  • 特殊字符:. (点), _ (下划线), - (连字符), + (加号), ~ (波浪号), @ (at 符号), / (正斜杠)

包文件名不能:

  • 以波浪号 (~) 或 at 符号 (@) 开头
  • 以波浪号 (~) 或 at 符号 (@) 结尾
  • 包含空格

故障排除

HTTP 403 错误

您可能会收到 HTTP 403 Forbidden 错误。当发生以下情况时会出现此错误:

  • 您没有访问资源的权限。
  • 包注册表未为项目启用。

要解决此问题,请确保包注册表已启用,并且您有权限访问它。

上传大文件到 S3 时出现内部服务器错误

S3 兼容的对象存储将单个 PUT 请求的大小限制为 5 GB。如果在对象存储连接设置中将 aws_signature_version 设置为 2,尝试发布大于 5 GB 限制的包文件可能会导致 HTTP 500: Internal Server Error 响应。

如果您在向 S3 发布大文件时收到 HTTP 500: Internal Server Error 响应,请将 aws_signature_version 设置为 4

# 统一的对象存储设置
gitlab_rails['object_store']['connection'] = {
  # 其他连接设置
  'aws_signature_version' => '4'
}
# 或者
# 存储特定的表单设置
gitlab_rails['packages_object_store_connection'] = {
  # 其他连接设置
  'aws_signature_version' => '4'
}