42 lines
2.3 KiB
PHP
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]);
|