Git post-接收挂钩不适用于 Github

Git post-receive hook doesn't work with Github

背景和设置

我正在尝试按照 the last part of this tutorial here 创建一个 post-receive Git 挂钩(实际上只是一个例子,其他地方的说明基本相同)。

除了我的本地存储库之外,我还有一个 GitHub 存储库设置为一个名为 central 的远程服务器,还有一个生产服务器设置为一个名为远程服务器的远程服务器直播。 我已准备好一切,以便能够轻松地从本地存储库推送到 GitHub,并通过 SSH 进入生产服务器以从 GitHub 中提取。

目标

我想完全取消后一步,这样我需要做的就是推送到中央存储库,生产服务器将从那里自动提取这些更改——我所看到的一切都告诉我post-receive hook 是执行此操作的方法。

问题

出于某种原因,到目前为止我为使 post-receive 挂钩正常工作所做的所有尝试都失败了。

我的 post-receive 文件存在于我的生产服务器 .git/hooks/ 中,它已通过 chmod ug+x 变为可执行文件,是的,"post-receive" 拼写正确。 post-receive 文件包含以下 Bash 代码:

#!/bin/sh
cd ~/www.example.com/public_html || exit
unset GIT_DIR
git pull central master
exec git update-server-info

我什至可以通过 SSH 进入生产服务器并手动执行 post-receive 挂钩,但由于某种原因,当我推送到中央存储库时它没有被触发,尽管 事实上,所有指南都指定这是它应该工作的方式。

我与这些指南不同的唯一方法是我服务器上的存储库是一个非裸存储库,但从我了解到的两者之间的差异来看,这应该没有什么区别已经确定我可以正常推拉。

那么为什么我的 post-receive 挂钩不起作用?

编辑:测试 1

cd 行更改为:

cd ~/www.example.com/public_html && touch ./cd_ran_successfully || exit

...然后在本地执行 push 命令不会在服务器上创建任何 cd_ran_successfully 文件。但是,在登录到服务器时手动执行该文件确实会创建该文件。这表明共享服务器用于执行文件的 user/process 存在某种问题,但除此之外我不知道。

post-receive hook 是服务器端 hook,它需要在您的 git 服务器上。

通常,要 运行 自定义挂钩,您需要托管自己的 git 服务器。从听起来像你想要的,你需要设置你的生产服务器来托管一个 git 服务器,你可以将它设置为一个不同的 git 远程,你可以推送到。

然后您可以设置 post-receive 以根据需要部署文件。

或者,您可以设置一个预推送脚本,让您的产品服务器知道有更新可用,尽管它很老套。

预推:

#!/usr/bin/env bash

ssh user@prod "/home/user/my_script.sh &"

my_script.sh

#!/usr/bin/env bash

# Wait for push to go through
sleep(25)

cd git_dir && git pull

# Deploy
cp git_dir/binary /usr/bin/

正如 jpsalm 所指出的,Git 挂钩只能在 Git 服务器上 运行,这在托管网站和 CMS 时通常不会设置,例如Wordpress,尤其是在 root 访问不太可能的共享服务器上。 Github 没有使用 Git 的钩子,而是实现了自己的技术版本 webhooks

N.B。下面所学的都是我最近几个小时研究的结果,这个回答主要是为了巩固这些知识,让我觉得时间并没有完全浪费。

Webhooks 是一种与 APIs 非常相似的技术 - 其中 API 功能是提供用户请求的数据,webhooks 似乎以相反的方式工作:它们监听指定的服务器上的更改并将这些更改通知用户。

通常应用于 Git 和 Github,webhook 侦听 Github 的事件,例如 git push,然后发送 POST 向 端点 请求包含该事件的所有详细信息。这个端点是服务器上的一个脚本,用于从 POST 请求中解析 JSON,检查身份验证,然后在服务器上执行另一个实际做某事的脚本——最常见的是,从 Git集线器回购。

Github 通过提供一个 Web 界面来创建请求,从而消除了 Webhooks 的一些痛苦,但这仍然保留了端点本身(Github 混淆地调用了有效载荷,我仍然没有得到)进行编程,除了端点将 运行s.

的脚本

不幸的是,我没有时间编写用于用 Bash 或任何其他语言解析 JSON 的端点,所以直到有人出现并做就是这样,看来我将不得不满足于执行一个额外的 push 命令。 :)