update logging

This commit is contained in:
Chirag Aggarwal
2026-03-25 10:01:25 +05:30
parent a7cdfed253
commit 617d6fe1eb
+112 -101
View File
@@ -152,12 +152,14 @@ class SDKs extends Action
}
if (! $language['enabled']) {
Console::warning($language['name'] . ' for ' . $platform['name'] . ' is disabled');
Console::warning("{$language['name']} for {$platform['name']} is disabled");
continue;
}
Console::info('Fetching API Spec for ' . $language['name'] . ' for ' . $platform['name'] . ' (version: ' . $version . ')');
Console::log('');
Console::info("━━━ {$language['name']} SDK ({$platform['name']}, {$version}) ━━━");
Console::log(' Fetching API spec...');
$specPath = __DIR__ . '/../../../../app/config/specs/swagger2-' . $version . '-' . $language['family'] . '.json';
@@ -321,7 +323,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
$releaseTarget = $language['repoBranch'] ?? 'main';
if ($repoName === '/') {
Console::warning("{$language['name']} SDK is not an SDK, skipping release");
Console::warning(' Not a releasable SDK, skipping');
continue;
}
@@ -331,8 +333,8 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
$existingReleaseUrl = trim(\shell_exec($checkReleaseCommand) ?? '');
if (! empty($existingReleaseUrl)) {
Console::warning("Release {$releaseVersion} already exists for {$language['name']} SDK, skipping...");
Console::info("Existing release: {$existingReleaseUrl}");
Console::warning(" Release {$releaseVersion} already exists, skipping");
Console::log(" {$existingReleaseUrl}");
continue;
}
@@ -350,7 +352,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
$tagCommitSha = trim(\shell_exec($tagCommitCommand) ?? '');
if (! empty($tagCommitSha) && $latestCommitSha === $tagCommitSha) {
Console::warning("Latest commit on {$releaseTarget} already has a release ({$latestReleaseTag}) for {$language['name']} SDK, skipping to avoid empty release...");
Console::warning(" Latest commit already released ({$latestReleaseTag}), skipping");
continue;
}
@@ -371,17 +373,16 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
}
if (! $commitRelease) {
Console::info("[DRY RUN] Would create release for {$language['name']} SDK:");
Console::log(" Repository: {$repoName}");
Console::log(" Version: {$releaseVersion}");
Console::log(" Title: {$releaseTitle}");
Console::log(" Target Branch: {$releaseTarget}");
Console::log(' Previous Version: ' . ($previousVersion ?: 'N/A'));
Console::log(' Release Notes:');
Console::log(' ' . str_replace("\n", "\n ", $formattedNotes));
Console::log('');
Console::info(' [DRY RUN] Would create release:');
Console::log(" Repository: {$repoName}");
Console::log(" Version: {$releaseVersion}");
Console::log(" Title: {$releaseTitle}");
Console::log(" Target Branch: {$releaseTarget}");
Console::log(' Previous Version: ' . ($previousVersion ?: 'N/A'));
Console::log(' Release Notes:');
Console::log(' ' . str_replace("\n", "\n ", $formattedNotes));
} else {
Console::info("Creating release {$releaseVersion} for {$language['name']} SDK...");
Console::log(" Creating release {$releaseVersion}...");
$tempNotesFile = \tempnam(\sys_get_temp_dir(), 'release_notes_');
\file_put_contents($tempNotesFile, $formattedNotes);
@@ -409,22 +410,22 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
}
}
Console::success("Successfully created release {$releaseVersion} for {$language['name']} SDK");
Console::success(" Release {$releaseVersion} created");
if (! empty($releaseUrl)) {
Console::info("Release URL: {$releaseUrl}");
Console::log(" {$releaseUrl}");
}
} else {
$errorMessage = implode("\n", $releaseOutput);
Console::error("Failed to create release for {$language['name']} SDK: " . $errorMessage);
Console::error(" Failed to create release: " . $errorMessage);
}
}
continue;
}
Console::info($examplesOnly
? "Generating examples for {$language['name']} SDK..."
: "Generating {$language['name']} SDK...");
Console::log($examplesOnly
? ' Generating examples...'
: ' Generating SDK...');
$sdk = new SDK($config, new Swagger2($spec));
@@ -478,11 +479,11 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
$aiChangelog = ''; // Track AI-generated changelog for PR description
if (! empty($apiKey) && ! $examplesOnly) {
Console::info("Analyzing SDK changes with AI...");
Console::log(' Analyzing changes with AI...');
$aiResult = $this->generateVersionAndChangelog($language, $result);
if (!empty($aiResult['skip'])) {
Console::warning("Skipping {$language['name']} SDK generation");
Console::warning(' Skipping (no relevant changes)');
continue;
} elseif ($aiResult !== null) {
$newVersion = $aiResult['version'];
@@ -510,7 +511,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
Console::error($exception->getMessage());
}
} else {
Console::warning('AI analysis failed, using existing version');
Console::warning(' AI analysis failed, using existing version');
}
}
@@ -543,9 +544,9 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
if (! empty($prUrls)) {
Console::log('');
Console::log('Pull Request Summary');
Console::info('━━━ Pull Request Summary ━━━');
foreach ($prUrls as $sdkName => $url) {
Console::log("{$sdkName}: {$url}");
Console::log(" {$sdkName}: {$url}");
}
Console::log('');
}
@@ -553,7 +554,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
private function pushToGit(array $language, string $target, string $result, string $gitUrl, string $gitBranch, string $repoBranch, string $commitMessage): bool
{
Console::info("Preparing {$language['name']} SDK repository...");
Console::log(' Preparing git repository...');
try {
// Init fresh repo
@@ -639,11 +640,11 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
$repo->commit($commitMessage);
$repo->execute('push', '-u', 'origin', $gitBranch, '--quiet');
} catch (\Throwable $e) {
Console::warning("Git operations failed for {$language['name']} SDK: " . $e->getMessage());
Console::warning(" Git push failed: " . $e->getMessage());
return false;
}
Console::success("Pushed {$language['name']} SDK to {$gitUrl}");
Console::success(" Pushed to {$gitUrl}");
return true;
}
@@ -656,7 +657,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
}
$repoName = $language['gitUserName'] . '/' . $language['gitRepoName'];
Console::info("Creating pull request for {$language['name']} SDK...");
Console::log(' Creating pull request...');
$prCommand = 'cd ' . $target . ' && \
gh pr create \
@@ -672,7 +673,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
\exec($prCommand, $prOutput, $prReturnCode);
if ($prReturnCode === 0) {
Console::success("Successfully created pull request for {$language['name']} SDK");
Console::success(" Pull request created");
foreach ($prOutput as $line) {
if (\str_starts_with(trim($line), 'https://')) {
$prUrls[$language['name']] = trim($line);
@@ -682,9 +683,18 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
} else {
$errorMessage = implode("\n", $prOutput);
if (strpos($errorMessage, 'already exists') === false) {
Console::error("Failed to create pull request for {$language['name']} SDK: " . $errorMessage);
Console::error(" Failed to create pull request: " . $errorMessage);
} else {
$this->updateExistingPr($target, $repoName, $gitBranch, $prTitle, $prBody, $language['name'], $prUrls);
// Extract PR URL from the error output (gh includes it in "already exists" messages)
$existingPrUrl = '';
foreach ($prOutput as $line) {
if (\preg_match('#(https://github\.com/[^\s]+/pull/\d+)#', $line, $urlMatch)) {
$existingPrUrl = $urlMatch[1];
break;
}
}
$this->updateExistingPr($repoName, $gitBranch, $prTitle, $prBody, $language['name'], $prUrls, $existingPrUrl);
}
}
}
@@ -692,7 +702,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
private function cleanupTarget(string $target, string $languageName): void
{
\exec('chmod -R u+w ' . $target . ' && rm -rf ' . $target);
Console::success("Remove temp directory '{$target}' for {$languageName} SDK");
Console::log(' Cleaned up temp directory');
}
private function copyExamples(array $language, string $version, string $result, string $resultExamples): void
@@ -708,7 +718,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
$examplesSource = $result . '/docs/examples' . $languagePath;
if (! \is_dir($examplesSource)) {
Console::warning("No code examples found for {$language['name']} SDK at: {$examplesSource}. Skipping copy.");
Console::warning(" No code examples found at: {$examplesSource}");
continue;
}
@@ -717,7 +727,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
'mkdir -p ' . $resultExamples . $languagePath . ' && \
cp -r ' . $examplesSource . ' ' . $resultExamples
);
Console::success("Copied code examples for {$language['name']} SDK to: {$resultExamples}");
Console::success(" Examples copied to {$resultExamples}");
}
}
@@ -773,13 +783,13 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
$repoBranch = $language['repoBranch'] ?? 'main';
if (empty($gitUrl)) {
Console::warning("No git URL for {$language['name']} SDK, skipping AI analysis");
Console::warning(' No git URL, skipping AI analysis');
return null;
}
$apiKey = System::getEnv('_APP_ASSISTANT_OPENAI_API_KEY', '');
if (empty($apiKey)) {
Console::warning('_APP_ASSISTANT_OPENAI_API_KEY not set, cannot use AI for version analysis');
Console::warning(' _APP_ASSISTANT_OPENAI_API_KEY not set, skipping AI analysis');
return null;
}
@@ -871,7 +881,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
->setMaxDiffLines(500)
->setUserId('sdk-analyst');
Console::info("Running DiffCheck for {$language['name']} SDK...");
Console::log(' Running DiffCheck...');
$result = (new DiffCheck())->run(
runner: $adapter,
@@ -882,43 +892,42 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
);
if (!$result['hasChanges']) {
Console::info(" No changes detected - SDK is up to date");
Console::success(' No changes detected, SDK is up to date');
return null;
}
$responseContent = $result['response'];
if (empty(trim($responseContent))) {
Console::warning('AI returned empty response');
Console::warning(' AI returned empty response');
return null;
}
$parsed = json_decode($responseContent, true);
if (json_last_error() !== JSON_ERROR_NONE) {
Console::warning('Failed to parse AI response as JSON: ' . json_last_error_msg());
Console::log('Raw response:');
Console::log($responseContent);
Console::warning(' Failed to parse AI response: ' . json_last_error_msg());
Console::log(' Raw response: ' . $responseContent);
return null;
}
if (empty($parsed['version']) || empty($parsed['changelog']) || empty($parsed['versionBump'])) {
Console::warning('AI response missing required fields');
Console::warning(' AI response missing required fields');
return null;
}
// Guard: beta SDKs must not be bumped to >= 1.0.0
if ($isBeta && ($parsed['versionBump'] === 'major' || \version_compare($parsed['version'], '1.0.0', '>='))) {
Console::warning("Beta SDK {$language['name']} cannot have a major bump or version >= 1.0.0 (AI suggested {$parsed['version']}), skipping");
Console::warning(" Beta SDK cannot bump to {$parsed['version']}, skipping");
return ['skip' => true];
}
Console::success(" Analysis complete");
Console::log(" Version: {$language['version']}{$parsed['version']} ({$parsed['versionBump']} bump)");
Console::log(" Changelog:");
Console::success(" AI analysis complete");
Console::log(" Version: {$language['version']}{$parsed['version']} ({$parsed['versionBump']})");
Console::log(" Changelog:");
foreach (explode("\n", $parsed['changelog']) as $line) {
if (trim($line)) {
Console::log(" {$line}");
Console::log(" {$line}");
}
}
@@ -928,7 +937,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
'versionBump' => $parsed['versionBump'],
];
} catch (\Throwable $e) {
Console::error('Error generating version and changelog: ' . $e->getMessage());
Console::error(' AI error: ' . $e->getMessage());
return null;
}
}
@@ -946,7 +955,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
$configPath = $this->getSdkConfigPath();
if (! file_exists($configPath)) {
Console::error("Config file not found: {$configPath}");
Console::error(" Config file not found: {$configPath}");
return false;
}
@@ -961,10 +970,10 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
$newContent = preg_replace($inlinePattern, '${1}' . $newVersion . '${3}', $content);
if (file_put_contents($configPath, $newContent) !== false) {
Console::success("Updated {$sdkKey} version from {$oldVersion} to {$newVersion} in config");
Console::success(" Config updated: {$sdkKey} {$oldVersion} {$newVersion}");
return true;
} else {
Console::error('Failed to write config file');
Console::error(' Failed to write config file');
return false;
}
}
@@ -986,7 +995,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
$blockContent = $blockMatch[2];
if (preg_match($entryPattern, $blockContent, $entryMatch)) {
$oldVersion = $entryMatch[2];
Console::success("Updated {$sdkKey} version from {$oldVersion} to {$newVersion} in config");
Console::success(" Config updated: {$sdkKey} {$oldVersion} {$newVersion}");
$blockContent = preg_replace($entryPattern, '${1}' . $newVersion . '${3}', $blockContent);
$updated = true;
}
@@ -998,7 +1007,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
}
if (file_put_contents($configPath, $newContent) === false) {
Console::error('Failed to write config file');
Console::error(' Failed to write config file');
return false;
}
@@ -1016,7 +1025,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
private function updateChangelogFile(string $changelogPath, string $version, string $notes): bool
{
if (empty($changelogPath) || ! file_exists($changelogPath)) {
Console::warning("Changelog file not found: {$changelogPath}");
Console::warning(" Changelog file not found: {$changelogPath}");
return false;
}
@@ -1025,7 +1034,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// Check if version already exists
if (strpos($content, "## {$version}") !== false) {
Console::warning("Version {$version} already exists in changelog, skipping update");
Console::warning(" Version {$version} already in changelog, skipping");
return false;
}
@@ -1053,72 +1062,74 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
$newContent = implode("\n", $newLines);
if (file_put_contents($changelogPath, $newContent) !== false) {
Console::success("Updated changelog at {$changelogPath} with version {$version}");
Console::success(" Changelog updated with version {$version}");
return true;
} else {
Console::error('Failed to write changelog file');
Console::error(' Failed to write changelog file');
return false;
}
}
private function updateExistingPr(string $target, string $repoName, string $gitBranch, string $prTitle, string $prBody, string $sdkName, array &$prUrls): void
private function updateExistingPr(string $repoName, string $gitBranch, string $prTitle, string $prBody, string $sdkName, array &$prUrls, string $existingPrUrl = ''): void
{
Console::warning("Pull request already exists for {$sdkName} SDK, updating title and body...");
Console::log(' Pull request already exists, updating...');
$prNumberCommand = 'cd ' . $target . ' && \
gh pr list \
--repo ' . \escapeshellarg($repoName) . ' \
--head ' . \escapeshellarg($gitBranch) . ' \
--json number \
--jq ".[0].number" \
2>&1';
$prNumber = '';
$prUrl = '';
$prNumberOutput = [];
$prNumberReturnCode = 0;
\exec($prNumberCommand, $prNumberOutput, $prNumberReturnCode);
// Try extracting from the gh pr create error output first (free, no API call)
if (! empty($existingPrUrl) && \preg_match('#/pull/(\d+)#', $existingPrUrl, $matches)) {
$prNumber = $matches[1];
$prUrl = $existingPrUrl;
}
if ($prNumberReturnCode !== 0 || empty($prNumberOutput[0])) {
Console::error("Failed to get PR number for {$sdkName} SDK");
// Otherwise, look it up via gh pr list
if (empty($prNumber)) {
$prListCommand = 'gh pr list'
. ' --repo ' . \escapeshellarg($repoName)
. ' --head ' . \escapeshellarg($gitBranch)
. ' --json number,url'
. ' --jq ".[0] | (.number|tostring) + \" \" + .url"'
. ' 2>&1';
$prListOutput = [];
\exec($prListCommand, $prListOutput);
if (! empty($prListOutput[0])) {
$parts = \explode(' ', trim($prListOutput[0]), 2);
$prNumber = $parts[0] ?? '';
$prUrl = $parts[1] ?? '';
}
}
if (empty($prNumber)) {
Console::error(" Failed to find existing PR for branch {$gitBranch}");
return;
}
$prNumber = trim($prNumberOutput[0]);
$apiPath = "/repos/{$repoName}/pulls/{$prNumber}";
$updateCommand = 'cd ' . $target . ' && \
gh api \
--method PATCH \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
' . \escapeshellarg($apiPath) . ' \
-f title=' . \escapeshellarg($prTitle) . ' \
-f body=' . \escapeshellarg($prBody) . ' \
2>&1';
$updateCommand = 'gh api'
. ' --method PATCH'
. ' -H "Accept: application/vnd.github+json"'
. ' -H "X-GitHub-Api-Version: 2022-11-28"'
. ' ' . \escapeshellarg($apiPath)
. ' -f title=' . \escapeshellarg($prTitle)
. ' -f body=' . \escapeshellarg($prBody)
. ' 2>&1';
$updateOutput = [];
$updateReturnCode = 0;
\exec($updateCommand, $updateOutput, $updateReturnCode);
if ($updateReturnCode !== 0) {
Console::error("Failed to update pull request for {$sdkName} SDK: " . implode("\n", $updateOutput));
Console::error(" Failed to update pull request: " . implode("\n", $updateOutput));
return;
}
Console::success("Successfully updated pull request for {$sdkName} SDK");
Console::success(" Pull request updated");
$prUrlCommand = 'cd ' . $target . ' && \
gh pr list \
--repo ' . \escapeshellarg($repoName) . ' \
--head ' . \escapeshellarg($gitBranch) . ' \
--json url \
--jq ".[0].url" \
2>&1';
$prUrlOutput = [];
$prUrlReturnCode = 0;
\exec($prUrlCommand, $prUrlOutput, $prUrlReturnCode);
if ($prUrlReturnCode === 0 && ! empty($prUrlOutput)) {
$prUrls[$sdkName] = trim($prUrlOutput[0]);
if (! empty($prUrl)) {
$prUrls[$sdkName] = $prUrl;
}
}
}