在GitHub Actions工作流中无外部文件使用字典数据类型的技巧
在GitHub Workflow中使用字典结构的技巧(不读取外部文件)
一、定义字典结构
不用外部文件的话,直接通过环境变量或工作流变量定义字典即可,注意要写成JSON字符串格式(避免YAML解析问题):
env: CLUSTER_MAP: '{"clusters01": ["cluster-eu","cluster-us","cluster-au"], "clusters02": ["cluster-eu","cluster-au"]}'
如果需要可读性更强的多行写法,用|定义多行字符串,后续解析时同样用fromJson()转成对象:
env: CLUSTER_MAP: | { "clusters01": ["cluster-eu","cluster-us","cluster-au"], "clusters02": ["cluster-eu","cluster-au"] }
二、检查指定键是否存在
借助GitHub Actions的表达式函数keys()和contains()就能判断键是否存在:
jobs: check-key-exists: runs-on: ubuntu-latest env: CLUSTER_MAP: '{"clusters01": ["cluster-eu","cluster-us","cluster-au"], "clusters02": ["cluster-eu","cluster-au"]}' steps: - name: Verify key presence run: echo "clusters01 exists: ${{ contains(keys(fromJson(env.CLUSTER_MAP)), 'clusters01') }}"
解析逻辑:fromJson()把字符串转成对象,keys()提取所有键组成数组,contains()检查目标键是否在数组中。
三、获取列表并遍历元素
有两种常用遍历方式,根据场景选择:
1. 单步骤内Shell循环
适合在同一个步骤中处理所有元素:
jobs: iterate-in-step: runs-on: ubuntu-latest env: CLUSTER_MAP: '{"clusters01": ["cluster-eu","cluster-us","cluster-au"], "clusters02": ["cluster-eu","cluster-au"]}' steps: - name: Process each cluster run: | for cluster in ${{ join(fromJson(env.CLUSTER_MAP).clusters01, ' ') }}; do echo "Handling cluster: $cluster" # 在这里添加具体处理逻辑 done
用join()把数组转成空格分隔的字符串,方便Shell循环读取。
2. 矩阵式多Job遍历
适合每个元素单独启动一个Job实例(比如并行处理):
jobs: fetch-clusters: runs-on: ubuntu-latest env: CLUSTER_MAP: '{"clusters01": ["cluster-eu","cluster-us","cluster-au"], "clusters02": ["cluster-eu","cluster-au"]}' outputs: target_clusters: ${{ steps.set-output.outputs.clusters }} steps: - id: set-output run: echo "clusters=${{ toJson(fromJson(env.CLUSTER_MAP).clusters01) }}" >> $GITHUB_OUTPUT process-cluster: needs: fetch-clusters runs-on: ubuntu-latest strategy: matrix: cluster: ${{ fromJson(needs.fetch-clusters.outputs.target_clusters) }} steps: - name: Process ${{ matrix.cluster }} run: echo "Processing cluster: ${{ matrix.cluster }}"
先通过前置Job把目标列表输出,再用矩阵strategy遍历每个元素,自动生成多个并行Job。
四、Object Filters(对象过滤器)详解
这是GitHub Actions表达式中用于快速提取集合数据的语法,核心规则如下:
.:访问对象的单个属性,比如obj.key获取对象中key对应的属性值*:通配符,匹配所有元素:obj.*:提取对象所有属性的值,返回一个数组arr.*.key:如果数组元素是对象,提取所有元素的key属性,返回数组obj.*.*:如果对象的属性值是数组,提取所有数组元素,生成扁平数组
针对你的字典示例:
fromJson(env.CLUSTER_MAP).*→ 返回两个集群列表组成的数组:[["cluster-eu","cluster-us","cluster-au"], ["cluster-eu","cluster-au"]]fromJson(env.CLUSTER_MAP).*.*→ 返回所有集群名的扁平数组:["cluster-eu","cluster-us","cluster-au","cluster-eu","cluster-au"]
对象过滤器的作用是简化批量数据提取,不用手动写循环就能快速拿到目标集合。
内容的提问来源于stack exchange,提问作者Sokogen
相关产品推荐
相关产品推荐

