问题描述
在使用GitHub Actions时遇到了一个问题:他在一个仓库中有两个目录,一个包含用于构建C库的Makefile,另一个包含用于构建基于Node-API的Node.js C插件和使用该插件的小型JS/TS API的Makefile。后者依赖于前者。用户希望根据代码提交的位置和内容,最小限度地运行所需的GitHub Workflows。
具体来说,当只有C目录发生变更时,用户希望运行涉及C库的Workflow和涉及Node.js C插件的Workflow。当只有Node.js C插件目录发生变更时,用户只希望运行涉及Node.js C插件的Workflow。当C目录和Node.js C插件目录都发生变更时,用户希望运行两个Workflow,但是Node.js C插件的Workflow只运行一次。
然而,当前的设置中,当C目录和Node.js C插件目录都发生变更时,Node.js C插件的Workflow被触发了两次,一次是因为Node.js C插件目录的变更,另一次是因为C目录的Workflow成功完成。
用户希望解决这个问题,避免Node.js C插件的Workflow重复触发。
解决方案
解决方案1
在GitHub Actions中,可以通过以下步骤来解决这个问题:
- 在Workflow文件中,添加一个步骤以获取提交/PR中所修改的文件列表。可以使用GitHub提供的API来获取这些信息。
- 根据文件列表的内容,决定是否运行C目录的Workflow和Node.js C插件的Workflow。
- 对于Node.js C插件的Workflow,可以使用一个标志来标记是否已经运行过,以避免重复触发。
以下是一个伪代码示例,演示了如何在Workflow中实现这个解决方案:
name: Check Changes
on:
push:
paths:
- 'C/*'
- 'NAPI/*'
jobs:
check-changes:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Get changed files
run: |
CHANGED_FILES=$(git diff --name-only ${{ github.event.before }} ${{ github.sha }})
echo "Changed files: $CHANGED_FILES" > changed_files.txt
- name: Check C directory
run: |
if grep -q 'C/' changed_files.txt; then
echo "Run C Workflow"
# Run C Workflow here
fi
- name: Check NAPI directory
run: |
if grep -q 'NAPI/' changed_files.txt; then
if [ ! -f "napi_workflow_run.txt" ]; then
echo "Run NAPI Workflow"
touch napi_workflow_run.txt
# Run NAPI Workflow here
else
echo "NAPI Workflow already run"
fi
fi
解决方案2
另一种解决方案是将C目录的Makefile和Node.js C插件的Makefile合并成一个Makefile。然后在GitHub Workflow中运行make all
命令,并使用GitHub Actions的缓存功能,只有在依赖发生更改时才重新构建组件。
此外,你可以使用GitHub Actions的concurrency功能,确保多个运行不会同时重叠。
以下是一个伪代码示例,演示了如何在Makefile和Workflow中实现这个解决方案:
name: Build
on:
push:
paths:
- '**/*'
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: 14
- name: Install dependencies
run: npm install
- name: Build all
run: make all
- name: Save cache
uses: actions/cache@v2
with:
path: |
~/.npm
node_modules
key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}
- name: Cleanup
run: make clean
通过合并Makefile和使用缓存,可以实现更高效的构建和部署过程。
请根据你的实际情况选择适合的解决方案,并在实施之前做好充分的测试。