Admin: allow configurable deploy remote for update checks
This commit is contained in:
+61
-7
@@ -2,21 +2,26 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
function adminCheckForUpdates(string $projectRoot, string $branch): array
|
||||
function adminCheckForUpdates(string $projectRoot, string $branch, string $remoteName = 'origin', string $remoteUrl = ''): array
|
||||
{
|
||||
if (!is_dir($projectRoot . '/.git')) {
|
||||
throw new RuntimeException('Репозиторий не найден: .git отсутствует');
|
||||
}
|
||||
|
||||
$fetch = adminRunShellCommand('git fetch origin ' . escapeshellarg($branch) . ' --prune', $projectRoot);
|
||||
$remoteName = adminNormalizeRemoteName($remoteName);
|
||||
adminEnsureRemote($projectRoot, $remoteName, $remoteUrl);
|
||||
|
||||
$remoteRef = $remoteName . '/' . $branch;
|
||||
|
||||
$fetch = adminRunShellCommand('git fetch ' . escapeshellarg($remoteName) . ' ' . escapeshellarg($branch) . ' --prune', $projectRoot);
|
||||
if ($fetch['code'] !== 0) {
|
||||
throw new RuntimeException('Не удалось обновить данные из origin: ' . adminTailOutput($fetch['output']));
|
||||
throw new RuntimeException('Не удалось обновить данные из ' . $remoteName . ': ' . adminTailOutput($fetch['output']));
|
||||
}
|
||||
|
||||
$local = adminRunShellCommand('git rev-parse --short=12 HEAD', $projectRoot);
|
||||
$remote = adminRunShellCommand('git rev-parse --short=12 origin/' . escapeshellarg($branch), $projectRoot);
|
||||
$behindRaw = adminRunShellCommand('git rev-list --count HEAD..origin/' . escapeshellarg($branch), $projectRoot);
|
||||
$aheadRaw = adminRunShellCommand('git rev-list --count origin/' . escapeshellarg($branch) . '..HEAD', $projectRoot);
|
||||
$remote = adminRunShellCommand('git rev-parse --short=12 ' . escapeshellarg($remoteRef), $projectRoot);
|
||||
$behindRaw = adminRunShellCommand('git rev-list --count HEAD..' . escapeshellarg($remoteRef), $projectRoot);
|
||||
$aheadRaw = adminRunShellCommand('git rev-list --count ' . escapeshellarg($remoteRef) . '..HEAD', $projectRoot);
|
||||
|
||||
if ($local['code'] !== 0 || $remote['code'] !== 0 || $behindRaw['code'] !== 0 || $aheadRaw['code'] !== 0) {
|
||||
throw new RuntimeException('Не удалось определить состояние ветки');
|
||||
@@ -36,6 +41,7 @@ function adminCheckForUpdates(string $projectRoot, string $branch): array
|
||||
|
||||
return [
|
||||
'state' => $state,
|
||||
'remote_name' => $remoteName,
|
||||
'branch' => $branch,
|
||||
'local_ref' => trim($local['output']),
|
||||
'remote_ref' => trim($remote['output']),
|
||||
@@ -45,15 +51,19 @@ function adminCheckForUpdates(string $projectRoot, string $branch): array
|
||||
];
|
||||
}
|
||||
|
||||
function adminRunDeployScript(string $projectRoot, string $branch, string $scriptPath, string $phpBin): array
|
||||
function adminRunDeployScript(string $projectRoot, string $branch, string $scriptPath, string $phpBin, string $remoteName = 'origin', string $remoteUrl = ''): array
|
||||
{
|
||||
if (!is_file($scriptPath)) {
|
||||
throw new RuntimeException('Скрипт деплоя не найден: ' . $scriptPath);
|
||||
}
|
||||
|
||||
$remoteName = adminNormalizeRemoteName($remoteName);
|
||||
|
||||
$run = adminRunShellCommand('bash ' . escapeshellarg($scriptPath), $projectRoot, [
|
||||
'BRANCH' => $branch,
|
||||
'PHP_BIN' => $phpBin,
|
||||
'REMOTE_NAME' => $remoteName,
|
||||
'REMOTE_URL' => $remoteUrl,
|
||||
]);
|
||||
|
||||
return [
|
||||
@@ -63,6 +73,50 @@ function adminRunDeployScript(string $projectRoot, string $branch, string $scrip
|
||||
];
|
||||
}
|
||||
|
||||
function adminEnsureRemote(string $projectRoot, string $remoteName, string $remoteUrl): void
|
||||
{
|
||||
$getRemote = adminRunShellCommand('git remote get-url ' . escapeshellarg($remoteName), $projectRoot);
|
||||
if ($getRemote['code'] !== 0) {
|
||||
if ($remoteUrl === '') {
|
||||
throw new RuntimeException('Remote ' . $remoteName . ' не найден');
|
||||
}
|
||||
|
||||
$add = adminRunShellCommand('git remote add ' . escapeshellarg($remoteName) . ' ' . escapeshellarg($remoteUrl), $projectRoot);
|
||||
if ($add['code'] !== 0) {
|
||||
throw new RuntimeException('Не удалось добавить remote ' . $remoteName . ': ' . adminTailOutput($add['output']));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ($remoteUrl === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
$currentUrl = trim($getRemote['output']);
|
||||
if ($currentUrl === $remoteUrl) {
|
||||
return;
|
||||
}
|
||||
|
||||
$set = adminRunShellCommand('git remote set-url ' . escapeshellarg($remoteName) . ' ' . escapeshellarg($remoteUrl), $projectRoot);
|
||||
if ($set['code'] !== 0) {
|
||||
throw new RuntimeException('Не удалось обновить remote ' . $remoteName . ': ' . adminTailOutput($set['output']));
|
||||
}
|
||||
}
|
||||
|
||||
function adminNormalizeRemoteName(string $remoteName): string
|
||||
{
|
||||
$remoteName = trim($remoteName);
|
||||
if ($remoteName === '') {
|
||||
return 'origin';
|
||||
}
|
||||
|
||||
if (!preg_match('/^[A-Za-z0-9._-]+$/', $remoteName)) {
|
||||
throw new RuntimeException('Некорректное имя remote');
|
||||
}
|
||||
|
||||
return $remoteName;
|
||||
}
|
||||
|
||||
function adminRunShellCommand(string $command, string $cwd, array $env = []): array
|
||||
{
|
||||
$envPrefix = '';
|
||||
|
||||
@@ -144,8 +144,10 @@ function adminHandlePostAction(string $action, bool $isAjax, string $projectRoot
|
||||
}
|
||||
|
||||
case 'check_updates': {
|
||||
$remoteName = (string)($deployOptions['remote_name'] ?? 'origin');
|
||||
$remoteUrl = (string)($deployOptions['remote_url'] ?? '');
|
||||
$branch = (string)($deployOptions['branch'] ?? 'main');
|
||||
$deployStatus = adminCheckForUpdates($projectRoot, $branch);
|
||||
$deployStatus = adminCheckForUpdates($projectRoot, $branch, $remoteName, $remoteUrl);
|
||||
$state = (string)($deployStatus['state'] ?? '');
|
||||
|
||||
if ($state === 'update_available') {
|
||||
@@ -162,11 +164,13 @@ function adminHandlePostAction(string $action, bool $isAjax, string $projectRoot
|
||||
}
|
||||
|
||||
case 'deploy_updates': {
|
||||
$remoteName = (string)($deployOptions['remote_name'] ?? 'origin');
|
||||
$remoteUrl = (string)($deployOptions['remote_url'] ?? '');
|
||||
$branch = (string)($deployOptions['branch'] ?? 'main');
|
||||
$scriptPath = (string)($deployOptions['script'] ?? ($projectRoot . '/scripts/deploy.sh'));
|
||||
$phpBin = (string)($deployOptions['php_bin'] ?? 'php');
|
||||
|
||||
$deployStatus = adminCheckForUpdates($projectRoot, $branch);
|
||||
$deployStatus = adminCheckForUpdates($projectRoot, $branch, $remoteName, $remoteUrl);
|
||||
if (!(bool)($deployStatus['can_deploy'] ?? false)) {
|
||||
$state = (string)($deployStatus['state'] ?? '');
|
||||
if ($state === 'up_to_date') {
|
||||
@@ -182,13 +186,13 @@ function adminHandlePostAction(string $action, bool $isAjax, string $projectRoot
|
||||
throw new RuntimeException('Нельзя применить обновление в текущем состоянии ветки.');
|
||||
}
|
||||
|
||||
$deployResult = adminRunDeployScript($projectRoot, $branch, $scriptPath, $phpBin);
|
||||
$deployResult = adminRunDeployScript($projectRoot, $branch, $scriptPath, $phpBin, $remoteName, $remoteUrl);
|
||||
$deployOutput = (string)($deployResult['output'] ?? '');
|
||||
if (!(bool)($deployResult['ok'] ?? false)) {
|
||||
throw new RuntimeException('Деплой завершился с ошибкой: ' . ($deployOutput !== '' ? $deployOutput : ('код ' . (int)($deployResult['code'] ?? 1))));
|
||||
}
|
||||
|
||||
$deployStatus = adminCheckForUpdates($projectRoot, $branch);
|
||||
$deployStatus = adminCheckForUpdates($projectRoot, $branch, $remoteName, $remoteUrl);
|
||||
$message = 'Обновление выполнено.';
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user