如何在 GitLab 中存储 releases/binaries?

How to store releases/binaries in GitLab?

我正在使用 GitlabJenkins 和 - 可能 - Nexus(我需要一个神器存储)。我想让 GitLab 存储 releases/binaries - 有可能以方便的方式吗?

我不希望拥有可以从中下载版本(和文档)的其他服务,而是希望以某种方式将其与存储库管理器集成,就像在例如中处理版本一样。 GitHub。有什么线索吗?

2020 年 10 月更新:

GitLab 13.5 现在提供:

Attach binary assets to Releases

If you aren’t currently using GitLab for your releases because you can’t attach binaries to releases, your workflow just got a lot simpler.

You now have the ability to attach binaries to a release tag from the gitlab.ci-yml. This extends support of Release Assets to include binaries, rather than just asset links or source code. This makes it even easier for your development teams to adopt GitLab and use it to automate your release process.

See Documentation and Issue.


2015 年 11 月更新:GitLab 8.2 now supports releases.

凭借其 API,您现在可以 create and update a relase associated to a tag
目前,只能将发行说明(降价文本和附件)添加到 git 标签(又名发行版)。

2019 年 5 月更新:GitLab 1.11 引入了一个有趣的“Guest access to Releases”:

It is now possible for guest users of your projects to view releases that you have published on the Releases page.
They will be able to download your published artifacts, but are not allowed to download the source code nor see repository information such as tags and commits.


原始答案 2015 年 3 月

正在进行中,并在 suggestions 4156755 中提出建议:

We’re accepting merge requests for the minimal proposal by Ciro:

  1. For each repository tag under https://github.com/cirosantilli/test/releases/tag/3.0, allow to upload and download a list of files. 2. The upload and download can be done directly from the tag list view. 3. If a tag gets removed, the uploads are destroyed. (we’re not accepting the tag message edit mentioned in recent comments)

对该建议的评论包括:

What makes it more interesting is the next step.
I would really like a way to let public download artifacts from "releases" without being able to access source code (i.e. make sources private for project team only except anything else like wiki, "releases", issue tracker).

However, such additional feature looks more generic and I submitted a separate feature request for that.

Nevertheless, I repeat my point here:
While the simplistic version of "releases" is still nice to have, many people can easily set up external file server and point URLs in release/tag description to this server outside GitLab.
In other words, "releases" may not look attractive now without some future picture of integration.

Gitlab(服务器)本身用于 git 存储库。您不应该将二进制文件存储在 git 中。 Nexus 将是必经之路。您可以在您的存储库描述或自述文件中向 nexus 添加一个 link(就像您也可以指向您的 jenkins 构建一样)。

您可能想查看与 Gitlab 集成的 GitLab 持续集成。这似乎更像是詹金斯。不知道有没有像Nexus一样自带数据存储。

我们正在使用 scp 复制在 GitlabCI 中生成的文件,例如二进制文件或报告。

# capture test exit code
set +e
bash build/ci/test.sh; TESTS_EXIT_CODE=$?
set -e

