如何使用Node.js和Github Webhooks保持远程项目同步

介绍

在处理具有多个开发人员的项目时,当一个人推送到存储库然后另一个人开始对过时版本的代码进行更改时,这可能会令人沮丧。像这些花费时间的错误,这使得设置脚本以保持您的存储库同步是值得的。您还可以在生产环境中应用此方法以快速推送修补程序和其他更改。

虽然存在其他解决方案来完成此特定任务,但编写自己的脚本是一种灵活的选项,为将来的自定义留出了空间。

GitHub允许您为存储库配置webhook,这些事件是在事件发生时发送HTTP请求的事件。例如,您可以使用webhook在有人创建拉取请求或推送新代码时通知您。

在本指南中,您将开发一个Node.js服务器,只要您或其他人将代码推送到GitHub,它就会监听GitHub webhook通知。此脚本将使用最新版本的代码自动更新远程服务器上的存储库,从而无需登录服务器来提取新提交。

先决条件

要完成本教程,您需要:

  • 一个Ubuntu 16.04服务器按照Ubuntu 16.04初始服务器设置指南设置,包括具有sudo权限和防火墙的非root用户。没有服务器的同学可以在这里购买,不过我个人更推荐您使用免费的腾讯云开发者实验室进行试验,学会安装后再购买服务器。如果您使用的是腾讯云的CVM服务器,您可以直接在腾讯云控制台中的安全组进行设置。
  • 在本地计算机上安装Git。您可以按照教程如何在Ubuntu上安装Git在您的计算机上安装和设置Git。
  • 使用官方PPA将Node.js和npm安装在远程服务器上。安装distro-stable版本就足够了,因为它为我们提供了推荐的版本而无需任何其他配置。
  • Github上的一个存储库,包含您的项目代码。如果您没有考虑项目,请随意分享我们将在本教程的其余部分中使用的示例。

第1步 - 设置Webhook

我们首先为您的存储库配置webhook。这一步很重要,因为没有它,Github不知道发生事件时要发送什么事件,或者发送它们的位置。我们将首先创建webhook,然后创建将响应其请求的服务器。

登录您的GitHub帐户并导航到您要监控的存储库。单击存储库页面顶部菜单栏中的“设置”选项卡,然后单击左侧导航菜单中的“ Webhooks ”。单击右上角的添加Webhook,然后在出现提示时输入您的帐户密码。你会看到一个如下所示的页面:

  • Payload URL字段中,输入http://your_server_ip:8080。这是我们即将编写的Node.js服务器的地址和端口。
  • 内容类型更改为application/json。我们将编写的脚本将需要JSON数据,并且无法理解其他数据类型。
  • 对于Secret,请输入此webhook的密码。您将在Node.js服务器中使用此秘密来验证请求并确保它们来自GitHub。
  • 对于您想要触发此webhook 的事件,请选择推送事件。我们只需要push事件,因为那时代码已更新并需要同步到我们的服务器。
  • 选中“ 活动”复选框。
  • 查看字段,然后单击添加webhook以创建它。

ping将首先失败,但请放心,您的webhook现已配置完毕。现在让我们将存储库克隆到服务器。

第2步 - 将存储库克隆到服务器

我们的脚本可以更新存储库,但它最初无法处理设置存储库,所以我们现在就这样做。登录您的服务器:

ssh sammy@your_server_ip

确保您在主目录中。然后使用Git克隆您的存储库。请务必使用您的GitHub用户名替换sammy,然后用Github项目的名称替换hello_hapi

cd
git clone https://github.com/sammy/hello_hapi.git

这将创建一个包含项目的新目录。您将在下一步中使用此目录。

克隆项目后,您可以创建webhook脚本。

第3步 - 创建Webhook脚本

让我们创建我们的服务器来监听来自GitHub的那些webhook请求。我们将编写一个Node.js脚本,用于在端口8080上启动Web服务器。服务器将侦听来自webhook的请求,验证我们指定的秘密,并从GitHub中提取最新版本的代码。

导航到您的主目录:

cd ~

为您的webhook脚本创建一个名为NodeWebhooks的新目录:

mkdir ~/NodeWebhooks

然后导航到新目录:

