GitLab 通用包仓库
- Tier: Free, Premium, Ultimate
- Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
使用通用包仓库来发布和管理您项目包注册表中的通用文件,例如发布二进制文件。此功能对于存储和分发不适合特定包格式(如 npm 或 Maven)的工件特别有用。
通用包仓库提供:
- 存储任何文件类型作为包的位置。
- 包的版本控制。
- 与 GitLab CI/CD 的集成。
- 用于自动化的 API 访问。
向包注册表进行身份验证
要与包注册表交互,您必须使用以下方法之一进行身份验证:
- 具有
api范围的个人访问令牌 - 具有
api范围和至少 Developer 角色的项目访问令牌 - CI/CD 作业令牌
- 具有
read_package_registry、write_package_registry或两者范围的部署令牌
不要使用此处未记录的身份验证方法。未记录的身份验证方法将来可能会被移除。
当您向包注册表进行身份验证时,应遵循以下最佳实践:
- 要访问与 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 角色。
要禁止发布重复文件名:
- 在左侧边栏,选择搜索或转到并找到您的群组。
- 选择设置 > 包和注册表。
- 在重复包表的通用行中,关闭允许重复切换。
- 可选。在例外文本框中,输入与允许的包名称和版本匹配的正则表达式。
如果允许重复已打开,您可以在例外文本框中指定不应有重复的包名称和版本。
添加包保留策略
实施包保留策略以管理存储并维护相关版本。
为此:
- 使用内置的 GitLab清理策略。
您还可以使用 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'
}