使用 GitHub API 将发行说明文本上传到 GitHub 有时会失败

Uploading releasenotes text to GitHub using GitHub API fails sometimes

如果标签是刚刚创建的 (https://github.com/tschulte/gradle-semantic-release-plugin/issues/3),我在上传现有标签的发行说明时遇到问题。我的代码首先创建一个带注释的标签并推送它。紧接着,它使用 GitHub API 来设置刚刚创建的版本的主体。这确实经常失败——在提交很少的新存储库上不太常见,如果存储库包含更多提交,则更常见。

我使用以下 bash 脚本来重现此行为

#!/bin/bash

set -e

user=tschulte
repo=github-releasetest

version=""
tag="v$version"

git tag $tag -m "Release of $version"
git push origin "$tag"

curl -i -X POST -H "Accept: application/vnd.github.v3+json" -H "Authorization: token $GH_TOKEN" \
    "https://api.github.com/repos/$user/$repo/releases" \
    -d "{\"tag_name\": \"$tag\", \"body\": \"# Changelog of $version\"}"

我运行循环中的脚本

export GH_TOKEN=...
for v in {61..100}; do ./issue3 $v; done

结果是,并非所有版本都已上传。 GitHub API(HTTP 状态代码 422)返回以下无法上传的内容:

{
    "message":"Validation Failed",
    "errors":[
        {
            "resource":"Release",
            "code":"custom",
            "message":"Published releases must have a valid tag"
        }
    ],
    "documentation_url":"https://developer.github.com/v3/repos/releases/#create-a-release"
}

我知道我可以通过不使用 git taggit push 而是使用 GitHub API 来修复我的代码来同时创建标签而不仅仅是设置发行说明文本。但是发行说明的上传是对现有行为的补充,我不想改变它。

还有什么我可以做的吗?或者这是 API 中的错误?

创建版本的 API 确实支持多个用例:

  • 创建标签并发布(使用当前主控或给定的提交)并设置其正文
  • 使用现有标签创建版本

但是选择使用哪个版本只是标签是否已经存在而已。如果标签刚刚创建,API 可能还不知道。可以肯定的是,在推送标签之后和创建发布之前,使用 API 检查标签是否存在。以下脚本确实有效

#!/bin/bash

set -e

user=tschulte
repo=github-releasetest

version=""
tag="v$version"

git tag $tag -m "Release of $version"
git push origin "$tag"

echo "checking existence of tag $tag using API"
while [ "$(curl -s -w "%{http_code}" -H "Authorization: token $GH_TOKEN" "https://api.github.com/repos/$user/$repo/git/refs/tags/$tag" -o /dev/null)" -ne "200" ]
do
    echo "API does not know tag -- retrying"
done
echo "API knows tag"

if [ "$(curl -s -w "%{http_code}" -X POST -H "Accept: application/vnd.github.v3+json" -H "Authorization: token $GH_TOKEN" \
    "https://api.github.com/repos/$user/$repo/releases" \
    -d "{\"tag_name\": \"$tag\", \"body\": \"# Changelog of $version\"}" -o /dev/null)" == "201" ]
then
    echo "Release uploaded successfully"
else
    echo "Release could not be uploaded"
    exit 1
fi

有趣的是,有时 API 似乎需要一些时间才能知道标签:

Counting objects: 1, done.
Writing objects: 100% (1/1), 171 bytes | 0 bytes/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To git@github.com:tschulte/github-releasetest.git
 * [new tag]         v238 -> v238
checking existence of tag v238 using API
API does not know tag -- retrying
API does not know tag -- retrying
API does not know tag -- retrying
API does not know tag -- retrying
API does not know tag -- retrying
API knows tag
Release uploaded successfully