# copy reports
sshpass -p "$SFTP_PASS" ssh -o StrictHostKeyChecking=no sftp@192.168.1.60 "mkdir -p ${CI_REPORTS_PATH}"
sshpass -p "$SFTP_PASS" scp -r ${CI_APP_VOLUME}/tests/_output/* sftp@192.168.23.17:${CI_REPORTS_PATH}

# return test exit-code
exit ${TESTS_EXIT_CODE}

这个答案与 VonC 的答案基本相同,只是以 step-by-step 方式描述给经验不足的 CI 用户。

那么,假设您有一个非常棒的提交 30728cab,并且您希望将此版本的代码设为新版本...

1) 为您的提交创建一个标签

git tag -a MY_TAG_NAME 30728cab

执行此命令后,系统会要求您填写说明,就像您对代码提交新更改时一样。

2) 将标签推送到您的远程存储库

标签不会随您的提交自动推送到那里!您需要手动将它们推送到您的遥控器。

git push REMOTE_REPO_NAME REMOTE_BRANCH_NAME MY_TAG_NAME

3) 上传文件

现在您可以 a) 将文件上传到 GitLab 存储库,b) 将其上传到其他任何地方并在这两种情况下都保存 link。

警告: Files uploaded to the GitLab repository can't be easily deleted then and you can't see their link later!

虽然由于上述原因我不建议将二进制文件上传到存储库,但您要求这样做,所以方法如下:

curl --request POST --header "Private-Token: YOUR_PRIVATE_TOKEN" --form "file=@/PATH/TO/THE/FILE/file.txt" "https://MY_GITLAB_HOSTING.COM/api/v4/projects/MY_PROJECT_ID/uploads"

可以在 用户设置 -> 访问令牌.

中创建 private token

此外,如果您确实需要删除文件,您可以export the project, remove manually the folder updates from your downloaded archive, delete the former remote repository and create a new one by importing您下载并修改过的存档。

4) 创建一个版本

现在我们终于可以使用 Release.

将它们联系在一起了
curl --request POST --header 'Content-Type: application/json' --header "Private-Token: YOUR_PRIVATE_TOKEN" --data '{"name": "MY_RELEASE_NAME", "tag_name": "MY_TAG_NAME", "description": "Release with the binary LINK_TO_YOUR_BINARY"}' "https://MY_GITLAB_HOSTING.COM/api/v4/projects/MY_PROJECT_ID/releases"

您可以看到,Release 本质上与特定标签相关联,该标签随后与特定提交相关联。然后只需向这些文件提供 links 即可执行与二进制文件的连接。

有趣的是,你的description支持Markdown,但是在这么繁琐的one-liner中写一些更大的*.md文档真的很难。所以我写了一个简短的 Bash 脚本,它允许我们将 Markdown 文件写在一边,然后它读取它并自动发送它:

#!/bin/bash

RELEASE_NAME=""
TAG_NAME=""
PROJECT_ID=""
DESCRIPTION_FILE_PATH=""
PRIVATE_TOKEN=""

if [ "" == "" ]; then
    echo "Missing parameter! Parameters are RELEASE_NAME, TAG_NAME, PROJECT_ID, DESCRIPTION_FILE_PATH and PRIVATE_TOKEN.";
    exit 1;
fi

DESCRIPTION=''

# Load data from file
while read -r line; do
    DESCRIPTION="${DESCRIPTION}${line}\n";
done < "${DESCRIPTION_FILE_PATH}"

curl --request POST\
     --header 'Content-Type: application/json'\
     --header "Private-Token: ${PRIVATE_TOKEN}"\
     --data-binary "{\"name\": \"${RELEASE_NAME}\", \"tag_name\": \"${TAG_NAME}\", \"description\": \"${DESCRIPTION}\"}"\
     "https://MY_GITLAB_HOSTING.com/api/v4/projects/${PROJECT_ID}/releases" 

echo

所以你可以像

一样使用它

./upload_release.sh MY_RELEASE_NAME MY_TAG_NAME MY_PROJECT_ID MY_MARKDOWN_FILE_PATH MY_PRIVATE_TOKEN

现在就是这样!你有你的第一个完整版本!

直到您意识到,您在发布说明的 header 中犯了一个可怕的拼写错误...

5) 删除版本(如果需要)

在这里你很幸运!与上传的二进制文件不同,您也可以使用 REST API 删除您的版本!

curl --request DELETE --header "Private-Token: MY_PRIVATE_TOKEN" "https://MY_GITLAB_HOSTING.com/api/v4/projects/MY_PROJECT_ID/releases/MY_TAG_NAME"

由于连续输入几次仍然很烦人,我制作了另一个 Bash 脚本:

#!/bin/bash

PROJECT_ID=
TAG_NAME=
PRIVATE_TOKEN=

if [ "" == "" ]; then
    echo "Missing parameter! Parameters are PROJECT_ID, TAG_NAME and PRIVATE_TOKEN.";
    exit 1;
fi

curl --request DELETE --header "Private-Token: ${PRIVATE_TOKEN}" "https://MY_GITLAB_HOSTING.com/api/v4/projects/${PROJECT_ID}/releases/${TAG_NAME}"

echo

可以像./delete_release.sh MY_PROJECT_ID MY_TAG_NAME MY_PRIVATE_TOKEN一样使用。

我正在使用我在 python 中编写的 command line tool 作为快捷方式。执行先前答案中描述的 API 方法的某些步骤(上传、发布、删除发布)。

您可以查看source code或者自己使用。

对于更简单的版本,如果有人有兴趣用 python 和 requests.py 做这些;这是非常微不足道的。

待上传

import requests
secret_token = "<your secret token>"
project_id = "<your project id>"
file_path = "your_file.txt"
api_root = "https://gitlab.com/api/v4"

headers = {
    'PRIVATE-TOKEN': secret_token,
}

uri = '{}/projects/{}/uploads'.format(api_root, project_id)

files = {
    'file': open(file_path, 'rb')
}


r_upload = requests.post(uri, headers=headers, files=files)
if(r_upload.status_code != 201 and r_upload.status_code != 200):
    raise ValueError(f"Upload API responded with unvalid status {r_upload.status_code}")  # noqa: E501

upload = r_upload.json()

上传 returns 一个 json link 和 link 格式的 markdown。我发现 markdown 格式 link 对于 发布描述 非常有用。由于您必须自己将 link 添加到描述中。

用于创建版本

import requests
secret_token = "<your secret token>"
project_id = "<your project id>"
api_root = "https://gitlab.com/api/v4"

desc = """
Your release description. **You can use markdown !**
Don't forget to add download link here.
"""

headers = {
    'PRIVATE-TOKEN': secret_token,
}

data = {
    "description": desc
}

r_new_release = requests.post(uri, data=data, headers=headers)
if(r_new_release.status_code != 201 and r_new_release.status_code != 200):
    raise ValueError(f"Releases API responded with invalid status {r_new_release.status_code}")

new_release = r_new_release.json()

JSON 响应是 release.

其他步骤基本按照API guidelines进行调整即可。他们都很相似。