GitHub Action自动校验格式化PR变更代码失败,求排查及替代方案
GitHub Action 自动校验/格式化变更文件失败问题排查及解决方案
一、错误原因分析
1. 自动校验Action(Lint)报错./lint.sh: line 1: No: command not found
- 核心问题:
tj-actions/changed-files输出的all_changed_files是换行分隔的文件列表,但你用for file in ${ALL_CHANGED_FILES}遍历会把换行解析为空格,若文件名含空格或工具输出异常字符串(比如"No changed files"),会导致pnpm lint:check被传入无效参数,触发命令错误。 - 额外可能:即使
any_changed判断为true,若文件列表格式不符合预期,也会出现该问题。
2. 自动格式化Action(Format)报错ENOTEMPTY: directory not empty
- 核心问题:
pnpm/action-setup与actions/setup-node的缓存机制冲突,或本地Act环境中已存在pnpm目录,导致安装时无法重命名目录完成升级。 - 额外问题:当前配置中提交代码的权限不足,即使格式化成功也无法push到PR分支。
二、修复后的配置代码
修复后的自动校验Action
name: Lint changed files on: pull_request: types: [opened, synchronize, reopened] jobs: auto_lint: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: 20 cache: 'pnpm' - name: Setup pnpm uses: pnpm/action-setup@v4 with: version: 8 run_install: false - name: Get changed files id: changed-files uses: tj-actions/changed-files@v44 with: # 可指定需要校验的文件后缀,比如只处理js/ts文件 files: | **/*.js **/*.ts **/*.jsx **/*.tsx - name: Install dependencies run: pnpm install - name: Lint all changed files if: steps.changed-files.outputs.any_changed == 'true' env: ALL_CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }} run: | # 用while循环读取换行分隔的文件列表,支持带空格的文件名 while IFS= read -r file; do if [ -f "$file" ]; then pnpm lint:check "$file" fi done <<< "$ALL_CHANGED_FILES" - name: No changes to lint if: steps.changed-files.outputs.any_changed != 'true' run: echo "No files to lint"
修复后的自动格式化Action
name: Format changed files on: pull_request: types: [opened, synchronize, reopened] jobs: auto_format: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 with: fetch-depth: 0 persist-credentials: false - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: 20 cache: 'pnpm' - name: Setup pnpm uses: pnpm/action-setup@v4 with: version: 8 run_install: false - name: Get changed files id: changed-files uses: tj-actions/changed-files@v44 with: files: | **/*.js **/*.ts **/*.jsx **/*.tsx - name: Install dependencies run: pnpm install - name: Format all changed files if: steps.changed-files.outputs.any_changed == 'true' env: ALL_CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | while IFS= read -r file; do if [ -f "$file" ]; then pnpm format:fix "$file" fi done <<< "$ALL_CHANGED_FILES" # 检查是否有格式化后的变更 if git diff --exit-code; then echo "No files needed formatting" exit 0 fi git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" git add . git commit -m "style: auto format" # 使用GITHUB_TOKEN授权push到PR分支 git push https://x-access-token:$GITHUB_TOKEN@github.com/${{ github.repository }}.git HEAD:${{ github.head_ref }} - name: No changes to format if: steps.changed-files.outputs.any_changed != 'true' run: echo "No files to format"
三、现成替代Action推荐
如果不想自己维护配置,可以直接使用成熟的第三方Action:
- 针对Lint:
reviewdog/action-eslint,支持仅检查PR变更文件,直接在PR中评论Lint错误,无需手动遍历文件。 - 针对格式化:
creyD/prettier_action,自动用Prettier格式化代码并提交到PR,支持自定义格式化命令。 - 一体化工具:
tj-actions/eslint,专门针对变更文件的ESLint检查,内置文件过滤逻辑,无需额外处理文件列表。
内容的提问来源于stack exchange,提问作者Ethan
相关产品推荐
相关产品推荐

