tambah webhook
This commit is contained in:
132
public/webhook.php
Normal file
132
public/webhook.php
Normal file
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
/**
|
||||
* Gitea Webhook Handler
|
||||
*
|
||||
* URL: https://your-domain.com/webhook.php
|
||||
* Gitea Content-Type: application/json
|
||||
* Gitea Secret: nilai WEBHOOK_SECRET dalam .env
|
||||
* Gitea Events: Push Events
|
||||
*/
|
||||
|
||||
define('APP_ROOT', dirname(__DIR__));
|
||||
define('LOG_FILE', APP_ROOT . DIRECTORY_SEPARATOR . 'storage' . DIRECTORY_SEPARATOR . 'logs' . DIRECTORY_SEPARATOR . 'webhook.log');
|
||||
|
||||
function log_msg(string $message): void
|
||||
{
|
||||
$line = '[' . date('Y-m-d H:i:s') . '] ' . $message . PHP_EOL;
|
||||
file_put_contents(LOG_FILE, $line, FILE_APPEND | LOCK_EX);
|
||||
}
|
||||
|
||||
function respond(int $code, string $message): never
|
||||
{
|
||||
http_response_code($code);
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode(['status' => $code, 'message' => $message]);
|
||||
exit;
|
||||
}
|
||||
|
||||
function read_env(string $key, string $default = ''): string
|
||||
{
|
||||
static $env = null;
|
||||
if ($env === null) {
|
||||
$env = [];
|
||||
$file = APP_ROOT . DIRECTORY_SEPARATOR . '.env';
|
||||
if (file_exists($file)) {
|
||||
foreach (file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) as $line) {
|
||||
$line = trim($line);
|
||||
if ($line === '' || str_starts_with($line, '#')) {
|
||||
continue;
|
||||
}
|
||||
if (str_contains($line, '=')) {
|
||||
[$k, $v] = explode('=', $line, 2);
|
||||
$env[trim($k)] = trim($v, " \t\"'");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $env[$key] ?? (getenv($key) ?: $default);
|
||||
}
|
||||
|
||||
// ── Hanya terima POST ────────────────────────────────────────────────────────
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
respond(405, 'Method Not Allowed');
|
||||
}
|
||||
|
||||
$payload = file_get_contents('php://input');
|
||||
if (empty($payload)) {
|
||||
respond(400, 'Empty payload');
|
||||
}
|
||||
|
||||
// ── Sahkan signature Gitea ───────────────────────────────────────────────────
|
||||
$secret = read_env('WEBHOOK_SECRET');
|
||||
if (!empty($secret)) {
|
||||
$signature = $_SERVER['HTTP_X_GITEA_SIGNATURE'] ?? '';
|
||||
$expected = hash_hmac('sha256', $payload, $secret);
|
||||
|
||||
if (!hash_equals($expected, $signature)) {
|
||||
log_msg('WARN: Signature tidak sah dari IP ' . ($_SERVER['REMOTE_ADDR'] ?? 'unknown'));
|
||||
respond(403, 'Invalid signature');
|
||||
}
|
||||
}
|
||||
|
||||
// ── Parse payload ────────────────────────────────────────────────────────────
|
||||
$data = json_decode($payload, true);
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
respond(400, 'Invalid JSON payload');
|
||||
}
|
||||
|
||||
$event = $_SERVER['HTTP_X_GITEA_EVENT'] ?? 'unknown';
|
||||
$ref = $data['ref'] ?? '';
|
||||
$branch = basename($ref);
|
||||
$pusher = $data['pusher']['login'] ?? 'unknown';
|
||||
$commitId = substr($data['after'] ?? '', 0, 8);
|
||||
|
||||
log_msg("Event: $event | Branch: $branch | Pusher: $pusher | Commit: $commitId");
|
||||
|
||||
// ── Hanya deploy pada push ke master/main ───────────────────────────────────
|
||||
$targetBranch = read_env('WEBHOOK_BRANCH', 'master');
|
||||
if ($event !== 'push' || $branch !== $targetBranch) {
|
||||
respond(200, "Skipped — event=$event branch=$branch (target=$targetBranch)");
|
||||
}
|
||||
|
||||
// ── Jalankan deployment script ───────────────────────────────────────────────
|
||||
$deployScript = APP_ROOT . '\\scripts\\deploy.ps1';
|
||||
$deployLog = APP_ROOT . '\\storage\\logs\\deploy-' . date('Ymd-His') . '.log';
|
||||
|
||||
if (!file_exists($deployScript)) {
|
||||
log_msg('ERROR: Deploy script tidak dijumpai: ' . $deployScript);
|
||||
respond(500, 'Deploy script not found');
|
||||
}
|
||||
|
||||
$command = sprintf(
|
||||
'powershell.exe -NonInteractive -ExecutionPolicy Bypass -File "%s" > "%s" 2>&1',
|
||||
$deployScript,
|
||||
$deployLog
|
||||
);
|
||||
|
||||
log_msg("Menjalankan: $command");
|
||||
|
||||
$descriptors = [
|
||||
0 => ['pipe', 'r'],
|
||||
1 => ['file', $deployLog, 'a'],
|
||||
2 => ['file', $deployLog, 'a'],
|
||||
];
|
||||
|
||||
$process = proc_open($command, $descriptors, $pipes, APP_ROOT);
|
||||
|
||||
if (!is_resource($process)) {
|
||||
log_msg('ERROR: Gagal memulakan proses deployment');
|
||||
respond(500, 'Failed to start deployment process');
|
||||
}
|
||||
|
||||
fclose($pipes[0]);
|
||||
$exitCode = proc_close($process);
|
||||
|
||||
log_msg("Deployment selesai — exit code: $exitCode | log: $deployLog");
|
||||
|
||||
if ($exitCode === 0) {
|
||||
respond(200, "Deployment berjaya — commit $commitId");
|
||||
} else {
|
||||
respond(500, "Deployment gagal — exit code $exitCode, semak $deployLog");
|
||||
}
|
||||
Reference in New Issue
Block a user