diff --git a/app/config/platforms.php b/app/config/platforms.php index 663c254b66..51930d1728 100644 --- a/app/config/platforms.php +++ b/app/config/platforms.php @@ -338,7 +338,7 @@ return [ [ 'key' => 'go', 'name' => 'Go', - 'version' => '0.14.0', + 'version' => 'v0.12.0', 'url' => 'https://github.com/appwrite/sdk-for-go', 'package' => 'https://github.com/appwrite/sdk-for-go', 'enabled' => true, diff --git a/docs/sdks/go/CHANGELOG.md b/docs/sdks/go/CHANGELOG.md index 7c72fd03be..9191f77aa3 100644 --- a/docs/sdks/go/CHANGELOG.md +++ b/docs/sdks/go/CHANGELOG.md @@ -1,9 +1,10 @@ # Change Log -## 0.14.0 +## v0.12.0 * Deprecate `createVerification` method in `Account` service * Add `createEmailVerification` method in `Account` service +* Add `orderRandom` query support ## 0.9.0 diff --git a/src/Appwrite/Platform/Tasks/SDKs.php b/src/Appwrite/Platform/Tasks/SDKs.php index 47c72c4424..87c70d214b 100644 --- a/src/Appwrite/Platform/Tasks/SDKs.php +++ b/src/Appwrite/Platform/Tasks/SDKs.php @@ -46,27 +46,35 @@ class SDKs extends Action ->param('git', null, new Nullable(new WhiteList(['yes', 'no'])), 'Should we use git push?', optional: true) ->param('production', null, new Nullable(new WhiteList(['yes', 'no'])), 'Should we push to production?', optional: true) ->param('message', null, new Nullable(new Text(256)), 'Commit Message', optional: true) + ->param('release', null, new Nullable(new WhiteList(['yes', 'no'])), 'Should we create releases?', optional: true) + ->param('commit', null, new Nullable(new WhiteList(['yes', 'no'])), 'Actually create releases (yes) or dry-run (no)?', optional: true) ->callback($this->action(...)); } - public function action(?string $selectedPlatform, ?string $selectedSDK, ?string $version, ?string $git, ?string $production, ?string $message): void + public function action(?string $selectedPlatform, ?string $selectedSDK, ?string $version, ?string $git, ?string $production, ?string $message, ?string $release, ?string $commit): void { $selectedPlatform ??= Console::confirm('Choose Platform ("' . APP_PLATFORM_CLIENT . '", "' . APP_PLATFORM_SERVER . '", "' . APP_PLATFORM_CONSOLE . '" or "*" for all):'); $selectedSDK ??= \strtolower(Console::confirm('Choose SDK ("*" for all):')); $version ??= Console::confirm('Choose an Appwrite version'); - $git ??= Console::confirm('Should we use git push? (yes/no)'); - $git = $git === 'yes'; + $createRelease = ($release === 'yes'); + $commitRelease = ($commit === 'yes'); - $prUrls = []; + if (!$createRelease) { + $git ??= Console::confirm('Should we use git push? (yes/no)'); + $git = ($git === 'yes'); - if ($git) { - $production ??= Console::confirm('Type "Appwrite" to push code to production git repos'); - $production = $production === 'Appwrite'; - $message ??= Console::confirm('Please enter your commit message:'); + $prUrls = []; + $createPr = false; - $createPr = Console::confirm('Should we create pull request automatically? (yes/no)'); - $createPr = $createPr === 'yes'; + if ($git) { + $production ??= Console::confirm('Type "Appwrite" to push code to production git repos'); + $production = $production === 'Appwrite'; + $message ??= Console::confirm('Please enter your commit message:'); + + $createPr = Console::confirm('Should we create pull request automatically? (yes/no)'); + $createPr = ($createPr === 'yes'); + } } if (!\in_array($version, [ @@ -245,6 +253,97 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND throw new \Exception('Language "' . $language['key'] . '" not supported'); } + if ($createRelease) { + $releaseVersion = $language['version']; + + $repoName = $language['gitUserName'] . '/' . $language['gitRepoName']; + $releaseNotes = $this->extractReleaseNotes($changelog, $releaseVersion); + if (empty($releaseNotes)) { + $releaseNotes = "Release version {$releaseVersion}"; + } + + $releaseTitle = $releaseVersion; + $releaseTarget = $language['repoBranch'] ?? 'main'; + + if ($repoName === '/') { + Console::warning("{$language['name']} SDK is not an SDK, skipping release"); + continue; + } + + // Check if release already exists + $checkReleaseCommand = 'gh release view "' . $releaseVersion . '" --repo "' . $repoName . '" --json url --jq ".url" 2>/dev/null'; + $existingReleaseUrl = trim(\shell_exec($checkReleaseCommand) ?? ''); + + if (!empty($existingReleaseUrl)) { + Console::warning("Release {$releaseVersion} already exists for {$language['name']} SDK, skipping..."); + Console::info("Existing release: {$existingReleaseUrl}"); + continue; + } + + $previousVersion = ''; + $tagListCommand = 'gh release list --repo "' . $repoName . '" --limit 1 --json tagName --jq ".[0].tagName" 2>&1'; + $previousVersion = trim(\shell_exec($tagListCommand) ?? ''); + + $formattedNotes = "## What's Changed\n\n"; + $formattedNotes .= $releaseNotes . "\n\n"; + + if (!empty($previousVersion)) { + $formattedNotes .= "**Full Changelog**: https://github.com/" . $repoName . "/compare/" . $previousVersion . "..." . $releaseVersion; + } else { + $formattedNotes .= "**Full Changelog**: https://github.com/" . $repoName . "/releases/tag/" . $releaseVersion; + } + + 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(''); + } else { + Console::info("Creating release {$releaseVersion} for {$language['name']} SDK..."); + + $tempNotesFile = \tempnam(\sys_get_temp_dir(), 'release_notes_'); + \file_put_contents($tempNotesFile, $formattedNotes); + + $releaseCommand = 'gh release create "' . $releaseVersion . '" \ + --repo "' . $repoName . '" \ + --title "' . $releaseTitle . '" \ + --notes-file "' . $tempNotesFile . '" \ + --target "' . $releaseTarget . '" \ + 2>&1'; + + $releaseOutput = []; + $releaseReturnCode = 0; + \exec($releaseCommand, $releaseOutput, $releaseReturnCode); + + \unlink($tempNotesFile); + + if ($releaseReturnCode === 0) { + // Extract release URL from output + $releaseUrl = ''; + foreach ($releaseOutput as $line) { + if (strpos($line, 'https://github.com/') !== false) { + $releaseUrl = trim($line); + break; + } + } + + Console::success("Successfully created release {$releaseVersion} for {$language['name']} SDK"); + if (!empty($releaseUrl)) { + Console::info("Release URL: {$releaseUrl}"); + } + } else { + $errorMessage = implode("\n", $releaseOutput); + Console::error("Failed to create release for {$language['name']} SDK: " . $errorMessage); + } + } + continue; + } + Console::info("Generating {$language['name']} SDK..."); $sdk = new SDK($config, new Swagger2($spec)); @@ -423,4 +522,47 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND Console::log(''); } } + + /** + * Extract release notes from changelog for a specific version + * + * @param string $changelog + * @param string $version + * @return string + */ + private function extractReleaseNotes(string $changelog, string $version): string + { + if (empty($changelog)) { + return ''; + } + + // Changelog version header pattern: ## 0.14.0 + $pattern = '/^##\s+' . preg_quote($version, '/') . '\s*$/m'; + $startPos = false; + if (preg_match($pattern, $changelog, $matches, PREG_OFFSET_CAPTURE)) { + $startPos = $matches[0][1]; + } + + if ($startPos === false) { + return ''; + } + + $contentStart = strpos($changelog, "\n", $startPos); + if ($contentStart === false) { + return ''; + } + $contentStart++; + + $nextHeaderPattern = '/^##?\s+/m'; + $remainingContent = substr($changelog, $contentStart); + + if (preg_match($nextHeaderPattern, $remainingContent, $matches, PREG_OFFSET_CAPTURE)) { + $endPos = $matches[0][1]; + $notes = substr($remainingContent, 0, $endPos); + } else { + $notes = $remainingContent; + } + + return trim($notes); + } }