8ctopus / git-hook
自动化GitHub和Gitea的git推送部署
3.0.1
2024-03-07 07:25 UTC
Requires
- php: >=8.0
- ext-mbstring: *
- psr/http-message: ^1.0|^2.0
- psr/log: ^1.1.4|^2.0|^3.0
Requires (Dev)
- 8ctopus/apix-log: ^1.0|^2.0|^3.0
- friendsofphp/php-cs-fixer: ^3.4
- httpsoft/http-message: ^1.1
- httpsoft/http-server-request: ^1.0
- phpmd/phpmd: ^2.11
- phpstan/phpstan: ^1.4
- phpunit/phpunit: ^9.0|^10.0
Replaces
- 8ctopus/gitea-hook: *
README
使用webhooks自动化GitHub和Gitea的git推送部署。
自动将git仓库更改推送到任何网站。
演示
- 克隆仓库
- 启动本地PHP开发服务器:
php -S localhost:80 demo.php - 运行curl请求以模拟webhook请求
curl \
--request POST \
--header "content-type: application/json" \
--header "X-HUB-SIGNATURE-256: 2d8e4a6f3114e41f09a65195b2d69b5844e7a1a9284cdb2671354568304dd7a6" \
--data '{"ref":"refs/heads/master", "before":"fc7fc95de2d998e0b41e17cfc3442836bbf1c7c9", "after": "fc7fc95de2d998e0b41e17cfc3442836bbf1c7c9", "total_commits":1, "repository":{"name": "site"}}' \
https:///
安装
composer require 8ctopus/git-hook
GitHub使用方法
- 在网站公开部分创建一个新页面,例如这个页面(在这个例子中
https://example.com/api/myhook/index.php)
use Apix\Log\Logger\File; use HttpSoft\ServerRequest\ServerRequestCreator; use Oct8pus\GitHubHook; // assuming script is in DOCUMENT_ROOT/public/api/myhook/index.php $documentRoot = __DIR__ . '/../../..'; require_once $documentRoot . '/vendor/autoload.php'; $commands = [ // repository name eg. https://github.com/8ctopus/site 'site' => [ // directory in which commands will be executed 'path' => $documentRoot, 'commands' => [ // adjust to your flavor '/usr/bin/git pull', '/usr/local/bin/composer install --no-interaction --no-dev', ], ], ]; // the logger is optional but provides useful information (any PSR-3 logger will do) // to use this logger, composer require 8ctopus/apix-log $logger = new File(sys_get_temp_dir() . '/git-hook-' . date('Y-m-d-His') . '.log'); try { $logger->info('Git hook...'); $request = ServerRequestCreator::createFromGlobals($_SERVER, $_FILES, $_COOKIE, $_GET, $_POST); (new GitHubHook($request, $commands, 'SAME_SECRET_KEY_AS_IN_GITHUB_ADMIN', $logger)) ->run(); $logger->notice('Git hook - OK'); } catch (Exception $exception) { if ($exception->getCode() !== 0) { // informs the webhook that the command failed http_response_code($exception->getCode()); // REMOVE ME IN PRODUCTION echo $exception->getMessage(); } }
- 在GitHub项目中,转到
设置>Webhooks>添加webhook。 - 将
Payload URL设置为https://example.com/api/myhook/ - 将
Content type设置为application/json - 使用强密码设置
Secret(与脚本中的SAME_SECRET_KEY_AS_IN_GITHUB_ADMIN相同) - 设置
Just the push event - 勾选
Active - 点击
添加Webhook - 一旦添加,点击它并滚动到最底部以检查第一次投递。如果第一次投递成功,则设置完成。如果失败,请检查响应错误,并在修复后点击
重发。
注意:请参阅下面的重要说明。
Gitea使用方法
- 在网站公开部分创建一个新页面,例如这个页面(在这个例子中
https://example.com/api/myhook/index.php)
declare(strict_types=1); use Apix\Log\Logger\File; use HttpSoft\ServerRequest\ServerRequestCreator; use Oct8pus\GiteaHook; // assuming script is in DOCUMENT_ROOT/public/api/myhook/index.php $documentRoot = __DIR__ . '/../../..'; require_once $documentRoot . '/vendor/autoload.php'; $commands = [ 'site' => [ 'path' => $documentRoot, 'commands' => [ // adjust to your flavor '/usr/bin/git pull', '/usr/local/bin/composer install --no-interaction --no-dev', ], ], ]; // the logger is optional but provides useful information (any PSR-3 logger will do) // to use this logger, composer require 8ctopus/apix-log $logger = new File(sys_get_temp_dir() . '/git-hook-' . date('Y-m-d-His') . '.log'); try { $logger->info('Git hook...'); $request = ServerRequestCreator::createFromGlobals($_SERVER, $_FILES, $_COOKIE, $_GET, $_POST); (new GiteaHook($request, $commands, 'SAME_SECRET_KEY_AS_IN_GITEA_ADMIN', $logger)) ->run(); $logger->notice('Git hook - OK'); } catch (Exception $exception) { if ($exception->getCode() !== 0) { // informs the webhook that the command failed http_response_code($exception->getCode()); // REMOVE ME IN PRODUCTION echo $exception->getMessage(); } }
- 更新您的Gitea配置,以便允许将webhooks发送到您的域
[webhook] SKIP_TLS_VERIFY = false ALLOWED_HOST_LIST = example.com
- 在Gitea项目中,转到
设置,从添加webhook中选择Gitea。 - 将
Target URL设置为https://example.com/api/myhook/ - 将
HTTP Method设置为POST - 将
Post Content Type设置为application/json - 使用强密码设置
Secret(与脚本中的SAME_SECRET_KEY_AS_IN_GITEA_ADMIN相同) - 将
Trigger On设置为Push Events - 将
Branch filter设置为master或您想要触发脚本的任何分支 - 勾选
Active - 点击
添加Webhook - 一旦添加,点击它并滚动到最底部并点击
测试投递 - 如果投递成功,则设置完成。如果失败,请转到服务器并检查日志。
GitHub和Gitea的重要说明
注意:为了使使用用户 www-data(Apache通常运行在该用户下)的git pull工作,您可能需要
- 确保已设置上游,以便git知道从哪里拉取
git branch --set-upstream-to=origin/master master
- 确保用户
www-data是git仓库的所有者。如果不是,您将收到错误消息
[2023-05-05 16:23:21] ERROR fatal: detected dubious ownership in repository at '...'
注意:如果您对安全性较弱,您可以考虑授予用户 www-data 运行git作为另一个用户(如 ubuntu)的权限。这样,您的web服务器文件可以由 ubuntu 拥有,而 www-data 只能读取它们。我不是安全专家,所以请小心。
sudo -H -u ubuntu -- /usr/bin/git pull;
注意:为了使使用用户 www-data(Apache进程通常运行在该用户下)的git pull工作,您可能需要
- 在git remote url中包含用户和密码(必须进行url编码)
- git remote set-url origin https://user:password@example.com/gitea/site.git
回调
可以为每个命令或所有命令实现回调
$commands = [ 'site' => [ 'path' => $path, 'commands' => [ 'git status' => commandCallback(...), 'composer install --no-interaction', ], 'afterExec' => globalCallback(...), ], ];
这两个回调具有相同的签名
function callback(?LoggerInterface $logger, string $command, string $stdout, string $stderr, string $status) : bool
返回false将终止部署
调试
可以使用ngrok轻松地在本地调试部署脚本。
- 运行ngrok
ngrok http 80 - 将 Github 的
Payload URL或 Gitea 的Target URL更新为 ngrok 地址,类似于这个https://6daf-31-218-13-51.ngrok-free.app - 运行 PHP 本地服务器
php -S localhost:80 demo.php - 启动 Visual Studio Code 调试并设置
demo.php的断点 - 重新发送 webhook 请求
清理代码
composer fix(-risky)
phpstan
composer phpstan
phpmd
composer phpmd