GitHub Actions的startsWith能否处理字符串列表?如何优化lint工作流
问题分析与解决方案
1. GitHub Actions的startsWith/endsWith能否处理文件名列表?
不能。startsWith和endsWith是针对单个字符串的判断函数,只会检查整个输入字符串的开头/结尾是否匹配指定值,不会遍历空格分隔的文件名列表去判断每个元素。
比如你的变更文件列表是src/main.py scripts/deploy.sh,endsWith(..., '.py')会检查整个字符串的结尾是不是.py(实际结尾是.sh),所以条件不成立,导致Python lint步骤被跳过——这就是你当前遇到的核心问题。
2. 实现"仅对变更文件执行lint"的最优方案
推荐利用你已经在使用的tj-actions/changed-files的内置过滤功能,它可以直接帮你筛选出指定后缀的变更文件,还能处理文件名含空格的边缘情况,比手动拆分字符串更可靠。
修改后的完整工作流代码
name: Lint Changed Files on: [push, pull_request] jobs: changed_files: runs-on: ubuntu-latest outputs: has_py_changes: ${{ steps.changed-py.outputs.any_changed }} py_files: ${{ steps.changed-py.outputs.all_changed_files }} has_sh_changes: ${{ steps.changed-sh.outputs.any_changed }} sh_files: ${{ steps.changed-sh.outputs.all_changed_files }} has_yaml_changes: ${{ steps.changed-yaml.outputs.any_changed }} yaml_files: ${{ steps.changed-yaml.outputs.all_changed_files }} steps: - name: Checkout code uses: actions/checkout@v2 with: fetch-depth: 0 # 筛选变更的Python文件 - name: Get changed Python files id: changed-py uses: tj-actions/changed-files@v39 with: files: | **/*.py # 筛选变更的Shell文件 - name: Get changed Shell files id: changed-sh uses: tj-actions/changed-files@v39 with: files: | **/*.sh # 筛选变更的YAML文件 - name: Get changed YAML files id: changed-yaml uses: tj-actions/changed-files@v39 with: files: | **/*.yaml **/*.yml lint: needs: [changed_files] runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v2 - name: Lint Python scripts if: ${{ needs.changed_files.outputs.has_py_changes == 'true' }} run: | pip install flake8 flake8 ${{ needs.changed_files.outputs.py_files }} - name: Lint shell scripts if: ${{ needs.changed_files.outputs.has_sh_changes == 'true' }} run: | sudo apt-get install shellcheck shellcheck ${{ needs.changed_files.outputs.sh_files }} - name: Lint YAML files if: ${{ needs.changed_files.outputs.has_yaml_changes == 'true' }} run: | pip install yamllint yamllint ${{ needs.changed_files.outputs.yaml_files }}
方案优势
- 避免了手动拆分字符串的错误(比如文件名含空格时,
tr ' ' '\n'会把文件名拆成多个元素) - 利用action的
any_changed输出直接判断是否有对应类型的文件变更,条件判断更准确 - 直接使用过滤后的文件列表执行lint命令,无需额外的
grep/xargs处理
替代方案(不依赖action过滤)
如果不想新增多个changed-files实例,可以在lint步骤的if条件里用contains结合通配逻辑,或者在shell命令里先判断是否存在对应文件:
# 示例:Python lint步骤的替代写法 - name: Lint Python scripts if: ${{ contains(needs.changed_files.outputs.all_changed_files, '.py') }} run: | pip install flake8 echo "${{ needs.changed_files.outputs.all_changed_files }}" | tr ' ' '\n' | grep -E '\.py$' | xargs flake8
但这种方法依然存在文件名含空格的问题,仅适合文件名无空格的场景。
内容的提问来源于stack exchange,提问作者Matho Avito
相关产品推荐
相关产品推荐

