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"}}' \ http://localhost/
安装
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