Some checks are pending
Deploy DummyBot / Build & Deploy to ${{ env.DEPLOY_HOST }} (push) Waiting to run
74 lines
2.7 KiB
PHP
74 lines
2.7 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Symfony\Component\Process\Process;
|
|
|
|
class WebhookController extends Controller {
|
|
/**
|
|
* Webhook de Gitea → deploy self-contained.
|
|
*
|
|
* Gitea envía POST al hacer push a main, con X-Hub-Signature-256.
|
|
* Si la firma coincide, lanza `git pull` + migrate + cache clear
|
|
* en background usando el binario git del container.
|
|
*
|
|
* IMPORTANTE: este código debe existir ANTES de que el webhook
|
|
* se active. El primer deploy se hace a mano vía SSH.
|
|
*/
|
|
public function deploy(Request $r): JsonResponse {
|
|
$secret = env('DEPLOY_WEBHOOK_SECRET');
|
|
$body = $r->getContent();
|
|
$sig = $r->header('X-Hub-Signature-256', '');
|
|
|
|
if ($secret && ! $this->validSignature($body, $sig, $secret)) {
|
|
Log::warning('[webhook] firma inválida', ['sig' => substr((string) $sig, 0, 20)]);
|
|
return response()->json(['ok' => false, 'error' => 'invalid signature'], 401);
|
|
}
|
|
|
|
$payload = json_decode($body, true) ?: [];
|
|
$ref = $payload['ref'] ?? '';
|
|
$branch = str_starts_with($ref, 'refs/heads/') ? substr($ref, 11) : 'main';
|
|
|
|
if (! in_array($branch, ['main', 'master'], true)) {
|
|
Log::info("[webhook] push a '$branch' ignorado");
|
|
return response()->json(['ok' => true, 'skipped' => 'branch != main'], 200);
|
|
}
|
|
|
|
$logFile = storage_path('logs/deploy-' . date('Ymd-His') . '.log');
|
|
$this->dispatchDeployInBackground($branch, $logFile);
|
|
|
|
Log::info("[webhook] deploy branch=$branch lanzado log=$logFile");
|
|
return response()->json([
|
|
'ok' => true,
|
|
'status' => 'deploy started',
|
|
'log' => basename($logFile),
|
|
], 202);
|
|
}
|
|
|
|
private function dispatchDeployInBackground(string $branch, string $logFile): void {
|
|
$script = base_path('deploy-runner.sh');
|
|
if (! file_exists($script)) {
|
|
// Modo fallback: registrar en log y salir
|
|
Log::warning("[webhook] $script no existe, deploy no ejecutado");
|
|
return;
|
|
}
|
|
$cmd = sprintf(
|
|
'BRANCH=%s BRANCH=%s nohup bash %s > %s 2>&1 &',
|
|
escapeshellarg($branch),
|
|
escapeshellarg($branch),
|
|
escapeshellarg($script),
|
|
escapeshellarg($logFile)
|
|
);
|
|
exec($cmd);
|
|
}
|
|
|
|
private function validSignature(string $body, string $sig, string $secret): bool {
|
|
if (! str_starts_with($sig, 'sha256=')) return false;
|
|
$expected = 'sha256=' . hash_hmac('sha256', $body, $secret);
|
|
return hash_equals($expected, $sig);
|
|
}
|
|
}
|