如何在GitHub Actions触发前的预构建脚本中获取PR变更文件
解决GitHub Actions预构建脚本中获取PR变更文件的问题
核心问题原因
你遇到的“bad substitution”错误是因为GitHub Actions的模板语法(${{ steps.files.outputs.all }})只能在Workflow的YAML配置中使用,无法直接在独立的shell脚本文件里解析——shell本身不认识这种语法结构。
可行解决方案步骤
1. 在Workflow中先提取变更文件列表
先在Workflow里新增一个步骤,用Git命令对比PR的基准分支和头分支,把变更文件列表存为环境变量或Step输出变量:
jobs: pre-build-auth: runs-on: ubuntu-latest steps: - name: 拉取完整代码仓库 uses: actions/checkout@v4 with: fetch-depth: 0 # 必须拉取完整历史才能对比分支差异 - name: 获取PR变更文件 id: get-changes run: | # 提取基准分支与当前分支的差异文件 CHANGED_FILES=$(git diff --name-only ${{ github.base_ref }} ${{ github.head_ref }}) # 写入环境变量,供后续脚本读取 echo "CHANGED_FILES=$CHANGED_FILES" >> $GITHUB_ENV # 同时写入Step输出,也可在YAML后续步骤中直接引用 echo "all=$CHANGED_FILES" >> $GITHUB_OUTPUT
2. 在预构建脚本中读取变更文件并验证
修改你的预构建shell脚本,通过环境变量$CHANGED_FILES获取变更列表,再检查是否包含目标文件夹的变更,最后执行身份验证逻辑:
#!/bin/bash # 从环境变量读取变更文件列表 CHANGED_FILES="$CHANGED_FILES" TARGET_FOLDER="your/target/folder/path" # 遍历变更文件,检查是否涉及目标文件夹 for file in $CHANGED_FILES; do if [[ "$file" == "$TARGET_FOLDER"/* ]]; then echo "检测到目标文件夹变更,启动身份验证..." # 从github_event_path提取用户信息 USER_LOGIN=$(jq -r '.pull_request.user.login' "$GITHUB_EVENT_PATH") # 这里替换为你的实际身份验证逻辑 # 示例:检查用户是否在授权列表中 AUTHORIZED_USERS=("user1" "user2" "team-bot") if [[ ! " ${AUTHORIZED_USERS[@]} " =~ " ${USER_LOGIN} " ]]; then echo "错误:用户 $USER_LOGIN 无权限修改目标文件夹" exit 1 fi echo "用户 $USER_LOGIN 身份验证通过" break fi done
3. 在Workflow中调用预构建脚本
在Workflow里添加步骤调用脚本,确保GITHUB_EVENT_PATH环境变量正常传递:
- name: 执行预构建身份验证 run: | chmod +x ./your-pre-build-script.sh ./your-pre-build-script.sh env: GITHUB_EVENT_PATH: ${{ github.event_path }}
关键注意事项
- 必须设置
fetch-depth: 0:默认checkout只拉取最新提交,没有完整分支历史的话,git diff无法正确对比PR的两个分支。 - 避免在shell脚本中直接写GitHub模板语法:所有需要的变量都要通过环境变量传递,或者在YAML的
run字段中先注入到脚本环境。 - 触发条件确保为
pull_request:只有PR事件下,github.base_ref和github.head_ref才会被正确赋值,git diff才能生效。
内容的提问来源于stack exchange,提问作者SHRISHA HEGDE
相关产品推荐
相关产品推荐

