refactoring

This commit is contained in:
Chirag Aggarwal
2026-03-04 19:03:21 +05:30
parent 300aaeb251
commit 198f9a64a3
4 changed files with 285 additions and 190 deletions
+1
View File
@@ -100,6 +100,7 @@
"swoole/ide-helper": "6.*",
"phpstan/phpstan": "1.12.*",
"textalk/websocket": "1.5.*",
"czproject/git-php": "4.*",
"laravel/pint": "1.*",
"phpbench/phpbench": "1.*"
},
Generated
+66 -2
View File
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "1fb043a556550f62ab27a0aad0b9332a",
"content-hash": "1cc64e07484256225f56bd525674c3b8",
"packages": [
{
"name": "adhocore/jwt",
@@ -5580,6 +5580,70 @@
],
"time": "2026-02-25T14:53:45+00:00"
},
{
"name": "czproject/git-php",
"version": "v4.6.0",
"source": {
"type": "git",
"url": "https://github.com/czproject/git-php.git",
"reference": "1f1ecc92aea9ee31120f4f5b759f5aa947420b0a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/czproject/git-php/zipball/1f1ecc92aea9ee31120f4f5b759f5aa947420b0a",
"reference": "1f1ecc92aea9ee31120f4f5b759f5aa947420b0a",
"shasum": ""
},
"require": {
"php": "8.0 - 8.5"
},
"require-dev": {
"nette/tester": "^2.5"
},
"type": "library",
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Jan Pecha",
"email": "janpecha@email.cz"
}
],
"description": "Library for work with Git repository in PHP.",
"keywords": [
"git"
],
"support": {
"issues": "https://github.com/czproject/git-php/issues",
"source": "https://github.com/czproject/git-php/tree/v4.6.0"
},
"funding": [
{
"url": "https://github.com/sponsors/janpecha",
"type": "github"
},
{
"url": "https://www.janpecha.cz/donate/git-php/",
"type": "other"
},
{
"url": "https://donate.stripe.com/7sIcO2a9maTSg2A9AA",
"type": "stripe"
},
{
"url": "https://thanks.dev/u/gh/czproject",
"type": "thanks.dev"
}
],
"time": "2025-11-10T07:24:07+00:00"
},
{
"name": "doctrine/annotations",
"version": "2.0.2",
@@ -9043,7 +9107,7 @@
],
"aliases": [],
"minimum-stability": "dev",
"stability-flags": [],
"stability-flags": {},
"prefer-stable": true,
"prefer-lowest": false,
"platform": {
-18
View File
@@ -152,7 +152,6 @@ services:
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_DB_ADAPTER
- _APP_SMTP_HOST
- _APP_SMTP_PORT
- _APP_SMTP_SECURE
@@ -305,7 +304,6 @@ services:
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_DB_ADAPTER
- _APP_USAGE_STATS
- _APP_LOGGING_CONFIG
- _APP_LOGGING_CONFIG_REALTIME
@@ -340,7 +338,6 @@ services:
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_DB_ADAPTER
- _APP_LOGGING_CONFIG
- _APP_DATABASE_SHARED_TABLES
@@ -371,7 +368,6 @@ services:
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_DB_ADAPTER
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
@@ -414,7 +410,6 @@ services:
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_DB_ADAPTER
- _APP_STORAGE_DEVICE
- _APP_STORAGE_S3_ACCESS_KEY
- _APP_STORAGE_S3_SECRET
@@ -474,7 +469,6 @@ services:
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_DB_ADAPTER
- _APP_LOGGING_CONFIG
- _APP_WORKERS_NUM
- _APP_QUEUE_NAME
@@ -513,7 +507,6 @@ services:
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_DB_ADAPTER
- _APP_LOGGING_CONFIG
- _APP_VCS_GITHUB_APP_NAME
- _APP_VCS_GITHUB_PRIVATE_KEY
@@ -658,7 +651,6 @@ services:
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_DB_ADAPTER
- _APP_LOGGING_CONFIG
- _APP_DATABASE_SHARED_TABLES
@@ -722,7 +714,6 @@ services:
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_DB_ADAPTER
- _APP_FUNCTIONS_TIMEOUT
- _APP_SITES_TIMEOUT
- _APP_COMPUTE_BUILD_TIMEOUT
@@ -808,7 +799,6 @@ services:
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_DB_ADAPTER
- _APP_LOGGING_CONFIG
- _APP_SMS_FROM
- _APP_SMS_PROVIDER
@@ -875,7 +865,6 @@ services:
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_DB_ADAPTER
- _APP_LOGGING_CONFIG
- _APP_MIGRATIONS_FIREBASE_CLIENT_ID
- _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET
@@ -918,7 +907,6 @@ services:
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_DB_ADAPTER
- _APP_MAINTENANCE_INTERVAL
- _APP_MAINTENANCE_RETENTION_EXECUTION
- _APP_MAINTENANCE_RETENTION_CACHE
@@ -994,7 +982,6 @@ services:
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_DB_ADAPTER
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
@@ -1028,7 +1015,6 @@ services:
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_DB_ADAPTER
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
@@ -1062,7 +1048,6 @@ services:
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_DB_ADAPTER
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
@@ -1100,7 +1085,6 @@ services:
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_DB_ADAPTER
- _APP_DATABASE_SHARED_TABLES
appwrite-task-scheduler-executions:
@@ -1131,7 +1115,6 @@ services:
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_DB_ADAPTER
appwrite-task-scheduler-messages:
entrypoint: schedule-messages
@@ -1161,7 +1144,6 @@ services:
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_DB_ADAPTER
- _APP_DATABASE_SHARED_TABLES
appwrite-assistant:
+218 -170
View File
@@ -25,6 +25,7 @@ use Appwrite\SDK\Language\Swift;
use Appwrite\SDK\Language\Web;
use Appwrite\SDK\SDK;
use Appwrite\Spec\Swagger2;
use CzProject\GitPhp\Git;
use Utopia\Agents\Adapters\OpenAI;
use Utopia\Agents\DiffCheck\DiffCheck;
use Utopia\Agents\DiffCheck\Options as DiffCheckOptions;
@@ -41,18 +42,6 @@ use Utopia\Validator\WhiteList;
class SDKs extends Action
{
protected function getSupportedSDKs(): array
{
$keys = [];
$platforms = Config::getParam('sdks');
foreach ($platforms as $platform) {
foreach ($platform['sdks'] as $sdk) {
$keys[] = $sdk['key'];
}
}
return \array_unique($keys);
}
public static function getName(): string
{
return 'sdks';
@@ -63,6 +52,19 @@ class SDKs extends Action
return Specs::getPlatforms();
}
protected function getSdkConfigPath(): string
{
return __DIR__ . '/../../../../app/config/sdks.php';
}
protected function getSupportedSDKs(): array
{
return \array_unique(\array_merge(...\array_map(
fn ($platform) => \array_column($platform['sdks'], 'key'),
Config::getParam('sdks')
)));
}
public function __construct()
{
$this
@@ -514,146 +516,151 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
$gitBranch = $language['gitBranch'];
$repoBranch = $language['repoBranch'] ?? 'main';
if ($git && ! empty($gitUrl)) {
// Generate commit message: use provided message, AI changelog, or fallback
if (! empty($message)) {
$commitMessage = $message;
} elseif (! empty($aiChangelog) && $aiChangelog !== '* No user-facing SDK changes.') {
$commitMessage = "feat: update {$language['name']} SDK to {$language['version']}\n\n{$aiChangelog}";
} else {
$commitMessage = "chore: update {$language['name']} SDK to {$language['version']}";
}
Console::info("Preparing {$language['name']} SDK repository...");
\exec('rm -rf ' . $target . ' && \
mkdir -p ' . $target . ' && \
cd ' . $target . ' && \
git init --quiet && \
git config core.ignorecase false && \
git config pull.rebase false && \
git config advice.defaultBranchName false && \
git remote add origin ' . $gitUrl . ' && \
git fetch origin --quiet --no-tags --depth 1 ' . $repoBranch . ' 2>&1 | grep -v "^remote:" | grep -v "^From " | grep -v "^ \* " || true && \
(git checkout -f ' . $repoBranch . ' 2>/dev/null || git checkout -b ' . $repoBranch . ') && \
git pull origin ' . $repoBranch . ' --quiet --no-tags 2>&1 | grep -v "^From " | grep -v "^ \* " || true && \
(git checkout -f ' . $gitBranch . ' 2>/dev/null || git checkout -b ' . $gitBranch . ') && \
(git fetch origin ' . $gitBranch . ' --quiet --no-tags --depth 1 2>/dev/null || git push -u origin ' . $gitBranch . ' --quiet 2>&1 | grep -v "^remote:" || true) && \
git reset --hard origin/' . $gitBranch . ' 2>/dev/null || true && \
(if [ -d .github ]; then cp -r .github /tmp/.github-backup-$$ 2>/dev/null; fi) && \
git rm -rf --cached . 2>/dev/null && \
git clean -fdx -e .git -e .github 2>/dev/null && \
cp -r ' . $result . '/. ' . $target . '/ && \
(if [ -d /tmp/.github-backup-$$/.github ]; then cp -rn /tmp/.github-backup-$$/.github . 2>/dev/null && rm -rf /tmp/.github-backup-$$; fi) && \
git add -A && \
git commit -m ' . \escapeshellarg($commitMessage) . ' --quiet && \
git push -u origin ' . $gitBranch . ' --quiet 2>&1 | grep -E "^(To | |[0-9a-f]+\\.\\.[0-9a-f]+)" || true
', $gitOutput, $gitReturnCode);
if ($gitReturnCode !== 0) {
Console::warning("Git operations completed with warnings (exit code: {$gitReturnCode})");
}
Console::success("Pushed {$language['name']} SDK to {$gitUrl}");
if ($git) {
$prTitle = "feat: {$language['name']} SDK update for version {$language['version']}";
// Build PR body with AI changelog if available
$prBody = "This PR contains updates to the {$language['name']} SDK for version {$language['version']}.";
if (!empty($aiChangelog) && $aiChangelog !== '* No user-facing SDK changes.') {
$prBody .= "\n\n## Changes\n\n{$aiChangelog}";
}
$repoName = $language['gitUserName'] . '/' . $language['gitRepoName'];
Console::info("Creating pull request for {$language['name']} SDK...");
$prCommand = 'cd ' . $target . ' && \
gh pr create \
--repo ' . \escapeshellarg($repoName) . ' \
--title ' . \escapeshellarg($prTitle) . ' \
--body ' . \escapeshellarg($prBody) . ' \
--base ' . \escapeshellarg($repoBranch) . ' \
--head ' . \escapeshellarg($gitBranch) . ' \
2>&1';
$prOutput = [];
$prReturnCode = 0;
\exec($prCommand, $prOutput, $prReturnCode);
if ($prReturnCode === 0) {
Console::success("Successfully created pull request for {$language['name']} SDK");
if (! empty($prOutput)) {
$prUrls[$language['name']] = end($prOutput);
}
} else {
$errorMessage = implode("\n", $prOutput);
if (strpos($errorMessage, 'already exists') !== false) {
Console::warning("Pull request already exists for {$language['name']} SDK, updating title and body...");
$prNumberCommand = 'cd ' . $target . ' && \
gh pr list \
--repo ' . \escapeshellarg($repoName) . ' \
--head ' . \escapeshellarg($gitBranch) . ' \
--json number \
--jq ".[0].number" \
2>&1';
$prNumberOutput = [];
$prNumberReturnCode = 0;
\exec($prNumberCommand, $prNumberOutput, $prNumberReturnCode);
if ($prNumberReturnCode === 0 && ! empty($prNumberOutput[0])) {
$prNumber = trim($prNumberOutput[0]);
// Use API directly to update PR to avoid deprecated projectCards field
$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';
$updateOutput = [];
$updateReturnCode = 0;
\exec($updateCommand, $updateOutput, $updateReturnCode);
if ($updateReturnCode === 0) {
Console::success("Successfully updated pull request for {$language['name']} SDK");
$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[$language['name']] = trim($prUrlOutput[0]);
}
} else {
$updateErrorMessage = implode("\n", $updateOutput);
Console::error("Failed to update pull request for {$language['name']} SDK: " . $updateErrorMessage);
}
} else {
Console::error("Failed to get PR number for {$language['name']} SDK");
}
} else {
Console::error("Failed to create pull request for {$language['name']} SDK: " . $errorMessage);
}
}
}
\exec('chmod -R u+w ' . $target . ' && rm -rf ' . $target);
Console::success("Remove temp directory '{$target}' for {$language['name']} SDK");
if (! $git || empty($gitUrl)) {
goto copyExamples;
}
// Generate commit message: use provided message, AI changelog, or fallback
if (! empty($message)) {
$commitMessage = $message;
} elseif (! empty($aiChangelog) && $aiChangelog !== '* No user-facing SDK changes.') {
$commitMessage = "feat: update {$language['name']} SDK to {$language['version']}\n\n{$aiChangelog}";
} else {
$commitMessage = "chore: update {$language['name']} SDK to {$language['version']}";
}
Console::info("Preparing {$language['name']} SDK repository...");
try {
// Init fresh repo
\exec('rm -rf ' . \escapeshellarg($target));
\mkdir($target, 0755, true);
$gitClient = new Git();
$repo = $gitClient->init($target);
$repo->execute('config', 'core.ignorecase', 'false');
$repo->execute('config', 'pull.rebase', 'false');
$repo->execute('config', 'advice.defaultBranchName', 'false');
$repo->addRemote('origin', $gitUrl);
// Fetch and checkout base branch (or create if new repo)
try {
$repo->execute('fetch', 'origin', '--quiet', '--no-tags', '--depth', '1', $repoBranch);
try {
$repo->execute('checkout', '-f', $repoBranch);
} catch (\Throwable) {
$repo->execute('checkout', '-b', $repoBranch);
}
} catch (\Throwable) {
$repo->execute('checkout', '-b', $repoBranch);
}
try {
$repo->execute('pull', 'origin', $repoBranch, '--quiet', '--no-tags');
} catch (\Throwable) {
}
// Checkout dev branch (or create if it doesn't exist)
try {
$repo->execute('checkout', '-f', $gitBranch);
} catch (\Throwable) {
$repo->execute('checkout', '-b', $gitBranch);
}
// Fetch dev branch, or push to create it on remote
try {
$repo->execute('fetch', 'origin', $gitBranch, '--quiet', '--no-tags', '--depth', '1');
} catch (\Throwable) {
try {
$repo->execute('push', '-u', 'origin', $gitBranch, '--quiet');
} catch (\Throwable) {
}
}
// Sync with remote dev branch
try {
$repo->execute('reset', '--hard', "origin/{$gitBranch}");
} catch (\Throwable) {
}
// Backup .github before cleaning working tree
$githubDir = $target . '/.github';
$githubBackup = \sys_get_temp_dir() . '/.github-backup-' . \getmypid();
$hasGithubDir = \is_dir($githubDir);
if ($hasGithubDir) {
\exec('cp -r ' . \escapeshellarg($githubDir) . ' ' . \escapeshellarg($githubBackup));
}
// Clean working tree
try {
$repo->execute('rm', '-rf', '--cached', '.');
} catch (\Throwable) {
}
try {
$repo->execute('clean', '-fdx', '-e', '.git', '-e', '.github');
} catch (\Throwable) {
}
// Copy generated SDK and restore .github
\exec('cp -r ' . \escapeshellarg($result . '/.') . ' ' . \escapeshellarg($target . '/'));
if ($hasGithubDir && \is_dir($githubBackup)) {
\exec('cp -rn ' . \escapeshellarg($githubBackup . '/.github') . ' ' . \escapeshellarg($target . '/') . ' 2>/dev/null');
\exec('rm -rf ' . \escapeshellarg($githubBackup));
}
// Stage, commit, push
$repo->addAllChanges();
$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::success("Pushed {$language['name']} SDK to {$gitUrl}");
// Create or update pull request
$prTitle = "feat: {$language['name']} SDK update for version {$language['version']}";
$prBody = "This PR contains updates to the {$language['name']} SDK for version {$language['version']}.";
if (!empty($aiChangelog) && $aiChangelog !== '* No user-facing SDK changes.') {
$prBody .= "\n\n## Changes\n\n{$aiChangelog}";
}
$repoName = $language['gitUserName'] . '/' . $language['gitRepoName'];
Console::info("Creating pull request for {$language['name']} SDK...");
$prCommand = 'cd ' . $target . ' && \
gh pr create \
--repo ' . \escapeshellarg($repoName) . ' \
--title ' . \escapeshellarg($prTitle) . ' \
--body ' . \escapeshellarg($prBody) . ' \
--base ' . \escapeshellarg($repoBranch) . ' \
--head ' . \escapeshellarg($gitBranch) . ' \
2>&1';
$prOutput = [];
$prReturnCode = 0;
\exec($prCommand, $prOutput, $prReturnCode);
if ($prReturnCode === 0) {
Console::success("Successfully created pull request for {$language['name']} SDK");
if (! empty($prOutput)) {
$prUrls[$language['name']] = end($prOutput);
}
} else {
$errorMessage = implode("\n", $prOutput);
if (strpos($errorMessage, 'already exists') === false) {
Console::error("Failed to create pull request for {$language['name']} SDK: " . $errorMessage);
} else {
$this->updateExistingPr($target, $repoName, $gitBranch, $prTitle, $prBody, $language['name'], $prUrls);
}
}
\exec('chmod -R u+w ' . $target . ' && rm -rf ' . $target);
Console::success("Remove temp directory '{$target}' for {$language['name']} SDK");
copyExamples:
$docDirectories = $language['docDirectories'] ?? [''];
if ($version === 'latest') {
@@ -858,7 +865,6 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
if (empty(trim($responseContent))) {
Console::warning('AI returned empty response');
return null;
}
@@ -868,7 +874,6 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
Console::warning('Failed to parse AI response as JSON: ' . json_last_error_msg());
Console::log('Raw response:');
Console::log($responseContent);
return null;
}
@@ -899,21 +904,10 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
];
} catch (\Throwable $e) {
Console::error('Error generating version and changelog: ' . $e->getMessage());
return null;
}
}
/**
* Get the SDK config file path
*
* @return string Path to the SDK config file
*/
protected function getSdkConfigPath(): string
{
return __DIR__ . '/../../../../app/config/sdks.php';
}
/**
* Update SDK version in the config file
*
@@ -928,7 +922,6 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
if (! file_exists($configPath)) {
Console::error("Config file not found: {$configPath}");
return false;
}
@@ -944,11 +937,9 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
if (file_put_contents($configPath, $newContent) !== false) {
Console::success("Updated {$sdkKey} version from {$oldVersion} to {$newVersion} in config");
return true;
} else {
Console::error('Failed to write config file');
return false;
}
}
@@ -964,11 +955,9 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
if (file_put_contents($configPath, $newContent) !== false) {
Console::success("Updated {$sdkKey} version from {$oldVersion} to {$newVersion} in config");
return true;
} else {
Console::error('Failed to write config file');
return false;
}
}
@@ -1027,12 +1016,71 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
if (file_put_contents($changelogPath, $newContent) !== false) {
Console::success("Updated changelog at {$changelogPath} with version {$version}");
return true;
} else {
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
{
Console::warning("Pull request already exists for {$sdkName} SDK, updating title and body...");
$prNumberCommand = 'cd ' . $target . ' && \
gh pr list \
--repo ' . \escapeshellarg($repoName) . ' \
--head ' . \escapeshellarg($gitBranch) . ' \
--json number \
--jq ".[0].number" \
2>&1';
$prNumberOutput = [];
$prNumberReturnCode = 0;
\exec($prNumberCommand, $prNumberOutput, $prNumberReturnCode);
if ($prNumberReturnCode !== 0 || empty($prNumberOutput[0])) {
Console::error("Failed to get PR number for {$sdkName} SDK");
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';
$updateOutput = [];
$updateReturnCode = 0;
\exec($updateCommand, $updateOutput, $updateReturnCode);
if ($updateReturnCode !== 0) {
Console::error("Failed to update pull request for {$sdkName} SDK: " . implode("\n", $updateOutput));
return;
}
Console::success("Successfully updated pull request for {$sdkName} SDK");
$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]);
}
}
}