如何在GitHub Actions中获取PR变更文件夹并执行Terraform与KICS扫描
实现需求的GitHub Actions工作流
以下是满足你三个需求的完整工作流配置,同时修复了原有工作流的不足:
name: PR Terraform Checks on: pull_request: branches: [ main ] # 替换为你的目标分支 workflow_dispatch: jobs: terraform-checks: runs-on: ubuntu-latest steps: - name: 检出代码 uses: actions/checkout@v4 with: fetch-depth: 0 # 获取完整历史用于diff对比 - name: 提取变更文件夹 id: changed-folders run: | # 获取PR的基准分支和头分支 base_branch="${{ github.base_ref }}" pr_branch="${{ github.head_ref }}" # 提取Modules目录下变更文件对应的唯一文件夹 changed_modules_folders=$(git diff --name-only $base_branch $pr_branch -- 'Modules/' | awk -F'/' '{print $1"/"$2}' | uniq) # 提取Resource usage目录下变更文件对应的唯一文件夹 changed_resource_folders=$(git diff --name-only $base_branch $pr_branch -- 'Resource usage/' | awk -F'/' '{print $1"/"$2}' | uniq) # 将结果输出为GitHub Actions变量(处理换行符) echo "modules_folders<<EOF" >> $GITHUB_OUTPUT echo "$changed_modules_folders" >> $GITHUB_OUTPUT echo "EOF" >> $GITHUB_OUTPUT echo "resource_folders<<EOF" >> $GITHUB_OUTPUT echo "$changed_resource_folders" >> $GITHUB_OUTPUT echo "EOF" >> $GITHUB_OUTPUT - name: 复制Resource usage中的.tfvars到Modules目录 if: steps.changed-folders.outputs.resource_folders != '' run: | # 遍历Resource usage下的变更文件夹 while IFS= read -r folder; do # 提取文件夹名称(去掉前缀"Resource usage/") folder_name=$(echo "$folder" | sed 's/Resource usage\///') # 复制该文件夹下的所有.tfvars到Modules对应目录 mkdir -p "Modules/$folder_name" cp "$folder"/*.tfvars "Modules/$folder_name/" || echo "No .tfvars files found in $folder" done <<< "${{ steps.changed-folders.outputs.resource_folders }}" - name: 安装Terraform uses: hashicorp/setup-terraform@v3 - name: 对变更文件夹执行terraform fmt检查 if: steps.changed-folders.outputs.modules_folders != '' run: | # 遍历Modules下的变更文件夹 while IFS= read -r folder; do echo "检查目录: $folder" # 执行fmt检查,若格式错误则退出并报错 terraform fmt -check -recursive "$folder" if [ $? -ne 0 ]; then echo "❌ $folder 目录下Terraform代码格式不符合规范" exit 1 fi done <<< "${{ steps.changed-folders.outputs.modules_folders }}"
关键改动说明
- 触发条件优化:新增
pull_request触发,确保PR提交时自动执行检查,保留workflow_dispatch支持手动触发测试。 - 变更文件夹提取:
- 用
awk -F'/' '{print $1"/"$2}'从变更文件路径中提取一级子文件夹(比如Modules/vpc/main.tf提取为Modules/vpc) - 用
uniq去重,避免同一文件夹多次处理 - 用多行输出格式(
<<EOF)处理包含空格的目录名和多行结果
- 用
- .tfvars文件复制:
- 遍历Resource usage下的变更文件夹,提取文件夹名后对应到Modules目录
- 自动创建目标目录(
mkdir -p),避免目录不存在报错
- Terraform fmt检查:
- 使用官方
hashicorp/setup-terraform安装Terraform,保证版本一致性 - 对每个变更文件夹执行
terraform fmt -check -recursive,格式错误时直接终止工作流并提示
- 使用官方
内容的提问来源于stack exchange,提问作者James bond
相关产品推荐
相关产品推荐

