使用Github API v3,有没有一种方法可以获取给定仓库的最新标签?

37

我对Github API相对较新,我很难获取给定存储库的最新标签。

Q:我为什么需要这个?

A:作为QA,我负责测试和发布到LIVE,我们的团队拥有大约40个工件(在github中的存储库)。我想构建一个工具,列出在最新标签之后有提交的项目,以便我可以更有效地管理发布。

回到重点。

根据Github API,获取给定存储库的所有标签是

GET /repos/:owner/:repo/tags

但这给出了仓库拥有的所有标签的完整列表。

有没有一种简单的方法可以在不遍历上述API调用中所有可用标记的情况下找到最新的标记?

如果我必须迭代每个标记以找到最新的标记(基于每个标记的时间戳),那显然不是有效的方式,因为随着时间的推移,标记数量将增加,并且由于我想至少为10个以上的仓库重复相同的过程。

非常感谢您的帮助。

提前致谢。


1
你不需要使用GitHub API来完成这个任务;请参考https://dev59.com/p2855IYBdhLWcg3wjlCL。但要注意,只有*带注释的*标签与时间戳相关联。对于简单(即非带注释的)标签,您的问题仍然存在歧义。 - jub0bs
相关:https://dev59.com/l2Mk5IYBdhLWcg3wxAhM - Jesse Nickles
6个回答

21

GitHub没有API可以检索最新的标签,就像它有用于检索最新版本的那样。这可能是因为标签可以是任意字符串,而不一定是semver,但这并不是一个借口,因为标签有时间戳,并且GitHub在通过其Tags API返回它们时按词典顺序对它们进行排序。

无论如何,要获取最新的标签,您需要调用该API,然后根据semver规则对标签进行排序。由于这些规则并不简单(请参见该链接的第11点),因此最好使用semver库为浏览器移植)。

const gitHubPath = 'dandv/local-iso-dt';  // example repo
const url = 'https://api.github.com/repos/' + gitHubPath + '/tags';

$.get(url).done(data => {
  const versions = data.sort((v1, v2) => semver.compare(v2.name, v1.name));
  $('#result').html(versions[0].name);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://rawgit.com/hippich/bower-semver/master/semver.min.js"></script>
<p>Latest tag: <span id="result"></span></p>


1
这种方法解决了不需要本地安装 git 的问题。而这里的技巧似乎是在 github 标签页上进行一些网络爬虫操作。对于网络爬虫,这些标签的 CSS 选择器只需使用 .commit-title a 即可。 - Liang Zhang
GitHub确实有一个GraphQL API...请查看@bertrand-martel的答案。 - rü-

21

15

您可以在 https://api.github.com/repos/$org/$repo/releases/latest 获取最新版本。

如果您只想获取标签名称,可以尝试类似以下的方法:

curl https://api.github.com/repos/$org/$repo/releases/latest -s | jq .name -r

3
如果代码仓库使用标签进行版本控制,但不使用GitHub系统创建发布,则此方法无效。一个真实的例子是Drupal项目在GitHub上进行开发,但通过drupal.org发布。 - Alexander Varwijk
你是指AlexanderVarwijk的意思吗?我不知道怎么在Github上禁用发布功能,你有例子吗? - Mathieu
2
据我所知,您也无法禁用它们。但是,非常有可能在GitHub上使用git标签而不实际创建GitHub发布。 - Alexander Varwijk
怎么做?你有例子吗? - Mathieu
1
例如:https://github.com/angular/angular.js/releases - API 不会返回此存储库的真实版本,只有标签。 - Jurosh
显示剩余3条评论

8
你可以考虑使用一个简单的脚本作为GitHub API的替代方案,这个脚本在 "Is there a simple way to “git describe” a remote repository?" (source, by svnpenn) 中提到。
#!/usr/bin/awk -f
BEGIN {
  if (ARGC != 2) {
    print "git-describe-remote.awk https://github.com/stedolan/jq"
    exit
  }
  FS = "[ /^]+"
  while ("git ls-remote " ARGV[1] "| sort -Vk2" | getline) {
    if (!sha)
      sha = substr($0, 1, 7)
    tag = $3
  }
  while ("curl -s " ARGV[1] "/releases/tag/" tag | getline)
    if ($3 ~ "commits")
      com = $2
  printf com ? "%s-%s-g%s\n" : "%s\n", tag, com, sha
}

这样可以提取标签(以及更多内容),而无需克隆存储库。

注意:如下面评论所述,由Joels Elf指出,请确保/usr/bin/awk指向gawk而不是mawk


1
谢谢提供脚本。我仍然很想知道是否有一种使用GITHUB API实现相同功能的方法(因为我计划构建一个Web工具 :),它可以从不同所有者那里获取存储库列表)。 - Varun Kumar Rao Ponugoti
这个脚本和源脚本在我的Mac和Ubuntu 14.04上都无法工作。在Ubuntu上,我得到了/bin/sh: 1: Syntax error: "|" unexpected的错误。 - Joels Elf
1
@JoelsElf 请尝试使用此脚本的更近期版本,网址为 https://github.com/svnpenn/a/blob/d3a1b0bf8b54f949f813687e68e153f208e2a106/git/git-describe-remote.awk - VonC
1
谢谢回复!新脚本仍然出现了相同的错误,所以我检查了 awk 的版本并发现我正在使用 mawk。当我安装并使用 gawk 时,它就像魔术般地工作了! - Joels Elf
@JoelsElf 发现得好!我已经将您的评论包含在答案中以增加可见性。 - VonC
显示剩余2条评论

6
使用 GraphQL API v4,您可以按字母顺序或提交日期获取最后一个标签。例如,按提交日期排序(例如指向最新提交的标签):

{
  repository(owner: "bertrandmartel", name: "caipy-dashboard") {
    refs(refPrefix: "refs/tags/", first: 1, orderBy: {field: TAG_COMMIT_DATE, direction: DESC}) {
      edges {
        node {
          name
          target {
            oid
            ... on Tag {
              message
              commitUrl
              tagger {
                name
                email
                date
              }
            }
          }
        }
      }
    }
  }
}

在资源管理器中测试它

请注意,如果标签是轻量级标签,则不会有taxgermessage字段。您还可以使用field: ALPHABETICAL以获取字母顺序中的最后一个标签。
如果您想获取最后创建的标签(这可能与指向最近提交的标签或按字母顺序排列的最后一个标签不同),则仅对注释标签可行,因为它们的创建日期已存储并可在tagger字段中获得。
要获取最后创建的标签,您需要获取所有标签并过滤响应中data.repository.refs.edges.node.target.tagger.date字段中最新的日期。可以通过以下请求获取响应:
{
  repository(owner: "google", name: "gson") {
    refs(refPrefix: "refs/tags/", first: 100, orderBy: {field: TAG_COMMIT_DATE, direction: DESC}) {
      edges {
        node {
          name
          target {
            oid
            ... on Tag {
              commitUrl
              tagger {
                date
              }
            }
          }
        }
      }
    }
  }
}

在浏览器中测试它


-1

我建议使用 awkbash 简单实现:

curl https://api.github.com/repos/{organization}/{repository_name}/releases/latest | grep -i "tag_name" | awk -F '"' '{print $4}'

  • curl 获取最新发布信息
  • grep 查找字段 "tag_name": "1.1.1"
  • awk"tag_name": "1.1.1" 解析为 1.1.1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接