在开发 GitHub Actions 时,有时候会遇到这样的问题:如果这个 Action 接受来自用户的 GitHub token,那该如何以这个 token 背后的身份完成所需的 git 操作?
使用 token 操作 GitHub API 是很容易的,通过 @actions/github
(或 @octokit/core
)创建一个 Octokit
实例时把 token 传进去就可以了,之后通过这个实例进行的所有 API 调用(包括 REST 和 GraphQL)都会以这个 token 的身份进行。但命令行的 git 操作怎么办呢?如何让 git commit
的作者变成 token 背后的身份?如何让 git push
以 token 背后的身份进行提交?(这两者并不一定要用同一个身份。)我做了 config-git-with-token-action
就是用来解决这个问题的。
这个 Action 会对 gh
和 git
进行配置,让它们的身份信息变成 GitHub token 背后的身份信息。gh
的配置相对简单一些,把 GH_TOKEN
这一环境变量配置好就行了,然后执行 go auth status
就能打印出 gh
认为自己在使用的身份信息。对 git
进行配置稍微麻烦一些,gh auth setup-git
只能保证 git 在跟 GitHub 交互时从 gh
获得身份信息,但并不指明具体是哪一个身份。为了保证 git commit
使用正确的身份,需要通过 git config
来设置正确的用户名和邮箱。此外,为了保证 git push
使用正确的身份,需要通过 git remote set-url origin
来更新上游地址,在 https://github.com/…
的地址中注入用户名和 token,让它变成 https://username:token@github.com/…
。
这个 Action 假设用户在执行它之前已经执行过了 @actions/checkout
,所以它不会尝试自行建立项目目录。大家最好使用同一个 token 进行 @actions/checkout
,这样项目目录从一开始就是以 token 背后的身份创建的。以下是一个完整的用例:
runs:
using: ‘composite’
steps:
- uses: actions/checkout@v4
- uses: CatChen/config-git-with-token-action@v1
with:
github-token: ${{ inputs.github-token }}
- shell: bash
run: |
echo “Set up git user name: $(git config —get user.name)”
echo “Set up git user email: $(git config —get user.email)”
echo “Set up git remote origin with login and token: $(git remote get-url origin)”
- shell: bash
run: |
touch test_file
git commit test_file -m ‘Created test file’
git push
做为 GitHub Actions 开发者,如果你利用 JavaScript 而非 bash 进行开发,那上述 composite action 的用例并不适用,我们需要一个针对 JavaScript action 的用例。我自己有同样的需求,所以 config-git-with-token-action
同时还是一个 NPM 包,可以在 JavaScript 中进行调用获得同样的功能。(这个包具备完整的 TypeScript 类型信息。)安装好之后,通过 JavaScript 调用的用例如下:
import { configGitWithToken } from ‘config-git-with-token-action’;
await configGitWithToken(githubToken);
希望这个 Action 对各位 GitHub Actions 开发者有用。非 Actions 开发者也可以直接在 Workflow 里面使用这个 Action,如果你的 Workflow 使用非默认的 GitHub Actions(机器人)身份进行 git 操作的话。大家在使用过程中遇到什么问题,或者是希望增加什么新功能,欢迎到项目的 GitHub 开 issue。
至于这个 Action 是如何获取到 token 背后的身份信息的,那是这个系列的下一篇文章要介绍的下一个 Action 负责的。