在GitHub action中获取当前分支和提交哈希值

101

我希望使用GitHub action构建Docker镜像,从TeamCity迁移而来。

在构建脚本中,我想要使用分支和提交的组合来标记镜像,例如master.ad959de。在本地测试时,我可以通过以下方式获取这些信息:

git_branch=`git symbolic-ref --short HEAD`
git_hash=`git rev-parse --short HEAD`
docker_version=${git_branch}.${git_hash}

这是 GitHub action 相关的部分代码:
name: CI
on: [push]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v1

    - name: Create docker image
      run: ./docker-build.sh  


在 GitHub action 中运行该脚本会导致以下错误:
fatal: ref HEAD is not a symbolic ref

我该如何在GitHub action中生成这样的标签?

通过以下的帮助,我能够创建一个自定义操作 https://github.com/mindhaq/action-docker-tags - Rüdiger Schulz
8个回答

122

来自使用环境变量

Github提供了两个有用的变量,您需要稍微处理一下才能获得所需的值:

GITHUB_SHA:触发工作流程的提交SHA。例如:ffac537e6cbbf934b08745a378932722df287a53

GITHUB_REF:触发工作流程的分支或标记引用。例如:refs/heads/feature-branch-1。如果事件类型不可用于分支或标记,则该变量将不存在。

可以像这样提取简短的值:

git_hash=$(git rev-parse --short "$GITHUB_SHA")
git_branch=${GITHUB_REF#refs/heads/}

18
请注意,如果分支名称包含“/”,则git_branch的值将不正确。例如,“ref/heads/actions/test”会转换为“test”,而“actions/test”是实际的分支名称。 请改用“git_branch=${branch#refs/heads/}”。来源:https://dev59.com/GVMH5IYBdhLWcg3w1TyK#58035262 - Shinebayar G
4
也许自从这个答案发布以来,github添加了更多的环境变量;git_branch现在应该作为GITHUB_REF_NAME环境变量可用。 - ssc
2
请注意,如果操作的触发器是 pull_request,那么 ${{github.sha}} 不是分支上最新的提交。请参阅 https://github.community/t/github-sha-isnt-the-value-expected/17903。 - blackwolf123333

101

另一种方法是使用GitHub 上下文

- name: Create docker image
  run: ./docker-build.sh ${{ github.head_ref }}.${{ github.sha }}
这种方法的好处是你不需要添加一步来设置值。注意它使用的是sha的完整版本(而不是短版本)。

这种方法的好处是您无需添加步骤来设置值。请注意,它使用 sha 的完整版本(而不是简短版本)。


23
${{ github.sha }} 是获取提交 SHA 的正确方式,因此这应该是正确的答案。 - Pietrek
1
@Pietrek 这并不是一个可靠的通用解决方案,因为 github.head_ref 仅在 pull_request 事件中定义 - Abandoned Cart
@AbandonedCart 我实际上正在使用 ${{github.ref}},但我不知道那是否符合您的需求。 - Pietrek
1
@Pietrek 我使用 $(git rev-parse --short HEAD) 方法。 - Abandoned Cart

42

一个方便的方法是在工作流程中获取并保存“当前分支和提交sha”的方式可能是将其保存在一个“变量”中。

  - name: Declare some variables
    shell: bash
    run: |
      echo "sha_short=$(git rev-parse --short "$GITHUB_SHA")" >> "$GITHUB_ENV"
      echo "branch=$(echo ${GITHUB_REF#refs/heads/})" >> "$GITHUB_ENV"
  
  - name: Another step
    run: |
      echo "Branch: ${{ env.branch }}"
      echo "Sha: ${{ env.sha_short }}"

也许你的 docker-build.sh 可以接收分支和 sha 作为参数,或者是完整版本作为参数。
  - name: Create docker image
     run: ./docker-build.sh "${{ env.branch }}.${{ env.sha_short }}"

或者只是

  - name: Create docker image
     run: ./docker-build.sh "${GITHUB_REF#refs/heads/}.${GITHUB_SHA}"

在这个操作上,你可以更清楚地看到它。

1
set-output已被弃用。新的语法在此处描述:https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#environment-files新的方式如下所示:echo "SHORT_SHA=$(git rev-parse --short "$GITHUB_SHA")" >> $GITHUB_ENV。 这将把变量添加到环境中:${{ env.SHORT_SHA }} - Ivan P

9
使用环境变量获取缩短SHA的最简单方法:
- name: Build Docker Image
    run: ./docker-build.sh alpha.${GITHUB_SHA::6}

1
这个 alpha. 语法是什么? - Rüdiger Schulz
@Rüdiger 这是构建脚本的一个参数,很可能是 Docker 镜像的标签。它与操作语法无关,但表达式的求值将导致类似“alpha.ec7ba90”这样的参数传递到构建脚本中。 - MorganP
2
你不应该将6→7改为获取7位短SHA吗? - Ben Mares
2
这个结尾的 ::6 是什么魔法?我从未见过这样的写法,而且 Github Actions 也不喜欢它:工作流无效。意外符号:'GITHUB_SHA::6'。 - Joshua Pinter
仅仅是跟进一下,我认为这实际上是"参数扩展",与Github Actions无关,这更加合理。 - Joshua Pinter

4
您可以在您的sh文件中这样获取它 -
BRANCH_NAME=$(echo $GITHUB_REF | cut -d'/' -f 3)
GITHUB_SHA_SHORT=$(echo $GITHUB_SHA | cut -c1-7)

3

也许像这样

name: CI 
on: push 
jobs:   
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v1

    - name: Get Branch
      id: branch
      run: echo "git_branch=${GITHUB_REF#refs/heads/}" >> $GITHUB_BRANCH

    - name: Check Branch
      run: echo "${{ env.branch }}"

    - name: Get Hash
      id: hash
      run: echo "git_hash=$(git rev-parse --short "$GITHUB_SHA")" >> $GITHUB_HASH

    - name: Check Hash
      run: echo "${{ env.hash }}"

    - name: Create docker image
      run: ./docker-build.sh ${{ env.branch }} ${{ env.hash }}

2

假设这是由拉取请求触发的操作,您应该能够使用${{ github.event.pull_request.head.sha }}访问最新Git提交的SHA。


1
使用https://github.com/tj-actions/branch-names提供的输出也适用于pushpull_request事件。

...
    steps:
      - uses: actions/checkout@v2
      - name: Get branch names
        uses: tj-actions/branch-names@v2.1
        id: branch-names
      
      - name: Current branch name
        if: github.event_name == 'pull_request'
        run: |
          echo "${{ steps.branch-name.outputs.current_branch }}"
        # Outputs: "feature/test" current PR branch.
      
      - name: Current branch name
        if: github.event_name == 'push'
        run: |
          echo "${{ steps.branch-name.outputs.current_branch }}"
        # Outputs: "main" the default branch that triggered the push event.
      
      - name: Get Ref brach name
        run: |
          echo "${{ steps.branch-name.outputs.ref_branch }}"
        #  Outputs: "main" for non PR branches | "1/merge" for a PR branch

      - name: Get Head Ref branch name
        if: github.event_name == 'pull_request'
        run: |
          echo "${{ steps.branch-name.outputs.head_ref_branch }}"
        # Outputs: "feature/test" current PR branch.

      - name: Get Base Ref branch name
        if: github.event_name == 'pull_request'
        run: |
          echo "${{ steps.branch-name.outputs.base_ref_branch }}"
        # Outputs: "main" for main <- PR branch.


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