前言

之前受某位友链大佬针对搜索引擎解析域名文章思路的启发,用闲置的小水管机做了个搜索引擎喂料方案。

为了图省事,直接用的 Windows 系统定时任务运行自动克隆代码仓库BAT,按固定的时间无脑从 GitHub 克隆仓库后发布。这样的方案确实省事,但也没法办法及时同步仓库中最新代码,因为还有个地方会自动将最新链接提交搜索引擎,这期间存在更新时间差,而且无更新时浪费小水管机流量资源。

故近日在小水管机上又加了个 webhook 监听程序,实现按需无时差同步代码。

需要用到的组件

  1. webhook监听服务端:开源Go项目 webhook,可自行编译也可以直接下载对应二进制程序
  2. Windows服务管理:这里用的 Windows Service Wrapper,见后文参考链接,不用第三方用 Windows 自己的服务注册方式也是可以的,目的只是为了将程序注册成系统服务守护,能实现目的就行
  3. 端口测试「可选」:telnet 或者 tcping 之类的都行

功能实现流程

sequenceDiagram
  actor Git客户端
  Git客户端->>GitHub仓库: git push
  GitHub仓库->>webhook监听端: 触发webhook
  webhook监听端->>BAT: 运行预定程序
  Note right of BAT: 自动 pull/clone及发布
  webhook监听端-->>GitHub仓库: 返回webhook结果
  GitHub仓库-->>Git客户端: git pull

Windows Server 部署 webhook 监听服务

本来要实现自动按需更新部署的功能在 LInux 服务器上很容易就实现,这部分可见本站早期教程:Hexo博客Git-VPS部署完整记录

或者可以安装个宝塔之类的再借助扩展功能也能容易实现,在纯 Windows Server 上稍微复杂一点,下面是实现步骤。

获取 webhook 监听程序

使用开源 Go 项目 webhook,可以自己编译,也可以直接下载作者已经编译好的二进制版本,Windows 下载 webhook-windows-amd64.tar.gz 解压到某个路径,如:C:\inetpub\webhook\webhook.exe

配置监听端 webhook.xml

监听端就是我们要部署在我们自己 Windows Server 上的服务,webhook.xml 中定义监听接口数据来源,对接口令,匹配条件等,以下是一个最简单的样本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
- id: auto-git
execute-command: "C:/inetpub/auto-git.bat" # 要执行的程序
command-working-directory: "C:/inetpub" # 执行程序工作目录
response-message: Got the payload! # 执行后返回给发起端的信息
response-headers:
- name: Access-Control-Allow-Origin
value: '*'
incomingpayload-content-type: application/json
trigger-rule:
and:
- match:
type: payload-hmac-sha1
secret: "YOURSECRET" # 设置一个对接口令
parameter:
source: header
name: X-Hub-Signature
- match:
type: value
value: refs/heads/main # 触发这个webhook的来源分支名
parameter:
source: payload
name: ref

以上是 yaml 格式样板,JSON 格式大同小异,注意执行程序路径使用 / 符号,否则会有一个错误,要执行的 BAT 可见本站另外教程:一个BAT批处理实现HTML网页自动同步发布到Windows Server

运行 webhook 测试

以上配置完成后,打开 powershellcmd,执行以下命令:

1
2
3
4
# cmd 不同盘符切换路径需带 /d 参数
cd C:\inetpub\webhook\
# 切换到程序所在路径
webhook.exe -hooks webhook.yaml -verbose

如果开启了 Windows defender 防火墙,默认会提示是否放行 webhook.exe,如果没提示请在防火墙中添加程序或者 TCP: 9000 端口允许入站连接,控制台将显示如下结果,表示监听配置没错,这个 webhook 服务就搭建成功了:

1
2
3
4
5
[webhook] 2024/05/17 08:19:55 version 2.8.1 starting
[webhook] 2024/05/17 08:19:55 attempting to load hooks from webhook.yaml
[webhook] 2024/05/17 08:19:55 found 1 hook(s) in file
[webhook] 2024/05/17 08:19:55 loaded: auto-git
[webhook] 2024/05/17 08:19:55 serving hooks on http://0.0.0.0:9000/hooks/{id}

