diff --git a/src/BuildNotifier.php b/src/BuildNotifier.php index 18b40de..c1ddebc 100644 --- a/src/BuildNotifier.php +++ b/src/BuildNotifier.php @@ -47,6 +47,9 @@ final class BuildNotifier { 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 { @@ -106,14 +109,19 @@ final class BuildNotifier { if (is_array($cached)) { return $cached; } - $path = (string) cfg( - 'build.notify.broadcast_config', - '/var/www/ac/broadcast/config/config.php' - ); - if ($path !== '' && is_file($path)) { - $cfg = require $path; - $cached = is_array($cfg) ? $cfg : []; - return $cached; + $paths = array_values(array_unique(array_filter([ + (string) cfg('build.notify.broadcast_config', ''), + '/var/www/ac/broadcast/config/config.php', + '/var/www/ac/workspace/ac-ms-broadcast/config/config.php', + ]))); + foreach ($paths as $path) { + if ($path !== '' && is_file($path)) { + $cfg = require $path; + if (is_array($cfg)) { + $cached = $cfg; + return $cached; + } + } } $cached = []; return $cached; @@ -187,7 +195,13 @@ final class BuildNotifier { /** @param array $smtp */ 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; } $host = (string) ($smtp['host'] ?? 'smtp.gmail.com'); @@ -233,4 +247,17 @@ final class BuildNotifier { $send('QUIT'); fclose($sock); } + + private static function sendMailTransport(string $to, string $subject, string $htmlBody): void { + $from = (string) cfg('mail.from', 'Android Cast '); + $replyTo = (string) cfg('mail.reply_to', ''); + $plain = strip_tags(str_replace(['
', '
', '
'], "\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); + } } diff --git a/src/BuildRunner.php b/src/BuildRunner.php index 25f5ea2..c76764b 100644 --- a/src/BuildRunner.php +++ b/src/BuildRunner.php @@ -133,7 +133,13 @@ YAML; ]); $dir = self::artifactDir($id); 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'; BuildRepository::update($id, ['log_path' => $logPath]);