cd ~/NodeWebhooks

NodeWebhooks目录内部创建一个名为webhook.js的新文件。

nano webhook.js

将这两行添加到脚本中:

var secret = "your_secret_here";
var repo = "/home/sammy/hello_hapi";

第一行定义了一个变量来保存您在步骤1中创建的秘密,该变量验证请求来自GitHub。第二行定义了一个变量,该变量包含要在本地磁盘上更新的存储库的完整路径。这应该指向您在步骤2中签出的存储库。

接下来,添加将这些将httpcryptolibaries导入脚本的这些行。我们将使用这些来创建我们的Web服务器并散列秘密,以便我们可以将它与我们从GitHub收到的内容进行比较:

let http = require('http');
let crypto = require('crypto');

接下来,包含child_process库,以便您可以从脚本执行shell命令:

const exec = require('child_process').exec;

接下来,添加此代码以定义处理GitHub webhook请求的新Web服务器,如果它是真实的请求,则下拉新版本的代码:

http.createServer(function (req, res) {
    req.on('data', function(chunk) {
        let sig = "sha1=" + crypto.createHmac('sha1', secret).update(chunk.toString()).digest('hex');
​
        if (req.headers['x-hub-signature'] == sig) {
            exec('cd ' + repo + ' && git pull');
        }
    });
​
    res.end();
}).listen(8080);

http.createServer()函数在端口8080上启动Web服务器,该服务器侦听来自Github的传入请求。出于安全目的,我们验证请求中包含的秘密与我们在步骤1中创建webhook时指定的秘密相匹配。秘密作为SHA1散列字符串在x-hub-signature头中传递,因此我们将我们的秘密哈希并将其与GitHub发送给我们。

如果请求是可信的,我们执行shell命令来使用git pull更新本地存储库。

完成的脚本如下所示:

const secret = "your_secret_here";
const repo = "~/your_repo_path_here/";
​
const http = require('http');
const crypto = require('crypto');
const exec = require('child_process').exec;
​
http.createServer(function (req, res) {
    req.on('data', function(chunk) {
        let sig = "sha1=" + crypto.createHmac('sha1', secret).update(chunk.toString()).digest('hex');
​
        if (req.headers['x-hub-signature'] == sig) {
            exec('cd ' + repo + ' && git pull');
        }
    });
​
    res.end();
}).listen(8080);

如果您遵循初始服务器设置指南,则需要允许此Web服务器通过允许端口8080上的流量与外部Web通信:

sudo ufw allow 8080/tcp

现在我们的脚本已经到位,让我们确保它正常工作。

第4步 - 测试Webhook

我们可以使用node在命令行中运行它来测试我们的webhook 。启动脚本并在终端中打开进程:

cd ~/NodeWebhooks
nodejs webhook.js

返回Github.com上的项目页面。单击存储库页面顶部菜单栏中的“设置”选项卡,然后单击左侧导航菜单中的“ Webhooks ”。单击您在步骤1中设置的webhook旁边的编辑。向下滚动,直到看到Recent Exiveries部分,如下图所示:

按下最右边的三个点以显示Redeliver按钮。在节点服务器运行的情况下,单击“ Redeliver ”再次发送请求。一旦确认要发送请求,您将看到成功的响应。重新启动ping后,响应代码200 OK将会表示这一点。

我们现在可以继续确保我们的脚本在后台运行并在启动时启动。使用CTRL+C来停止节点webhook服务器。

步骤5 - 将Webhook安装为Systemd服务

systemd是Ubuntu用来控制服务的任务管理器。我们将设置一个服务,允许我们在启动时启动webhook脚本,并使用systemd命令来管理它,就像我们使用任何其他服务一样。

首先创建一个新的服务文件:

sudo nano /etc/systemd/system/webhook.service

将以下配置添加到服务文件,该文件告诉systemd如何运行脚本。这告诉Systemd在哪里找到我们的节点脚本并描述我们的服务。

请务必使用您的用户名替换sammy

[Unit]
Description=Github webhook
After=network.target
​
[Service]
Environment=NODE_PORT=8080
Type=simple
User=sammy
ExecStart=/usr/bin/nodejs /home/sammy/NodeWebhooks/webhook.js
Restart=on-failure
​
[Install]
WantedBy=multi-user.target

