45

我想在浏览器中显示当前 git 提交的哈希,以便测试团队(无权运行 heruko 命令)能够在错误报告中包含相应的提交哈希。

首先我尝试了砂砾,但有些东西坏了,它在 Heroku 上不起作用(在本地它很好用,我不知道为什么它在 Heroku 上失败)。

于是我发现Heroku上有两个环境变量:

ENV["COMMIT_HASH"]
ENV["LAST_COMMIT_BY"]

但是它们都不可用(两者都为零)。

我还检查了:

heroku config

但同样,两者都没有设置。

有没有办法检索哈希信息?有没有办法获得更多的 git 信息,例如日期?

4

9 回答 9

96

现在可以尝试 Roberto 在他的回答中提到的 Heroku 功能,而无需联系 Heroku。它被称为Heroku Labs:Dyno 元数据,您可以通过以下方式启用它

heroku labs:enable runtime-dyno-metadata -a <app name>

然后信息作为环境变量可用(在下一次部署时):

~ $ env
HEROKU_APP_ID:                   9daa2797-e49b-4624-932f-ec3f9688e3da
HEROKU_APP_NAME:                 example-app
HEROKU_DYNO_ID:                  1vac4117-c29f-4312-521e-ba4d8638c1ac
HEROKU_RELEASE_VERSION:          v42
HEROKU_SLUG_COMMIT:              2c3a0b24069af49b3de35b8e8c26765c1dba9ff0
HEROKU_SLUG_DESCRIPTION:         Deploy 2c3a0b2
...
于 2015-12-30T19:58:17.673 回答
24

首先,由于 heroku在 slug 编译期间“删除 [s] 未使用的文件,包括 .git 目录”,因此您将无法从应用程序目录内(在 heroku dyno 上)执行一些 git 命令。这包括诸如 之类的东西git rev-parse HEAD,这通常是获取当前哈希值的简单方法。

其次,尝试git ls-remote在 heroku dyno 上检索信息将调用 ssh,您会看到消息说The authenticity of host 'heroku.com (50.19.85.132)' can't be established,因为 heroku 公钥没有安装在 heroku dyno 上。您将无权安装 heroku 公钥。

你仍然有至少两个选择。

  1. 添加提交后挂钩以更新哈希值。

    a) 创建或编辑文件.git/hooks/post-commit
    b) 添加一些 shell 脚本代码,如下所示:

    hash_name=HEAD_HASH
    hash=$(git rev-parse HEAD)
    echo 将 $hash_name 设置为 $hash
    heroku config:set $hash_name=$hash --app yourappname

    (你可以为 git hooks 使用任何你想要的代码;这只是一种选择)

    解释:

    • HEAD_HASH是 heroku 环境变量的名称。随心所欲地称呼它。您将在主应用程序中查找它并将其显示在页面上。
    • git rev-parse HEAD获取当前 HEAD 提交的哈希值。为您想要显示的任何内容自定义此行。


    现在,当您提交 git 时,HEAD_HASH每次都会更新 env var。这可行,但可能有点慢,因为您每次提交时都会等待 heroku 设置环境变量。如果您的网络连接中断等,该变量将不会被更新。有传言说 git 1.8.2 将允许一个“预推送”钩子,您可以在其中放置此代码。

  2. 使用脚本推送您的代码

    git push heroku master您可以编写一个 shell 脚本,其中包含来自选项的行并在末尾1.添加,而不是键入推送代码。git push heroku master然后运行这个 shell 脚本来部署你的代码。这将HEAD_HASH只在推送之前更新(而不是在每次 git 提交之后),并且它很好地将所有内容保存在一个地方。您可能还想将脚本添加到您的.slugignore文件中。

于 2013-02-17T19:09:31.923 回答
20

截至 2015 年 4 月 1 日,Git SHA 现在在构建过程中作为环境变量 SOURCE_VERSION 可用。见:https ://devcenter.heroku.com/changelog-items/630

请注意,它仅在编译步骤期间对正在运行的应用程序不可用。您可以添加一个自定义 buildpack 将其写入到 slug 中持久存在的文件中,然后从您的应用程序中读取该文件。

我正在测试这种方法并在这里有一个实验性的 buildpack:https ://github.com/sreid/heroku-buildpack-sourceversion

于 2015-04-03T04:00:23.037 回答
7

Heroku 容器上有一个 env var,称为SOURCE_VERSION

https://devcenter.heroku.com/articles/buildpack-api

你可以用那个!

于 2019-03-06T19:29:20.480 回答
6

Git >1.8.2 现在支持预推送钩子,这更适合我们的用例。这是我当前的钩子脚本:

#!/bin/sh

remote="$1"
url="$2"

if [[ $url =~ heroku ]] ; then

    if [[ $url =~ staging ]] ; then
        appname=YOUR_APP_NAME_STAGING
    else
        appname=YOUR_APP_NAME
    fi

    hash_name=COMMIT_HASH
    hash=$(git rev-parse HEAD)
    echo Setting $hash_name to $hash
    heroku config:set $hash_name=$hash --app $appname
fi
exit 0
于 2014-03-28T01:02:31.583 回答
6

git ls-remote heroku为我工作。我从这里的一个重复问题的答案中得到了这个。

于 2013-07-12T14:13:48.420 回答
2

culix 和 joshwa 都有很好的答案。如果您将 heroku git 遥控器命名为与相应的 heroku 应用程序相同,您可以拥有一个更短、更健壮的.git/hooks/pre-push钩子:

#!/bin/bash

remote="$1"
url="$2"

if [[ $url =~ heroku ]] ; then
    hash_name=COMMIT_HASH
    hash=$(git rev-parse HEAD)
    echo Setting $hash_name to $hash on app $remote
    heroku config:set $hash_name=$hash --app $remote
fi

exit 0
于 2014-07-15T04:30:04.767 回答
2

如果您使用 CI 并且无权访问 Heroku 客户端,也可以直接使用 Heroku API。

这是我在codeship.com上使用的解决方案(它在环境中提供哈希为$CI_COMMIT_ID

# you can use `heroku auth:token` to generate this
HEROKU_API_KEY="" 

APP_NAME="glorious-flying-birds"

curl -n -X PATCH "https://api.heroku.com/apps/$APP_NAME/config-vars" \
  -H "Authorization: Bearer $HEROKU_API_KEY" \
  -H "Accept: application/vnd.heroku+json; version=3" \
  -H "Content-Type: application/json" \
  -d "{\"GIT_COMMIT_HASH\": \"$CI_COMMIT_ID\"}"
于 2015-03-20T22:34:13.740 回答
2

Heroku 具有支持 dyno 元数据的新功能,如果您通过电子邮件发送支持,您可能会被添加到测试版中。这是 Heroku 自己使用它的地方:

https://github.com/heroku/fix/blob/6c8ab7a/lib/heroku_dyno_metadata.rb

附加功能将 JSON 文件写入到/etc/heroku/dyno- 内容如下所示:

{
   "dyno":{
      "physical_id":"161bfad9-9e83-40b7-b385-78305db2f168",
      "size":1,
      "name":"run.7145"
   },
   "app":{
      "id":null
   },
   "release":{
      "id":50,
      "commit":"2c3a0b24069af49b3de35b8e8c26765c1dba9ff0",
      "description":null
   }
}

..release.commit你所追求的领域也是如此。

于 2015-10-21T12:38:14.377 回答