63 lines
2.4 KiB
PHP
63 lines
2.4 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]);
|