Files
Investidor-V2/deploy/homologacao/webhook.php
T

42 lines
2.3 KiB
PHP

<?php
declare(strict_types=1);
// Nginx independently requires Basic on this exact endpoint. No portal identity is created.
$configFile = getenv('INVESTMOZ_DELIVERY_CONFIG') ?: '/etc/investmoz-deploy/delivery.json';
$config = json_decode((string) @file_get_contents($configFile), true);
if (!is_array($config)) { http_response_code(503); exit('Deployment configuration unavailable'); }
$secret = @file_get_contents($config['webhook_secret_file']);
if (!is_string($secret) || trim($secret) === '') { http_response_code(503); exit('Webhook unavailable'); }
$body = (string) file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_GITEA_SIGNATURE'] ?? $_SERVER['HTTP_X_GOGS_SIGNATURE'] ?? '';
if (!preg_match('/\A[0-9a-f]{64}\z/i', $signature)
|| !hash_equals(hash_hmac('sha256', $body, trim($secret)), strtolower($signature))) {
http_response_code(403); exit('Invalid signature');
}
$event = $_SERVER['HTTP_X_GITEA_EVENT'] ?? $_SERVER['HTTP_X_GOGS_EVENT'] ?? '';
if ($event !== 'push') { http_response_code(204); exit; }
$payload = json_decode($body, true);
if (!is_array($payload)) { http_response_code(400); exit('Invalid JSON'); }
if (($payload['repository']['full_name'] ?? '') !== $config['repository']
|| ($payload['ref'] ?? '') !== 'refs/heads/'.$config['branch']) {
http_response_code(204); exit;
}
$commit = strtolower((string) ($payload['after'] ?? ''));
if (!preg_match('/\A[0-9a-f]{40}\z/', $commit) || $commit === str_repeat('0', 40)) {
http_response_code(400); exit('Invalid revision');
}
$directory = $config['state_root'].'/requests';
$file = $directory.'/'.$commit.'.json';
// Atomic publication, exact commit identity; retries do not create duplicate requests.
$temporary = @tempnam($config['state_root'].'/incoming', 'incoming-');
if ($temporary === false) { http_response_code(503); exit('Queue unavailable'); }
chmod($temporary, 0640);
$data = json_encode(['commit' => $commit, 'ref' => $payload['ref'], 'received_at' => gmdate(DATE_ATOM)], JSON_THROW_ON_ERROR);
if (file_put_contents($temporary, $data) === false || !rename($temporary, $file)) {
@unlink($temporary); http_response_code(503); exit('Queue unavailable');
}
// systemd.path observes the queue even if a previous build is still active.
http_response_code(202);
header('Content-Type: application/json');
echo json_encode(['accepted' => true, 'commit' => $commit]);