我创建了一个 GitHub Actions 作业,其中包含一个创建一组环境变量的策略矩阵。 其中之一是
machine_architecture
,即 32 或 64。
在大多数步骤中我可以直接使用它,即通过
${{ machine_architecture }}
。
但有些步骤需要“i386”与“x86_64”等字符串。 github actions 有没有一种简单的方法来创建我可以在以下表达式中使用的地图对象:
map_object = { 32: "i386", 64: 'x86_64' }
...
${{ map_object[machine_architecture] }}
如果没有,github actions 中解决该问题的惯用方法是什么?
PS:我知道,我可以在步骤中设置环境变量,但问题是,这些变量仅适用于以下步骤(即不适用于“run-on:”标签)
同时我找到了解决方案:
虽然 GitHub Actions 没有直接创建映射/对象的语法,但可以使用 fromJson():
间接完成${{ fromJson('{ 32: "i386", 64: "x86_64" }')[machine_architecture] }}
这个 fromJson() 将创建一个从 int 到 string 的映射。以下 [] 运算符将 int 类型“machine_architecture”解析为字符串类型。
我不需要矩阵,但我需要一张用于查找的地图。
无法获得@PeterEvans 的答案来使用 GitHub,所以我稍微修改了一下:
jobs:
yourJobName:
name: Cool Job
runs-on: ubuntu-latest
steps:
- name: Get Machine Arc
run: |
MACHINE_ARC_MAP=$(cat <<END
{
32: "i386",
64: "x86_64",
999: ${{ secrets.SECRET_ARC }}
}
END
)
TARGET_ARC=$(echo $MACHINE_ARC_MAP | jq -r 'to_entries[] | select(.key=="${{ github.event.inputs.machine_architecture }}") | .value')
echo "TARGET_ARC=$TARGET_ARC" >> $GITHUB_ENV
- name: Echo Selected value
run: |
echo ${env.TARGET_VAR}
这里有一种使用 JSON 和 jq 来实现的方法。它创建步骤输出
${{ steps.vars.outputs.arch }}
,您可以在后续步骤中使用它。
jobs:
varMap:
strategy:
matrix:
machine_architecture: [32, 64]
runs-on: ubuntu-latest
steps:
- name: Set arch var
id: vars
run: |
echo ::set-output name=arch::\
$(echo '{ "32": "i386", "64": "x86_64" }' | jq -r 'to_entries[] | select(.key=="${{ matrix.machine_architecture }}") | .value')
- name: Test arch var
run: echo "Testing ${{ steps.vars.outputs.arch }}"
你的“map_object”实际上是一个将
machine_architecture
值映射到你需要的值的文件,例如:
32=i386
64=x86_64
或您想要保留的任何其他格式。
然后,您的工作可以在辅助变量中将其定义为:
jobs:
FirstJob:
name: job 1
runs-on: .....
steps:
- uses: ....
- name: Define variables
run: |
cat $(cat MAP_OBJECT_FILE_NAME) | grep $(cat machine_architecture)= | > MACHINE_ARCHITECTURE_STRING
从那时起,您将拥有可用于您需要的作业的
MACHINE_ARCHITECTURE_STRING
变量。当然,您可以做更简单的连接或其他操作,但在这里您可以使用映射文件在代码中维护映射,并且是可扩展的。
这是一个糟糕的解决方案,只能在工作流程中工作,而不是自定义操作,但您可以将查找表放在虚拟矩阵维度中。
jobs:
varMap:
strategy:
matrix:
lookup: [{ "32": "i386", "64": "x86_64" }]
arch: [32, 64]
runs-on: ubuntu-latest
steps:
- name: test
run: echo "Testing ${{ matrix.lookup[format('{0}',matrix.arch)] }}"
因为
lookup
的长度为 1,所以它不会导致作业的任何额外执行,它只是始终与您的真实矩阵一起可用。矩阵值是工作流语法允许使用真实对象和数组的少数几个位置之一,也可能是作业稍后可以在任意表达式中访问的唯一位置。 format
调用是将数字转换为字符串,如果 arch
是字符串而不是整数,则不需要。
这在自定义操作中不起作用,因为它们没有矩阵功能。自定义操作 yaml 语法的任何部分都不允许任意数组/对象。
这可能会对您的工作和/或步骤的明显/可见名称产生不良影响。就像我说的,糟糕的解决方案。