启用新服务,以便在系统引导时启动:

sudo systemctl enable webhook.service

现在开始服务:

sudo systemctl start webhook

确保服务已启动:

sudo systemctl status webhook

您将看到以下输出,指示该服务处于活动状态:

● webhook.service - Github webhook
   Loaded: loaded (/etc/systemd/system/webhook.service; enabled; vendor preset: enabled)
   Active: active (running) since Fri 2018-08-17 19:28:41 UTC; 6s ago
 Main PID: 9912 (nodejs)
    Tasks: 6
   Memory: 7.6M
      CPU: 95ms
   CGroup: /system.slice/webhook.service
           └─9912 /usr/bin/nodejs /home/sammy/NodeWebhooks/webhook.js

您现在可以将新提交推送到存储库并查看服务器上的更改。

从桌面计算机克隆存储库:

git clone https://github.com/sammy/hello_hapi.git

对存储库中的一个文件进行更改。然后提交文件并将代码推送到GitHub。

git add index.js
git commit -m "Update index file"
git push origin master

webhook将触发,您的更改将显示在您的服务器上。

结论

您已经设置了一个Node.js脚本,该脚本将自动将新提交部署到远程存储库。您可以使用此过程来设置您要监视的其他存储库。您甚至可以将其配置为在推送存储库时将网站或应用程序部署到生产环境。

更多Ubuntu教程请前往腾讯云+社区学习更多知识。


参考文献:《How to Use Node.js and Github Webhooks to Keep Remote Projects in Sync》

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏散尽浮华

Linux操作系统启动流程梳理

接触linux系统运维已经好几年了,常常被问到linux系统启动流程问题,刚好今天有空来梳理下这个过程: 一般来说,所有的操作系统的启动流程基本就是: ? 总的...

2878
来自专栏北京马哥教育

汇总:Linux文件管理的50个命令

文 | 糖豆 图 | 来源网络 糖豆贴心提醒,本文阅读时间6分钟,文末有秘密! Linux cat命令 cat 命令用于连接文件并打印到标准输出设备上...

5156
来自专栏影子

linux下svn(subversion)服务端添加工程及配置权限

转载请注明源地址:http://www.cnblogs.com/funnyzpc/p/9010507.html

1161
来自专栏猿人谷

mac下使用github

      提起github相信大家都不会陌生,在这里就不再赘述了。作为开源代码库以及版本控制系统,使用好了确实会非常受益,再说的势利点,你找工作时给面试官说你...

2085
来自专栏KK的小酒馆

用aliyun的Maven仓库下载Android Studio内依赖包

从GitHub导入新项目时,总是在gradle运行中卡壳,各种依赖包无法从jcenter或者Maven仓库下载下来,公司网也差……一上午就这么废了。 如果你也...

1222
来自专栏Timhbw博客

Android环境搭建,Android SDK下载

安装JDK和Eclipse 安装Android SDK 安装ADT插件 最后收尾 目录 由于国内环境原因,Android开发环境搭建比较麻烦,在这里给出...

4098
来自专栏yukong的小专栏

基于SpringCloud Finchley.SR1 、Spring Oauth2 SpringBoot 2.x、 vue、element-ui 微服务基础脚手架

github 地址 跪求大家star panda微服务工程地址 panda-admin前台工程地址

5993
来自专栏乐百川的学习频道

用TeamCity实现npm项目的自动部署

TeamCity是Jetbrains的持续集成工具,免费使用的话可以设置20个构建脚本,对于我们个人来说基本上是够用了。当然假如以后超过限制了,可以考虑使用另一...

3459
来自专栏蓝天

limits.conf

SuSE上的一些问题,可能需要另参考:http://blog.chinaunix.net/u2/64804/showart.php?id=2026903

721
来自专栏SpringBoot 核心技术

SpringCloud组件:Eureka服务注册是采用主机名还是IP地址?

我们一直在使用Eureka进行注册服务,然而你有可能很少关心服务在注册到Eureka Server时是采用的主机名的方式?还是IP地址的方式?

2621

扫码关注云+社区

领取腾讯云代金券