我为什么要这么做呢?
我们有一个私人仓库,维护者可以请求加入私人维护者社区。
有人认为用 @undefined 和 undefined 的句柄提交 1000 个问题到仓库会很有趣,但这是一个问题,因为它使得维护者很难找到需要被批准的实际问题。
在我能够向问题表单添加验证之前,我们需要对仓库做一些额外的工作,但与此同时,我们需要关闭这些问题。因此,我认为一个临时解决方案将是创建一个 GitHub 操作,关闭所有的问题 - 标题包含 Pending invitation request for: @undefined'
。
我们从1600多个问题,在几分钟内减少到64个有效问题。
这就是我所做的。
我做的第一件事就是去找我的人工智能助手聊天(GitHub Copilot Chat),问它我是否可以用一个 GitHub 操作关闭 1000 个问题。它给了我几个选项,但我决定用这个:
然后它生成了 closeIssue.js
文件,看起来像这样:
太好了,这是大部分的工作。现在我只需要将动作添加到我的仓库中。
我在 .github/workflows
目录下创建了一个名为 close_issues.yml
的文件,并添加了以下代码:
name: Close Undefined Issues
on:
workflow_dispatch:
push:
branches: [ "main" ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ "main" ]
schedule:
- cron: '43 0 * * 1'
jobs:
close_issues:
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: Run script
run: node closeIssues.js
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
我对代码做了一些调整,
这段代码主要是与
但总的来说,
Copilot合作编写的。
我创建的下一个文件是 closeIssues.js
文件,我添加了以下代码:
import { Octokit } from "@octokit/rest";
const octokit = new Octokit({
auth: process.env.GITHUB_TOKEN,
});
async function closeIssues() {
const { data: issues } = await octokit.issues.listForRepo({
owner: 'OWNER',
repo: 'internal-repo',
});
const issuesToClose = issues.filter(issue => issue.title === 'Pending invitation request for: @undefined');
for (const issue of issuesToClose) {
await octokit.issues.update({
owner: 'OWNER',
repo: 'internal-repo',
issue_number: issue.number,
state: 'closed',
});
}
}
closeIssues().catch(console.error);
我添加了一个 package.json
文件到我的仓库中,安装了需要的依赖,然后将代码推送到我的仓库中。
经过大约3次(好吧4次!) 尝试,我终于成功地运行了这个GitHub Action。
最初,这个操作一次关闭 30 个问题,因为这是 GitHub API 的限制。因此,我必须阅读文档 来理解如何获取所有符合条件的问题并关闭它们。
在阅读了文档后,我意识到我需要使用paginate()
方法来获取指定仓库的所有问题,我还了解到,通过 paginate,问题将以数组的形式返回,因此我不再需要 const { data: issues }
,在发出请求时,我还需要使用 octokit.rest.issues
。
最终,成功运行并同时关闭所有 1000 个问题的代码如下:
import { Octokit } from "@octokit/rest";
const octokit = new Octokit({
auth: process.env.GITHUB_TOKEN,
});
async function closeIssues() {
try {
console.log('Fetching issues...');
const issues = await octokit.paginate(octokit.rest.issues.listForRepo, {
owner: 'OWNER',
repo: 'internal-repo',
state: 'open',
});
console.log(`Fetched ${issues.length} issues.`);
const issuesToClose = issues.filter(issue => issue.title === 'Pending invitation request for: @undefined');
console.log(`Found ${issuesToClose.length} issues to close.`);
for (const issue of issuesToClose) {
console.log(`Closing issue #${issue.number}...`);
await octokit.rest.issues.update({
owner: 'OWNER',
repo: 'internal-repo',
issue_number: issue.number,
state: 'closed',
});
console.log(`Closed issue #${issue.number}.`);
}
} catch (error) {
console.error(error);
}
}
closeIssues();
我给代码添加了一些日志,这样我就能看到工作流运行期间发生了什么。我还添加了一个try/catch块来捕获可能发生的任何错误。
我很高兴我能做到这一点,因为我的队友要花好几个小时才能手动关闭所有这些问题。我可以在几分钟内完成!我超级兴奋的是,GitHub Copilot能够教我一些新的东西——如何使用Octokit库与GitHub API交互。
你曾经使用过 GitHub Copilot 来帮助你编写 GitHub Actions 吗?请在文章下面发送消息告诉我!我希望你今天学到了新的东西。
欢迎关注公众号:文本魔术,了解更多