Implement dynamic specification defaults for Functions and Sites

Co-authored-by: stnguyen90 <1477010+stnguyen90@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot] 2025-09-15 19:18:07 +00:00
parent 679de3574f
commit fea3544d4b
5 changed files with 48 additions and 4 deletions

View file

@ -5,6 +5,7 @@ namespace Appwrite\Platform\Modules\Compute;
use Appwrite\Event\Build;
use Appwrite\Extend\Exception;
use Appwrite\Platform\Action;
use Utopia\Config\Config;
use Utopia\Database\Database;
use Utopia\Database\Document;
use Utopia\Database\Exception\Duplicate;
@ -19,6 +20,49 @@ use Utopia\VCS\Exception\RepositoryNotFound;
class Base extends Action
{
/**
* Get default specification based on plan and available specifications.
*
* @param array $plan The billing plan configuration
* @return string The appropriate default specification
*/
protected function getDefaultSpecification(array $plan): string
{
$specifications = Config::getParam('specifications', []);
if (empty($specifications)) {
return APP_COMPUTE_SPECIFICATION_DEFAULT;
}
// If there's a plan with runtime specifications, use the highest one from the plan
if (!empty($plan) && array_key_exists('runtimeSpecifications', $plan) && !empty($plan['runtimeSpecifications'])) {
$planSpecifications = $plan['runtimeSpecifications'];
// Find the highest specification in the plan
foreach (array_reverse(array_keys($specifications)) as $specKey) {
if (in_array($specKey, $planSpecifications)) {
return $specKey;
}
}
}
// If no plan or plan-based specification, use the highest available specification
$maxCpus = (float) System::getEnv('_APP_COMPUTE_CPUS', 0);
$maxMemory = (int) System::getEnv('_APP_COMPUTE_MEMORY', 0);
$highestSpec = APP_COMPUTE_SPECIFICATION_DEFAULT;
foreach (array_reverse(array_keys($specifications)) as $specKey) {
$spec = $specifications[$specKey];
$withinCpuLimit = empty($maxCpus) || $spec['cpus'] <= $maxCpus;
$withinMemoryLimit = empty($maxMemory) || $spec['memory'] <= $maxMemory;
if ($withinCpuLimit && $withinMemoryLimit) {
$highestSpec = $specKey;
break;
}
}
return $highestSpec;
}
public function redeployVcsFunction(Request $request, Document $function, Document $project, Document $installation, Database $dbForProject, Build $queueForBuilds, Document $template, GitHub $github, bool $activate, string $referenceType = 'branch', string $reference = ''): Document
{
$deploymentId = ID::unique();

View file

@ -92,7 +92,7 @@ class Create extends Base
->param('providerBranch', '', new Text(128, 0), 'Production branch for the repo linked to the function.', true)
->param('providerSilentMode', false, new Boolean(), 'Is the VCS (Version Control System) connection in silent mode for the repo linked to the function? In silent mode, comments will not be made on commits and pull requests.', true)
->param('providerRootDirectory', '', new Text(128, 0), 'Path to function code in the linked repo.', true)
->param('specification', APP_COMPUTE_SPECIFICATION_DEFAULT, fn (array $plan) => new Specification(
->param('specification', fn (array $plan) => $this->getDefaultSpecification($plan), fn (array $plan) => new Specification(
$plan,
Config::getParam('specifications', []),
System::getEnv('_APP_COMPUTE_CPUS', 0),

View file

@ -89,7 +89,7 @@ class Update extends Base
->param('providerBranch', '', new Text(128, 0), 'Production branch for the repo linked to the function', true)
->param('providerSilentMode', false, new Boolean(), 'Is the VCS (Version Control System) connection in silent mode for the repo linked to the function? In silent mode, comments will not be made on commits and pull requests.', true)
->param('providerRootDirectory', '', new Text(128, 0), 'Path to function code in the linked repo.', true)
->param('specification', APP_COMPUTE_SPECIFICATION_DEFAULT, fn (array $plan) => new Specification(
->param('specification', fn (array $plan) => $this->getDefaultSpecification($plan), fn (array $plan) => new Specification(
$plan,
Config::getParam('specifications', []),
System::getEnv('_APP_COMPUTE_CPUS', 0),

View file

@ -78,7 +78,7 @@ class Create extends Base
->param('providerBranch', '', new Text(128, 0), 'Production branch for the repo linked to the site.', true)
->param('providerSilentMode', false, new Boolean(), 'Is the VCS (Version Control System) connection in silent mode for the repo linked to the site? In silent mode, comments will not be made on commits and pull requests.', true)
->param('providerRootDirectory', '', new Text(128, 0), 'Path to site code in the linked repo.', true)
->param('specification', APP_COMPUTE_SPECIFICATION_DEFAULT, fn (array $plan) => new Specification(
->param('specification', fn (array $plan) => $this->getDefaultSpecification($plan), fn (array $plan) => new Specification(
$plan,
Config::getParam('specifications', []),
System::getEnv('_APP_COMPUTE_CPUS', 0),

View file

@ -82,7 +82,7 @@ class Update extends Base
->param('providerBranch', '', new Text(128, 0), 'Production branch for the repo linked to the site.', true)
->param('providerSilentMode', false, new Boolean(), 'Is the VCS (Version Control System) connection in silent mode for the repo linked to the site? In silent mode, comments will not be made on commits and pull requests.', true)
->param('providerRootDirectory', '', new Text(128, 0), 'Path to site code in the linked repo.', true)
->param('specification', APP_COMPUTE_SPECIFICATION_DEFAULT, fn (array $plan) => new Specification(
->param('specification', fn (array $plan) => $this->getDefaultSpecification($plan), fn (array $plan) => new Specification(
$plan,
Config::getParam('specifications', []),
System::getEnv('_APP_COMPUTE_CPUS', 0),