介绍
在与多个开发人员一起工作时,当一个人推到一个存储库,然后另一个人开始对代码的过时版本进行更改时,可能会令人沮丧。
虽然有其他解决方案来完成这个特定的任务,但写自己的脚本是一个灵活的选项,在未来留下了自定义空间。
GitHub允许您为您的存储库配置 webhooks,这些事件在事件发生时发送 HTTP 请求。
在本指南中,您将开发一个 Node.js服务器,每当您或其他人将代码推到 GitHub 时,都会听取 GitHub Webhook 通知。
前提条件
要完成本教程,您将需要:
- 一个 Ubuntu 16.04 服务器由 Ubuntu 16.04 初始服务器安装指南来设置,包括具有
sudo
特权和防火墙的非根用户。 - Git 安装在您的本地机器上。您可以按照教程 如何在 Ubuntu 16.04 上安装 Node.js:开始使用 Git来安装并在您的计算机上安装 Git。
- Node.js 和 'npm' 安装在远程服务器上,使用官方 PPA,如在 How To Install Node.js on Ubuntu 16.04中所解释的那样。 安装分散稳定版本就足够了,因为它为我们提供了没有任何额外配置的推荐版本。 _MK
步骤 1 - 设置一个 Webhook
这个步骤很重要,因为没有它,Github不知道在事情发生时要发送什么事件,或者在哪里发送它们。
登录您的 GitHub 帐户并导航到您想要监控的存储库。在存储库页面上顶部菜单栏中单击设置
选项卡,然后在左侧导航菜单中单击Webhooks
选项卡。在右侧单击添加 Webhook
选项卡,并在提示时输入您的帐户密码。
- 在 Payload URL字段中,输入
http://your_server_ip:8080
. 这是我们即将写的 Node.js 服务器的地址和端口。 - 将 Content type 更改为
application/json
. 我们要写的脚本将期待 JSON 数据,并且无法理解其他数据类型。 - 对于 Secret,为此 webhook 输入秘密密密密码。 您将在您的 Node.js 服务器中使用此秘密来验证请求并确保它们来自 GitHub。
- 对于您想要触发此 webhook 的事件,只需选择 ** push 事件**. 我们只需要推动事件,因为它是当代码更新并需要
ping 最初会失败,但请放心您的 webhook 现在已经配置了,现在让我们把存储库克隆到服务器上。
步骤 2 – 将存储库克隆到服务器
我们的脚本可以更新一个存储库,但它不能处理最初的存储库设置,所以我们现在会这样做。
1[environment local]
2ssh sammy@your_server_ip
确保你在您的主目录中,然后使用Git来克隆您的存储库,请确保用您的GitHub用户名替换sammy
,用您的Github项目名称替换hello_hapi
。
1cd
2git clone https://github.com/sammy/hello_hapi.git
这将创建一个包含您的项目的新目录,您将在下一步使用该目录。
随着项目的克隆,您可以创建 webhook 脚本。
步骤 3 – 创建 Webhook 脚本
让我们创建我们的服务器来聆听那些来自GitHub的webhook请求,我们将写一个Node.js脚本,在端口8080
上启动一个Web服务器,服务器将聆听来自webhook的请求,验证我们指定的秘密,并从GitHub中提取最新版本的代码。
导航到您的家庭目录:
1cd ~
创建一个名为NodeWebhooks
的webhook脚本的新目录:
1mkdir ~/NodeWebhooks
然后导航到新目录:
1cd ~/NodeWebhooks
在NodeWebhooks
目录中创建一个名为webhook.js
的新文件。
1nano webhook.js
将这两个行添加到脚本中:
1[label webhook.js]
2var secret = "your_secret_here";
3var repo = "/home/sammy/hello_hapi";
第一行定义了一个变量,以保持您在步骤 1 中创建的秘密,该变量验证了请求来自GitHub。第二行定义了一个变量,该变量持有您想在本地磁盘上更新的完整路径。
接下来,添加这些行,将http
和crypto
库导入脚本中,我们将使用这些来创建我们的Web服务器,并哈希秘密,以便我们可以将其与我们从GitHub获得的内容进行比较:
1[label webhook.js]
2let http = require('http');
3let crypto = require('crypto');
接下来,包括child_process
库,以便您可以从脚本中执行壳命令:
1[label webhook.js]
2const exec = require('child_process').exec;
接下来,添加此代码来定义一个新的 Web 服务器,该服务器处理 GitHub Webhook 请求,并将新版本的代码拉下,如果是真实的请求:
1[label webhook.js]
2http.createServer(function (req, res) {
3 req.on('data', function(chunk) {
4 let sig = "sha1=" + crypto.createHmac('sha1', secret).update(chunk.toString()).digest('hex');
5
6 if (req.headers['x-hub-signature'] == sig) {
7 exec('cd ' + repo + ' && git pull');
8 }
9 });
10
11 res.end();
12}).listen(8080);
http.createServer()
函数在端口8080
上启动一个Web服务器,它会听取来自Github的入口请求,为了安全目的,我们验证请求中包含的秘密与我们在步骤 1中创建Webhook时所指定的秘密相匹配,秘密被传递到x-hub-签名
标题中作为一个SHA1加密字符串,所以我们将我们的秘密加密,并将其与GitHub发送给我们的内容进行比较。
如果请求是真实的,我们执行一个壳命令以使用git pull
更新我们的本地存储库。
完成的剧本看起来像这样:
1[label webhook.js]
2const secret = "your_secret_here";
3const repo = "~/your_repo_path_here/";
4
5const http = require('http');
6const crypto = require('crypto');
7const exec = require('child_process').exec;
8
9http.createServer(function (req, res) {
10 req.on('data', function(chunk) {
11 let sig = "sha1=" + crypto.createHmac('sha1', secret).update(chunk.toString()).digest('hex');
12
13 if (req.headers['x-hub-signature'] == sig) {
14 exec('cd ' + repo + ' && git pull');
15 }
16 });
17
18 res.end();
19}).listen(8080);
如果您遵循初始服务器设置指南,则需要允许该 Web 服务器通过允许对端口 8080
的流量与外部 Web 进行通信:
1sudo ufw allow 8080/tcp
现在我们的脚本已经到位,让我们确保它正常工作。
步骤 4 - 测试 Webhook
我们可以通过使用节点
来测试我们的webhook,在命令行中运行它。
1cd ~/NodeWebhooks
2nodejs webhook.js
返回您的项目页面在 Github.com。 点击您的库存页面上顶部菜单栏中的设置
卡,然后点击Webhooks
在左导航菜单中。
按一下右边的三个点,以显示 Redeliver按钮. 当节点服务器运行时,点击 Redeliver 以再次发送请求。一旦您确认要发送请求,您将看到成功的响应。
我们现在可以继续确保我们的脚本在背景中运行,并在启动时开始使用CTRL+C
来阻止节点webhook服务器。
步骤 5 — 安装 Webhook 作为 Systemd 服务
systemd是Ubuntu使用的任务管理器来控制服务,我们将设置一个服务,允许我们在启动时启动我们的webhook脚本,并使用systemd命令来管理它,就像我们在任何其他服务中一样。
创建一个新的服务文件:
1sudo nano /etc/systemd/system/webhook.service
将下列配置添加到服务文件中,该文件告诉 systemd 如何运行脚本. 这告诉 Systemd 在哪里找到我们的节点脚本并描述我们的服务。
请确保用您的用户名替换sammy
。
1[label /etc/systemd/system/webhook.service]
2[Unit]
3Description=Github webhook
4After=network.target
5
6[Service]
7Environment=NODE_PORT=8080
8Type=simple
9User=sammy
10ExecStart=/usr/bin/nodejs /home/sammy/NodeWebhooks/webhook.js
11Restart=on-failure
12
13[Install]
14WantedBy=multi-user.target
启用新服务,以便在系统启动时启动:
1sudo systemctl enable webhook.service
现在开始服务:
1sudo systemctl start webhook
确保服务开始:
1sudo systemctl status webhook
您将看到以下输出,表示该服务正在运行:
1[secondary_label Output]
2● webhook.service - Github webhook
3 Loaded: loaded (/etc/systemd/system/webhook.service; enabled; vendor preset: enabled)
4 Active: active (running) since Fri 2018-08-17 19:28:41 UTC; 6s ago
5 Main PID: 9912 (nodejs)
6 Tasks: 6
7 Memory: 7.6M
8 CPU: 95ms
9 CGroup: /system.slice/webhook.service
10 └─9912 /usr/bin/nodejs /home/sammy/NodeWebhooks/webhook.js
您现在可以将新承诺推向您的存储库,并在您的服务器上查看更改。
从您的桌面计算机,克隆存储库:
1[environment local]
2git clone https://github.com/sammy/hello_hapi.git
对存储库中的任何一个文件进行更改,然后发起文件并将您的代码推到GitHub。
1[environment local]
2git add index.js
3git commit -m "Update index file"
4git push origin master
Webhook将启动,您的更改将出现在您的服务器上。
结论
您已经设置了一个 Node.js 脚本,该脚本将自动部署新的承诺到远程存储库. 您可以使用此过程来设置您想要监控的额外存储库。