false, 'error' => 'POST required'], 405); } $raw = file_get_contents('php://input') ?: '{}'; $params = json_decode($raw, true); if (!is_array($params)) { $params = $_POST; } $params['pipeline_yaml'] = BuildRunner::resolvePipelineYaml($params); $params['run_tests'] = !empty($params['run_tests']); $params['run_native'] = array_key_exists('run_native', $params) ? !empty($params['run_native']) : true; $params['run_apk'] = array_key_exists('run_apk', $params) ? !empty($params['run_apk']) : true; $params['auto_ota'] = !empty($params['auto_ota']); $params['auto_deploy'] = !empty($params['auto_deploy']); $params['ota_channel'] = $params['ota_channel'] ?? 'staging'; $params['gradle_task'] = $params['gradle_task'] ?? 'assembleDebug'; $params['notify_on_fail'] = array_key_exists('notify_on_fail', $params) ? !empty($params['notify_on_fail']) : true; $params['notify_channel'] = in_array( (string) ($params['notify_channel'] ?? 'email'), ['email', 'telegram', 'both'], true ) ? (string) $params['notify_channel'] : 'email'; if (!isset($params['trigger_source'])) { $params['trigger_source'] = 'manual'; } $user = Auth::user(); try { $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, ]);