mirror of
git://f0xx.org/ac/ac-be-builder
synced 2026-08-12 18:12:50 +03:00
Builder: fail gracefully on artifact mkdir and notify on enqueue errors.
Use failBuild instead of throwing on permission errors, sendmail/SMTP fallback for notifications, correct broadcast config path, always alert admin. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -41,7 +41,7 @@ return [
|
|||||||
'scripts_dir' => '/workspace/ac-scripts',
|
'scripts_dir' => '/workspace/ac-scripts',
|
||||||
'notify' => [
|
'notify' => [
|
||||||
'admin_email' => 'bestcastr@gmail.com',
|
'admin_email' => 'bestcastr@gmail.com',
|
||||||
'broadcast_config' => '/var/www/ac/workspace/ac-ms-broadcast/config/config.php',
|
'broadcast_config' => '/var/www/ac/broadcast/config/config.php',
|
||||||
'telegram_token' => '',
|
'telegram_token' => '',
|
||||||
'telegram_chat_id' => '',
|
'telegram_chat_id' => '',
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -32,5 +32,15 @@ if (!isset($params['trigger_source'])) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$user = Auth::user();
|
$user = Auth::user();
|
||||||
$build = BuildRunner::enqueue($params, isset($user['id']) ? (int) $user['id'] : null);
|
try {
|
||||||
json_out(['ok' => true, 'build' => $build]);
|
$build = BuildRunner::enqueue($params, isset($user['id']) ? (int) $user['id'] : null);
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
error_log('[build_trigger] ' . $e->getMessage());
|
||||||
|
json_out(['ok' => false, 'error' => BuildErrorSanitizer::sanitize($e->getMessage())], 500);
|
||||||
|
}
|
||||||
|
$failed = (($build['status'] ?? '') === 'failed');
|
||||||
|
json_out([
|
||||||
|
'ok' => !$failed,
|
||||||
|
'build' => $build,
|
||||||
|
'error' => $failed ? (string) ($build['error_message'] ?? 'Build failed to start') : null,
|
||||||
|
]);
|
||||||
|
|||||||
@@ -47,6 +47,9 @@ final class BuildNotifier {
|
|||||||
self::sendPlainEmail($to, $subject, nl2br(h($bodyText)), self::smtpConfig());
|
self::sendPlainEmail($to, $subject, nl2br(h($bodyText)), self::smtpConfig());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Lab default: always alert admin_email (and Telegram when configured).
|
||||||
|
self::notifyAdmin($subject, $bodyText, $code, $safeError, $detailUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function notifyAdmin(string $subject, string $bodyText, string $code, string $safeError, string $detailUrl): void {
|
private static function notifyAdmin(string $subject, string $bodyText, string $code, string $safeError, string $detailUrl): void {
|
||||||
@@ -106,14 +109,19 @@ final class BuildNotifier {
|
|||||||
if (is_array($cached)) {
|
if (is_array($cached)) {
|
||||||
return $cached;
|
return $cached;
|
||||||
}
|
}
|
||||||
$path = (string) cfg(
|
$paths = array_values(array_unique(array_filter([
|
||||||
'build.notify.broadcast_config',
|
(string) cfg('build.notify.broadcast_config', ''),
|
||||||
'/var/www/ac/workspace/ac-ms-broadcast/config/config.php'
|
'/var/www/ac/broadcast/config/config.php',
|
||||||
);
|
'/var/www/ac/workspace/ac-ms-broadcast/config/config.php',
|
||||||
if ($path !== '' && is_file($path)) {
|
])));
|
||||||
$cfg = require $path;
|
foreach ($paths as $path) {
|
||||||
$cached = is_array($cfg) ? $cfg : [];
|
if ($path !== '' && is_file($path)) {
|
||||||
return $cached;
|
$cfg = require $path;
|
||||||
|
if (is_array($cfg)) {
|
||||||
|
$cached = $cfg;
|
||||||
|
return $cached;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$cached = [];
|
$cached = [];
|
||||||
return $cached;
|
return $cached;
|
||||||
@@ -187,7 +195,13 @@ final class BuildNotifier {
|
|||||||
|
|
||||||
/** @param array<string, mixed> $smtp */
|
/** @param array<string, mixed> $smtp */
|
||||||
private static function sendPlainEmail(string $to, string $subject, string $htmlBody, array $smtp): void {
|
private static function sendPlainEmail(string $to, string $subject, string $htmlBody, array $smtp): void {
|
||||||
if ($to === '' || empty($smtp['user']) || empty($smtp['pass'])) {
|
if ($to === '') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$transport = strtolower((string) cfg('mail.transport', 'smtp'));
|
||||||
|
$hasSmtpCreds = !empty($smtp['user']) && !empty($smtp['pass']);
|
||||||
|
if ($transport === 'sendmail' || !$hasSmtpCreds) {
|
||||||
|
self::sendMailTransport($to, $subject, $htmlBody);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$host = (string) ($smtp['host'] ?? 'smtp.gmail.com');
|
$host = (string) ($smtp['host'] ?? 'smtp.gmail.com');
|
||||||
@@ -233,4 +247,17 @@ final class BuildNotifier {
|
|||||||
$send('QUIT');
|
$send('QUIT');
|
||||||
fclose($sock);
|
fclose($sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static function sendMailTransport(string $to, string $subject, string $htmlBody): void {
|
||||||
|
$from = (string) cfg('mail.from', 'Android Cast <noreply@apps.f0xx.org>');
|
||||||
|
$replyTo = (string) cfg('mail.reply_to', '');
|
||||||
|
$plain = strip_tags(str_replace(['<br>', '<br/>', '<br />'], "\n", $htmlBody));
|
||||||
|
$headers = "From: {$from}\r\n";
|
||||||
|
if ($replyTo !== '') {
|
||||||
|
$headers .= "Reply-To: {$replyTo}\r\n";
|
||||||
|
}
|
||||||
|
$headers .= "MIME-Version: 1.0\r\n";
|
||||||
|
$headers .= "Content-Type: text/html; charset=UTF-8\r\n";
|
||||||
|
@mail($to, $subject, $htmlBody, $headers);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -133,7 +133,13 @@ YAML;
|
|||||||
]);
|
]);
|
||||||
$dir = self::artifactDir($id);
|
$dir = self::artifactDir($id);
|
||||||
if (!is_dir($dir) && !mkdir($dir, 0775, true) && !is_dir($dir)) {
|
if (!is_dir($dir) && !mkdir($dir, 0775, true) && !is_dir($dir)) {
|
||||||
throw new RuntimeException('Cannot create artifact dir: ' . $dir);
|
self::failBuild(
|
||||||
|
$id,
|
||||||
|
'Cannot create artifact dir: ' . $dir
|
||||||
|
. ' (check prepare-be-builder-dirs.sh: builds/ must be writable by PHP-FPM user nobody)',
|
||||||
|
null
|
||||||
|
);
|
||||||
|
return BuildRepository::getById($id) ?? ['id' => $id, 'build_code' => $buildCode, 'status' => 'failed'];
|
||||||
}
|
}
|
||||||
$logPath = $dir . '/build.log';
|
$logPath = $dir . '/build.log';
|
||||||
BuildRepository::update($id, ['log_path' => $logPath]);
|
BuildRepository::update($id, ['log_path' => $logPath]);
|
||||||
|
|||||||
Reference in New Issue
Block a user