我正在尝试使用当前分支名称的一部分作为在 CI 管道中发布 docker 镜像的标签。问题是在我的组织中,有一个命名分支的约定,如
feature/foo
,并且 docker 标签不能包含斜杠。所以我想用“/”符号分割字符串并取最后一部分。
带斜杠的完整分支名称应位于变量
github.ref_name
中。这是我试图评估的表达式:${{ github.ref_name.split('/')[-1] }}
。
我收到此错误:
Unable to interpolate expression 'format('{0}', github.ref_name.split('/')[-1])': Failed to parse: unexpected token "(" while parsing arguments of function call. expecting ",", ")"
在 github actions 表达式中操作字符串有哪些选项?我在文档中没有找到它https://docs.github.com/en/actions/learn-github-actions/expressions
该技术不需要从行动市场引入任何内容。
在操作中将其添加到
steps:
:
- name: Split branch name
env:
BRANCH: ${{ github.ref_name }}
id: split
run: echo "fragment=${BRANCH##*/}" >> $GITHUB_OUTPUT
它捕获 shell 命令的输出。唯一必要的操作是将
github.ref_name
设置为环境变量并使用 参数扩展 来获取所需的分支名称部分。
##
贪婪地从前面删除后续图案*/
匹配任何后跟 /
##*/
会删除最后一个正斜杠之前的所有内容。因为
id
是 split
和 name=fragment
,所以您可以使用 steps.split.outputs.fragment
引用分割字符串。例如,
# Another step
- name: Test variable
run: |
echo ${{ steps.split.outputs.fragment }}
其他参数扩展功能在这里也很有用,例如除了
#
之外,还有 %
、%%
和 ##
。
最初我用
$(echo ${BRANCH##*/})
生成了另一个进程,但这是不必要的。该变量可以直接引用。
我正在做一些本质上相同的事情,并且使用操作是最简单的临时解决方法,但是我也更喜欢内置的东西,例如字符串分割表达式。现在这就是有效的方法。
- uses: jungwinter/split@master
id: branch
with:
msg: ${{ github.ref_name }}
separator: "/"
maxsplit: -1
来自其存储库:
输出
、_0
、...、_1
:每个拆分结果_n
- 根据输出的元数据语法,它有
前缀_
- 目前仅支持100个分割
:分割的长度length
因此,我可以使用
steps.branch.outputs._n
引用字符串的每个部分,其中 branch
是 id,n
是分割索引。
我正在寻找分支名称中的第一个值而不是最后一个值,因此我可以将
maxsplit
设置为 1,然后只取 _0
。在您的情况下,您可能需要通过检查 length
并从那里选择索引来施展一些魔法。
我最终使用 bash 进行拆分并将其作为作业输出发布。回想起来,应该只安装 python(bash 语法更混乱且更难维护)。
build-docker:
container: docker:cli
outputs:
docker-tag: ${{steps.docker-tag.outputs.DOCKER_TAG}}
steps:
- name: add bash
run: |
apk update
apk upgrade
apk add bash
- name: determine docker tag by splitting branch name on slash
id: docker-tag
shell: bash
run: |
split=(${GITHUB_REF_NAME//\// })
index=$((${#split[@]}-1))
DOCKER_TAG=${split[$index]}
echo DOCKER_TAG=$DOCKER_TAG >> $GITHUB_ENV
echo "::set-output name=DOCKER_TAG::$DOCKER_TAG"
- name: Build and push
uses: docker/build-push-action@v3
file: ./docker/ci/Dockerfile
push: true
tags: |
artifactory.com/repo/image:${{ env.DOCKER_TAG }}
test-job:
needs: build-docker
runs-on: [self-hosted, Linux, docker]
container:
image: artifactory.com/repo/image:${{ needs.build-docker.outputs.docker-tag }}