GitHub Action遍历CHANGED_FILES字符串数组失败的问题求助
GitHub Action JSON Schema验证:逐个处理文件的正确实现
问题场景
使用GitHub Action验证JSON文件与对应Schema时,当前实现无法定位具体报错的文件,需要逐个处理变更文件,但原Workflow的循环写法触发错误:
Property ${{ each env in inputs.CHANGED_FILES }} is not allowed.
原Workflow代码:
name: JSON Schema Validation on: workflow_call: inputs: CHANGED_FILES: required: true type: string jobs: verify-json-validation: runs-on: ubuntu-latest steps: - ${{ each changedFile in inputs.CHANGED_FILES }}: verify-json-validation: runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 - name: Validate JSON Schema uses: cardinalby/schema-validator-action@v2 with: file: changedFile schema: 'schemas/notificationConfiguration.schema.json'
错误分析
- 循环层级错误:GitHub Action不支持在
steps层级直接使用each循环,要实现多文件逐个验证,需通过**矩阵(matrix)**动态生成独立任务。 - 字符串处理语法错误:尝试的
split写法不符合GitHub Action表达式规范,无法正确将逗号分隔字符串转为数组。 - 变量引用错误:循环中未使用正确的表达式语法引用文件名,直接写
changedFile无法识别为变量。
解决方案
方案一:使用矩阵策略(推荐)
通过矩阵动态生成任务,逐个验证每个文件,失败时可直接定位问题文件:
name: JSON Schema Validation on: workflow_call: inputs: CHANGED_FILES: required: true type: string jobs: verify-json-validation: runs-on: ubuntu-latest strategy: fail-fast: false # 单个文件验证失败不中断其他文件 matrix: # 将逗号分隔字符串转换为JSON数组 changedFile: ${{ fromJson('["' + replace(inputs.CHANGED_FILES, ', ', '","') + '"]') }} steps: - uses: actions/checkout@v4 - name: Validate ${{ matrix.changedFile }} against Schema uses: cardinalby/schema-validator-action@v2 with: file: ${{ matrix.changedFile }} schema: 'schemas/notificationConfiguration.schema.json'
关键细节
- 矩阵生成逻辑:通过
replace把输入的file1.json, file2.json格式转为["file1.json","file2.json"],再用fromJson解析为矩阵数组。 - fail-fast: false:确保所有文件都能完成验证,一次性查看所有错误。
- 明确任务名称:步骤名称中包含文件名,验证失败时直接显示问题文件。
方案二:Shell脚本循环处理
如果矩阵方式不适用,可通过Shell脚本逐个验证文件:
name: JSON Schema Validation on: workflow_call: inputs: CHANGED_FILES: required: true type: string jobs: verify-json-validation: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Install AJV validator run: npm install -g ajv-cli - name: Validate all JSON files run: | # 将逗号分隔字符串转为数组 IFS=', ' read -r -a file_list <<< "${{ inputs.CHANGED_FILES }}" exit_code=0 for file in "${file_list[@]}"; do echo "=== Validating $file ===" ajv validate -s schemas/notificationConfiguration.schema.json -d "$file" if [ $? -ne 0 ]; then echo "❌ Validation failed for $file" exit_code=1 fi done exit $exit_code
这个方案需要安装ajv-cli,优点是可自定义错误输出格式,灵活性更高。
内容的提问来源于stack exchange,提问作者Simon Price
相关产品推荐
相关产品推荐

