使用无服务器自动回复 GitHub 问题
您是否曾经在 GitHub 上为开源软件项目做出贡献,例如创建了一个问题,并立即收到了回复?如果回复中包含您的感谢,岂不美哉?本文将介绍一种自动创建节日主题“感谢”回复的方法,该回复将自动发送至您在一个或多个 GitHub 仓库中创建的所有问题。
如果您需要参考,这里是源代码的链接。
本文是#25DaysOfServerless 活动的一部分。整个 12 月,Microsoft Cloud Advocates 每天都会发布新的挑战。了解更多关于 Microsoft Azure 如何实现您的无服务器功能的信息。有想法或解决方案?请在 Twitter 上分享您的想法!
想要让这个故事“节日快乐”吗?一个可行的解决方案是使用 Azure Functions 通过 Webhook 监听 GitHub,然后针对该问题创建评论进行响应。我们先来了解一下你需要什么,然后再逐步介绍你可以亲自尝试的步骤。
方法
好的,让我们先回顾一下你接下来要做的事情。当 GitHub 上创建了一个问题时,你需要感谢问题的创建者报告了这个问题。
您需要知道该问题何时创建,因此您需要请求 GitHub 在创建问题时发出警报。GitHub 通过 Webhook 向我们发出警报。该 Webhook 由正在创建的问题触发,然后向您定义的 URL 发出 HTTP 请求,并传递已创建问题的有效负载。那么,GitHub Webhook 的 HTTP 请求会发送到哪里呢?它会调用您使用 Azure Functions 创建的函数。
您将创建一个函数,该函数接受 Webhook 请求并检查其有效负载。您将解析有效负载中的创建者和其他详细信息,并格式化对该问题的响应。现在您已经拥有了创建该问题评论所需的数据,您需要一种方法来回复同一问题并创建评论。然后,您将调用 GitHub API 来创建该问题的评论,并使用允许该函数进行调用的令牌。
您正在 GitHub 存储库和 Azure Functions 之间进行通信,因此您需要确保您拥有在它们之间发出这些 HTTP 请求的正确权限。这非常简单,正如您将在下面的解决方案中看到的那样。
以下是您将要做的事情的摘要:
- 在我们的一个 GitHub 存储库上创建一个 webhook,当创建问题时触发
- 创建一个 Azure 函数来接受 Webhook 发出的 HTTP 请求
- 生成函数在与 GitHub API 通信时可以使用的个人访问令牌
- 从函数向 GitHub API 发出 HTTP 请求以创建评论
现在您已经计划好了要做的事情,让我们开始将它们整合在一起。
资源和工具🚀
选择合适的工具,可以带来翻天覆地的变化。让我们从使用Visual Studio Code和Azure Functions 扩展开始。在我看来,这种组合是入门并高效创建 Azure Functions 的最佳方式。
如果您没有 Azure 帐户,您可以通过此处的链接注册Azure 免费试用版。
安装正确的工具
创建函数
您将首先在 Visual Studio Code 中创建 Azure Function 应用。
创建 Azure 函数项目
- 创建新文件夹并命名
thank-you
- 打开 VS Code 并打开
thank-you
文件夹 - 按F1键打开命令面板。
- 输入并选择Azure Functions:创建新项目
- 如果提示在文件夹中创建项目
thank-you
,请按“是” - 选择TypeScript作为新项目的语言
- 选择HTTP Trigger作为函数的模板
- 将函数命名为SayThankYou
- 选择匿名作为授权级别
VS Code 现在将创建函数项目thank-you和SayThankYou f
测试函数
让我们安装项目的依赖项
- 按F1打开命令面板
- 进入并选择Terminal:Create new integration Terminal
- 在终端中输入
npm install
,安装项目的依赖项 - 按F5运行该函数
- 转到浏览器并在地址栏中输入http://localhost:7071/api/saythankyou?name=Colleen
该函数将通过说“Hello Colleen”来响应浏览器
要停止函数应用运行,请执行以下操作:
- 按F1打开命令面板
- 输入并选择Debug: Disconnect
触发器是一个 webhook
您需要告诉该函数它是由 GitHub webhook 触发的。
- 打开
function.json
文件 - 修改 JSON 以
", webHookType": "github"
在后面添加"methods": ["get", "post"],
有效载荷是多少?
您需要了解函数将从 webhook 接收的有效负载的形状。您可以在GitHub 文档IssuesEvent
中找到相应的有效负载形状。
当您读取函数中的有效载荷时,您将引用此有效载荷信息。
在继续之前,让我们用以下启动代码替换函数中的代码。
import { AzureFunction, Context, HttpRequest } from '@azure/functions';
const httpTrigger: AzureFunction = async function(context: Context, req: HttpRequest): Promise<void> {
const { body: payload } = req;
let body = 'Nothing to see here';
context.res = { status: 200, body };
};
该函数从请求中收集有效负载,然后始终以相同的主体和状态进行响应。接下来,您将重构该函数以从 Webhook 中读取有效负载。
读取有效载荷
您想创建一条消息来感谢问题创建者。您可能需要收集以下信息:问题创建者的用户名、问题编号、仓库名称、仓库所有者以及触发 Webhook 的操作。
使用IssuesEvent
此处的 GitHub 文档作为参考,您可以编写以下代码从有效负载中收集这些值。
// Gather the data from the payload from the webhook
const repo = payload.repository.name;
const owner = payload.repository.owner.login;
const issue_number = payload.issue.number;
const user = payload.issue.user.login;
const action = payload.action;
现在您的函数将类似于以下代码。
import { AzureFunction, Context, HttpRequest } from '@azure/functions';
const httpTrigger: AzureFunction = async function(context: Context, req: HttpRequest): Promise<void> {
const { body: payload } = req;
// Gather the data from the payload from the webhook
const repo = payload.repository.name;
const owner = payload.repository.owner.login;
const issue_number = payload.issue.number;
const user = payload.issue.user.login;
const action = payload.action;
let body = 'Nothing to see here';
context.res = { status: 200, body };
};
制定回应
现在您可以读取有效负载,您需要编写用于创建问题评论的消息。您只需要在触发 Webhook 的事件创建了问题时撰写评论。创建 Webhook 后,您就会知道它来自问题事件。您不想响应编辑或删除问题的操作,因此我们需要查看action
问题事件是否是由打开问题引起的。
以下代码仅在问题被打开(创建)时才会创建消息。
let body = 'Nothing to see here';
if (action === 'opened') {
body = `Thank you @${user} for creating this issue!\n\nHave a Happy Holiday season!`;
context.log(body);
}
您的函数现在应该类似于以下代码。
import { AzureFunction, Context, HttpRequest } from '@azure/functions';
const httpTrigger: AzureFunction = async function(context: Context, req: HttpRequest): Promise<void> {
const { body: payload } = req;
const repo = payload.repository.name;
const owner = payload.repository.owner.login;
const issue_number = payload.issue.number;
const user = payload.issue.user.login;
const action = payload.action;
let body = 'Nothing to see here';
if (action === 'opened') {
body = `Thank you @${user} for creating this issue!\n\nHave a Happy Holiday season!`;
context.log(body);
}
context.res = { status: 200, body };
};
生成个人访问令牌
在我们开始编写代码来创建评论之前,我们需要从 GitHub 生成一个个人访问令牌,以便我们可以让我们的函数与 GitHub 对话。
您只希望令牌能够访问公共存储库,因此请确保仅选择public_repo范围。
- 请按照以下步骤生成个人访问令牌。仅当系统要求您选择令牌的范围时,才选择public_repo 。
- 将令牌复制到剪贴板
令牌是机密信息,不应粘贴到我们的代码中或存储在存储库中。Azure Functions 允许在local.settings.json
文件中设置机密信息和环境变量。此文件默认位于.gitignore
文件中,因此它仅存在于您的本地计算机上。接下来,您将在此文件中添加令牌的设置。
该
local.settings.json
文件仅适用于在计算机上本地运行该函数的情况。当需要将此函数推送到 Azure 时,您还将了解如何推送这些设置。
- 在您的函数项目中打开该
local.settings.json
文件。 - 在
Values
名为githubKey
- 将令牌粘贴为值
您的local.settings.json
代码应该看起来像下面的代码,除了您的令牌。
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "",
"FUNCTIONS_WORKER_RUNTIME": "node",
"githubKey": "YOUR_TOKEN_GOES_HERE"
}
}
在 GitHub 存储库中创建评论
现在您已经拥有了令牌以及想要写入仓库中新评论的消息,接下来需要告诉 GitHub 针对该问题创建一条评论。有几种方法可以做到这一点。一些常见的方法是使用axios之类的 HTTP 库直接向 GitHub API 发出 HTTP 请求,或者使用抽象并简化 HTTP 请求的库。我们选择后者。
Octokit/rest.js库是一个 JavaScript 的 GitHub REST API 客户端。它公开了一个 API,可以轻松创建评论。接下来让我们安装@octokit/rest 。
- 在项目文件夹中打开终端
- 跑步
npm install @octokit/rest
您将需要从库中导入Octokit
和。IssuesCreateCommentParams
import * as Octokit from '@octokit/rest';
import { IssuesCreateCommentParams } from '@octokit/rest';
通过制作类型的对象来创建评论IssuesCreateCommentParams
。
const comment: IssuesCreateCommentParams = {
repo,
owner,
issue_number,
body
};
现在是时候使用库来创建评论了。创建评论的重要 API 是异步函数。但在调用它之前,您需要通过 Octokit 将个人访问令牌从您的函数传递给 GitHub 的 API。您可以通过引用octokit.issues.createComment()
从文件中检索令牌。local.settings.json
process.env.githubKey
我们可以编写以下函数来获取个人访问令牌,将其传递给 Octokit,并创建评论。
async function createComment(comment: IssuesCreateCommentParams) {
const auth = process.env.githubKey;
const octokit = new Octokit({ auth });
const response = await octokit.issues.createComment(comment);
return response;
}
现在我们可以在撰写评论后立即调用该函数。
if (payload.action === 'opened') {
body = `Thank you @${user} for creating this issue!\n\nHave a Happy Holiday season!`;
const comment: IssuesCreateCommentParams = {
repo,
owner,
issue_number,
body
};
await createComment(comment);
}
你的最终功能
您的功能代码现在应该已经完成并且应该类似于下面的代码。
import { AzureFunction, Context, HttpRequest } from '@azure/functions';
import * as Octokit from '@octokit/rest';
import { IssuesCreateCommentParams } from '@octokit/rest';
const httpTrigger: AzureFunction = async function(context: Context, req: HttpRequest): Promise<void> {
const { body: payload } = req;
const repo = payload.repository.name;
const owner = payload.repository.owner.login;
const issue_number = payload.issue.number;
const user = payload.issue.user.login;
const action = payload.action;
let body = 'Nothing to see here';
if (action === 'opened') {
body = `Thank you @${user} for creating this issue!\n\nHave a Happy Holiday season!`;
const comment: IssuesCreateCommentParams = {
repo,
owner,
issue_number,
body
};
await createComment(comment);
}
context.res = { status: 200, body };
};
async function createComment(comment: IssuesCreateCommentParams) {
const auth = process.env.githubKey;
const octokit = new Octokit({ auth });
const response = await octokit.issues.createComment(comment);
return response;
}
export default httpTrigger;
您的功能现已完成!
将函数推送到 Azure
接下来,您需要将函数推送到 Azure。首先,您需要一个 Azure 帐户。如果您没有,可以在此处创建 Azure 免费试用版。
- 打开命令面板F1
- 输入并选择Azure Functions: 在 Azure 中创建函数应用
- 输入全局唯一标识符(名称)
- 如果出现提示,请选择操作系统
- 选择Node.js 10.x
- 选择要创建函数应用的区域
你现在正在 Azure 中创建函数。准备就绪后,VS Code 会提醒你。
在 Azure 中创建应用程序后,您必须将local.settings.json
文件中的设置推送到 Azure 中的应用程序。
- 打开命令面板F1
- 输入并选择Azure Functions:上传本地设置
- 出现提示时,选择您的函数应用程序
你刚刚创建了函数并将其推送到 Azure。下一步是为你的一个 GitHub 存储库创建 Webhook。
设置 webhook
您想要为其中一个存储库设置一个 webhook,每次在该存储库中创建问题时都会触发该 webhook。
设置此 webhook 分为两个步骤。第一步是告诉 webhook 哪些事件应该触发它。第二步是告诉 webhook 应该将 HTTP 请求发送到哪个 URL。让我们逐步了解如何设置您的 webhook。
创建 webhook
让我们在您现有的一个存储库中创建 webhook。
- 使用您的网络浏览器登录您的GitHub 帐户。
- 导航到您的一个存储库。
- 选择“设置”选项卡。
- 从左侧菜单中选择webhook 。
- 按“添加 webhook”按钮为该存储库创建一个新的 webhook
- 将内容类型设置为applicaiton/json
接下来,你需要函数应用的 URL。该 URL 可以在 VS Code 中找到。
- 转到 Azure 函数扩展
- 展开函数应用和函数节点
- 右键单击您的“SayThankYou”功能
- 选择复制函数网址
- 返回到您正在设置 webhook 的浏览器
- 将您的 URL 粘贴到Payload URL字段中
- 选中单个事件复选框
- 选中“问题”复选框
- 保存 webhook
现在,你的 webhook 已经准备好在问题发生时触发调用。webhook 会将有效负载发送到你的函数,你的函数会读取有效负载,生成一条消息,然后使用 GitHub API 为该问题创建评论!
尝试一下
剩下要做的就是看看它是否有效。你应该前往你的代码库并创建一个 issue。webhook 会触发一个 HTTP 请求,并将一个有效负载传递给你的函数。你的函数会将一条新的评论写回你的 issue,你应该很快就能看到它了。
成功!
显示代码
您可以按照以下步骤从头开始尝试。您也可以直接跳到此处的代码解决方案。
如果您遇到困难,请在 repo 中打开一个问题。
下一步
通过免费培训了解有关无服务器的更多信息!
资源
我推荐这些资源,因为它们非常有助于解释所有关键要素。
-
Octokit - 用于 JavaScript和文档的 GitHub REST API 客户端
额外资源⭐️
一般来说,一些额外的很棒的无服务器资源如下。
- ✅ Azure Functions 文档
- ✅ Azure SDK for JavaScript 文档
- ✅使用 Visual Studio Code 创建你的第一个函数
- ✅免费电子书 - Azure 无服务器计算手册,第二版
想要提交你的解决方案来应对这项挑战吗?请在本地构建解决方案,然后提交问题。如果你的解决方案不涉及代码,你可以录制一段简短的视频,并将其作为问题描述中的链接提交。请务必告诉我们该解决方案针对的是哪个挑战。我们期待看到你的成果!你有任何意见或问题吗?请在下方评论区留言。
12月,我们将庆祝无服务器25天,惊喜不断,敬请关注。敬请关注dev.to,我们将带来挑战和解决方案!立即注册Azure免费帐户,准备迎接挑战!
鏂囩珷鏉ユ簮锛�https://dev.to/azure/automate-your-replies-to-github-issues-5280