hook 地址中的 {id} 为配置监听端 webhook.xml 中定义的 auto-git,假设 Windows Server 服务器公网 IP 为 1.2.4.8 或者将域名 x.y.z 解析到了该公网 IP,那么我们这个服务器上完整的 webhook 调用地址可以为:

  • http://1.2.4.8:9000/hooks/auto-git
  • http://x.y.z:9000/hooks/auto-git

在外网调用时,一般还需要在云服务器控制台安全组中放行 TCP: 9000 端口,然后在调用端使用以上 webhook 地址中的任何一个都可以。

测试端口是否正常可用 tcping

1
2
PS C:\Users\xxx> tcping x.y.z 9000
Ping tcp://x.y.z:9000(1.2.4.8:9000) - Connected - time=48.4695ms

此处如果控制台输出中文乱码,可以运行 chcp 65001 再启动 webhook 监听查看,
65001 代表编码方式为 utf-8,更多可以查看文末参考链接

注册系统服务守护

监听服务运行没问题那基本上可以注册成服务守护来运行监听了,这里使用 Windows Service Wrapper 来完成。

直接在项目仓库 release 中找到 WinSW-x64.exe 下载到我们的 Windows Server 上,比如放到 webhook 同目录并改个顺眼的名字:webhookservice.exe,新建同名配置:webhookservice.xml

1
2
3
4
5
6
7
8
9
<service>
<id>auto-git</id>
<name>WebHook</name>
<description>GitHub WebHook</description>
<executable>C:\inetpub\webhook\webhook.exe</executable>
<arguments>-hooks webhook.yaml -verbose</arguments>
<logmode>reset</logmode>
<onfailure action="restart" />
</service>

配置保存后运行安装服务命令:webhookservice.exe install 就会将 C:\inetpub\webhook\webhook.exe 安装成服务,并且带参数 -hooks webhook.yaml -verbose 启动。

启动后会在同目录下生成几个对应日志文件,可以自行查看服务运行状态及调用记录。

webhookservice.exe 可以管理该服务,其命令参数如下:

Command Description
install Installs the service.
uninstall Uninstalls the service.
start Starts the service.
stop Stops the service.
restart Stops and then starts the service.
status Checks the status of the service.
refresh Refreshes trties without reinstallation.
customize Customizes the wrapper executable.
dev Experimental commands.

配置 webhook 调用端

如前文所示,该 webhook 目的就是为了 GitHub 仓库自动同步,我们自己 Windows Server 上 webhook 监听服务已经万事俱备。

接下来需要打开 GitHub 上要触发 webhook 的仓库 settingWebhooks》点击右上角的 add webhook:新增一个 webhook 调用:

GitHub添加调用端webhook

  • Payload URL:指向服务器的域名或者直接IP,前文提到的 webhook 地址
  • Content type:选择 application/json
  • Secret:设置的口令,需与监听端配置的相同

添加 webhook 后,默认会触发一次测试调用,Response 200 表示调用成功。至此,整套 hook 环节已经全部打通。

系统运行结果

在 GitHub 仓库 webhooks 列表中,可见每个 webhook 的调用结果,点击某个进入管理界面,可见 Recent Deliveries,这里保存了每一次的调用记录:

1
2
3
4
5
6
7
8
Headers
Access-Control-Allow-Origin: *
Content-Length: 16
Content-Type: text/plain; charset=utf-8
Date: Fri, 17 May 2024 00:02:14 GMT

Body
Got the payload!

如果失败,也可以查看具体的失败代码,Response 502 表示服务端异常,可以用上文提到的方法测试查找问题所在。

参考链接

  1. webhook
  2. Windows Service Wrapper
  3. windows+webhook+github自动化部署
  4. 让Windows程序运行为服务
  5. 怎样解决CMD命令行窗口中文乱码问题