如何仅在package.json版本变更时触发GitHub Workflow运行
问题根因
你现在的触发规则有两个问题,才会导致每次合并main分支都跑工作流:
- 路径匹配范围太宽:配置里的
'*.json'会匹配仓库根目录下所有json文件的改动,只要合并的PR改了根目录任意json(比如根目录package.json、tsconfig.json、eslint配置文件等),就会满足触发条件 - 缺少版本变更校验:就算删掉宽匹配规则,只监听
packages/testmodule/package.json,只要有人改了这个文件里的非version字段(比如依赖、脚本命令、仓库地址这些),推代码后一样会触发,根本达不到「只有版本升级才跑发布」的效果
解决方法
方案1:监听版本tag推送(最推荐,零误触发)
npm version patch这类命令执行时,会自动生成对应版本号的git tag,你只要给push命令加上--follow-tags参数把tag推到远端,直接监听tag推送触发就行,完全不会被普通PR合并影响:
name: Publish test module on: push: tags: - 'v*' # 匹配所有v开头的版本tag,比如v1.2.3
这种配置下,只有你执行类似npm version patch && git push origin main --follow-tags的操作,把版本tag推到GitHub时才会触发工作流,平时合并代码、改其他配置完全不会触发,逻辑最干净。
方案2:保留main分支package.json监听,加版本对比校验
如果你不想用tag触发,就想在main分支监听到package.json版本变化时发布,按两步改配置:
- 先删掉冗余的宽匹配路径,只留必要的监听项
- 在工作流里加版本对比步骤,只有检测到version字段确实变了,才执行后续发布逻辑,否则直接跳过
完整配置参考:
name: Publish test module on: push: branches: - main paths: - packages/testmodule/package.json # 调试阶段可以保留工作流文件本身的监听,正式上线后删掉下面这行 - .github/workflows/test.yml jobs: publish: runs-on: ubuntu-latest steps: - name: Checkout 代码 uses: actions/checkout@v4 with: fetch-depth: 2 # 拉取最近两次提交,用于对比文件差异 - name: 校验包版本是否变更 id: ver_check run: | OLD_VER=$(git show HEAD~1:packages/testmodule/package.json | grep '"version"' | head -n1 | awk -F '"' '{print $4}') NEW_VER=$(grep '"version"' packages/testmodule/package.json | head -n1 | awk -F '"' '{print $4}') echo "历史版本:$OLD_VER,当前版本:$NEW_VER" if [ "$OLD_VER" = "$NEW_VER" ]; then echo "版本未变化,跳过发布" echo "skip_publish=true" >> $GITHUB_OUTPUT else echo "检测到版本升级,启动发布流程" echo "skip_publish=false" >> $GITHUB_OUTPUT fi - name: 配置Node环境 if: steps.ver_check.outputs.skip_publish == 'false' uses: actions/setup-node@v4 with: node-version: 20 registry-url: 'https://registry.npmjs.org' - name: 安装依赖 if: steps.ver_check.outputs.skip_publish == 'false' run: npm ci - name: 构建包 if: steps.ver_check.outputs.skip_publish == 'false' run: npm run build -w packages/testmodule - name: 发布到npm if: steps.ver_check.outputs.skip_publish == 'false' run: npm publish -w packages/testmodule env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
内容的提问来源于stack exchange,提问作者Junius L
相关产品推荐
相关产品推荐

