如何为每个更新目录触发GH Action并执行打包推送?
实现GitHub Action打包更新目录并差异化推送的方案
以下是几种能满足需求的具体方案,可根据你的场景选择:
方案1:动态生成矩阵(推荐)
这个方案能自动识别提交中更新的目录,为每个目录生成独立的工作流任务,每个任务可配置专属参数,且任务并行执行。
name: 打包更新目录并推送 on: [push] jobs: # 第一步:检测本次提交中变更的目标目录 detect-changes: runs-on: ubuntu-latest outputs: changed_dirs: ${{ steps.set-matrix.outputs.changed_dirs }} steps: - uses: actions/checkout@v4 with: fetch-depth: 2 # 拉取上一次提交用于对比变更 - name: 提取更新的目录列表 id: set-matrix run: | # 筛选出dir1-dir4中发生变更的目录,去重后转为JSON数组 CHANGED_DIRS=$(git diff --name-only HEAD^ HEAD | grep -E '^(dir1|dir2|dir3|dir4)/' | cut -d'/' -f1 | sort | uniq) MATRIX=$(echo "$CHANGED_DIRS" | jq -R . | jq -s .) echo "changed_dirs=$MATRIX" >> "$GITHUB_OUTPUT" # 第二步:为每个更新的目录执行打包+推送 build-and-push: needs: detect-changes if: ${{ needs.detect-changes.outputs.changed_dirs != '[]' }} runs-on: ubuntu-latest strategy: matrix: dir: ${{ fromJSON(needs.detect-changes.outputs.changed_dirs) }} steps: - uses: actions/checkout@v4 - name: 设置当前目录的专属参数 id: set-params run: | case ${{ matrix.dir }} in dir1) echo "name=项目A" >> "$GITHUB_OUTPUT" echo "target_source=专属源地址1" >> "$GITHUB_OUTPUT" ;; dir2) echo "name=项目B" >> "$GITHUB_OUTPUT" echo "target_source=专属源地址2" >> "$GITHUB_OUTPUT" ;; dir3) echo "name=项目C" >> "$GITHUB_OUTPUT" echo "target_source=专属源地址3" >> "$GITHUB_OUTPUT" ;; dir4) echo "name=项目D" >> "$GITHUB_OUTPUT" echo "target_source=专属源地址4" >> "$GITHUB_OUTPUT" ;; esac - name: 打包目录为Zip run: zip -r "${{ matrix.dir }}.zip" ${{ matrix.dir }}/ - name: 推送Zip到指定源 run: | # 替换为你的实际推送命令(比如curl、云服务商CLI等) echo "推送 ${{ matrix.dir }}.zip 到 ${{ steps.set-params.outputs.target_source }},名称为 ${{ steps.set-params.outputs.name }}" # 示例:curl -X POST ${{ steps.set-params.outputs.target_source }} -F "file=@${{ matrix.dir }}.zip" -F "name=${{ steps.set-params.outputs.name }}"
方案2:单任务循环处理所有更新目录
如果不需要独立的工作流运行记录,可在一个任务里循环处理所有更新目录,逐个执行打包和推送:
name: 打包更新目录并推送 on: [push] jobs: build-and-push: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 2 - name: 批量处理更新目录 run: | # 获取本次提交中变更的目录列表 CHANGED_DIRS=$(git diff --name-only HEAD^ HEAD | grep -E '^(dir1|dir2|dir3|dir4)/' | cut -d'/' -f1 | sort | uniq) for DIR in $CHANGED_DIRS; do # 配置当前目录的专属参数 case $DIR in dir1) NAME="项目A" TARGET_SOURCE="专属源地址1" ;; dir2) NAME="项目B" TARGET_SOURCE="专属源地址2" ;; dir3) NAME="项目C" TARGET_SOURCE="专属源地址3" ;; dir4) NAME="项目D" TARGET_SOURCE="专属源地址4" ;; esac # 打包目录 zip -r "${DIR}.zip" "${DIR}/" # 推送文件 echo "推送 ${DIR}.zip 到 ${TARGET_SOURCE},名称为 ${NAME}" # 替换为实际推送命令 # curl -X POST $TARGET_SOURCE -F "file=@${DIR}.zip" -F "name=${NAME}" done
方案3:多工作流独立触发
如果必须为每个目录生成单独的工作流运行记录,可以为每个目录创建独立的工作流文件,比如dir2.yml、dir4.yml,每个工作流仅监听对应目录的变更:
示例dir2.yml:
name: 处理dir2更新 on: push: paths: - 'dir2/**' # 仅当dir2下文件变更时触发 jobs: build-and-push: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: 打包dir2为Zip run: zip -r dir2.zip dir2/ - name: 推送Zip到指定源 run: | # 使用dir2专属参数执行推送 echo "推送dir2.zip到专属源地址2,名称为项目B" # 替换为实际推送命令 # curl -X POST 专属源地址2 -F "file=@dir2.zip" -F "name=项目B"
这种方式适合目录数量少、参数长期固定的场景,但需要维护多个工作流文件。
内容的提问来源于stack exchange,提问作者fuzzi
相关产品推荐
相关产品推荐

