GitHub Actions中ZX脚本无法执行远程Git命令的问题
问题描述
我想在GitHub合并Pull Request后自动运行一个用ZX库编写的JavaScript脚本,用来确定npm包的下一个发布版本——需要拉取GitHub上最新的Git标签来协商版本号。但执行git pull --tags时出现超时,错误提示涉及“Username”,怀疑Git在用密码而非个人访问令牌进行GitHub认证。
已经用act实现本地运行脚本,Workflow中配置了Git HTTPS认证,最初直接在Workflow里执行git pull --tags能正常运行,之后失效。脚本内尝试了以下操作:
- 打印
GITHUB_TOKEN,可正常输出; - 执行无需远程认证的Git命令(如
git status),运行正常; - 在脚本内设置Git config,打印config能看到令牌,但
git pull --tags仍失败。
错误日志
| Username for 'https://github.com': /Users/work/projects/aves/node_modules/zx/build/core.cjs:245 | const output = new ProcessOutput( | ^ | | ProcessOutput [Error]: | at /Users/work/projects/aves/scripts/prepublish.js:609:37 | exit code: null | signal: SIGTERM | at EventEmitter.end (/Users/work/projects/aves/node_modules/zx/build/core.cjs:245:28) | at EventEmitter.emit (node:events:519:28) | at ChildProcess.<anonymous> (/Users/work/projects/aves/node_modules/zx/build/vendor.cjs:20283:16) | at ChildProcess.emit (node:events:519:28) | at maybeClose (node:internal/child_process:1105:16) | at Socket.<anonymous> (node:internal/child_process:457:11) | at Socket.emit (node:events:519:28) | at Pipe.<anonymous> (node:net:338:12) { | _code: null, | _signal: 'SIGTERM', | _stdout: '', | _stderr: '', | _combined: '' | } | | Node.js v20.15.0 error Command failed with exit code 1.
Workflow配置
name: Publish Package to npmjs on: pull_request: branches: - main types: ['closed'] jobs: build: runs-on: ubuntu-latest env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} steps: - name: Git checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Setup Node.js and copy .npmrc file uses: actions/setup-node@v4 with: node-version: '20.x' registry-url: 'https://registry.npmjs.org' - name: Configure git for HTTPS run: | git config --global url.https://github.com/.insteadOf git@github.com: git config --global url.https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/.insteadOf https://github.com/ - name: Fetch tags run: yarn && yarn zx ./scripts/prepublish.js --ci
脚本代码(prepublish.js)
#!/usr/bin/env zx const zx = require('zx'); const { $, spinner } = zx; (async () => { await $`git config --global url.https://x-access-token:${process.env.GITHUB_TOKEN}@github.com/.insteadOf https://github.com/`; const { stdout: gitConfig } = await $`git config --list`; console.log({ gitConfig }); const { stdout, stderr } = await $`git pull --tags`.timeout('2m'); if (stderr) { console.error('stderr:', stderr); } console.log('stdout:', stdout); return; })()
解决方案
1. 直接设置远程仓库地址,替换insteadOf规则
当前的insteadOf规则可能存在优先级或匹配问题,直接在Workflow中重新设置带令牌的远程地址:
git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/你的用户名/你的仓库名.git
将你的用户名/你的仓库名替换为实际信息,这样无需依赖规则匹配,直接用认证后的地址拉取。
2. 避免全局Git config冲突
Workflow和脚本中都设置了全局Git config,可能导致冲突。建议仅在当前仓库级别配置,去掉--global参数:
- Workflow的
Configure git for HTTPS步骤修改为:
git config url.https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/.insteadOf https://github.com/
- 脚本内的Git config命令修改为:
await $`git config url.https://x-access-token:${process.env.GITHUB_TOKEN}@github.com/.insteadOf https://github.com/`;
3. 替换git pull --tags为更轻量的git fetch --tags
如果仅需要获取最新标签,无需拉取所有分支更新,换成git fetch --tags能减少请求量,降低超时概率:
const { stdout, stderr } = await $`git fetch --tags`.timeout('2m');
4. 调试Git认证过程
添加Git调试日志,查看认证请求细节,确认令牌是否正确使用:
await $`GIT_CURL_VERBOSE=1 git fetch --tags`.timeout('2m');
5. 确认GITHUB_TOKEN权限
默认的GITHUB_TOKEN已具备仓库读取权限,如果使用自定义令牌,需确保其拥有仓库读取权限。
内容的提问来源于stack exchange,提问作者zkwsk
相关产品推荐
相关产品推荐

