Skip to content

Fix installer state#11634

Merged
abnegate merged 2 commits into1.9.xfrom
fix-installer-state
Mar 24, 2026
Merged

Fix installer state#11634
abnegate merged 2 commits into1.9.xfrom
fix-installer-state

Conversation

@abnegate
Copy link
Copy Markdown
Member

What does this PR do?

(Provide a description of what this PR does and why it's needed.)

Test Plan

(Write your test plan here. If you changed any code, please provide us with clear instructions on how you verified your changes work. Screenshots may also be helpful.)

Related PRs and Issues

  • (Related PR or issue)

Checklist

  • Have you read the Contributing Guidelines on issues?
  • If the PR includes a change to an API's metadata (desc, label, params, etc.), does it also include updated API specs and example docs?

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 24, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 3ca60fc1-0a67-4433-9302-0f380852e44b

📥 Commits

Reviewing files that changed from the base of the PR and between a92ad3a and 10a6e88.

📒 Files selected for processing (2)
  • app/views/install/installer/js/modules/progress.js
  • src/Appwrite/Platform/Installer/Server.php

📝 Walkthrough

Walkthrough

Changes to the installer flow across two files: (1) In progress.js, when resuming an existing install fails, the code now clears the stored install ID and install lock, then redirects to /?step=1 instead of directly initiating a fresh install. (2) In Server.php, a new autoDetectUpgrade() method and supporting detectDatabaseFromFiles() utility are introduced to detect and initialize upgrade state during Swoole server startup by examining docker-compose.yml and .env files for database configuration.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-installer-state

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@abnegate abnegate merged commit 7fcc640 into 1.9.x Mar 24, 2026
2 of 3 checks passed
@abnegate abnegate deleted the fix-installer-state branch March 24, 2026 13:09
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 24, 2026

Greptile Summary

This PR fixes installer state handling in two areas: on the frontend it redirects users back to step 1 (instead of silently starting a fresh install) when an existing install session cannot be resumed, and on the backend it adds auto-detection of existing Appwrite installations at server startup to correctly set the upgrade flag and locked database type from docker-compose.yml / .env files.

  • progress.js: When resumeInstall fails, state is now cleared and the user is redirected to /?step=1 rather than immediately launching a new install stream — a safer, more predictable recovery path.
  • Server.php: New autoDetectUpgrade method inspects the filesystem for an existing docker-compose.yml or .env and sets isUpgrade=true and lockedDatabase accordingly, preventing the installer from treating an upgrade as a fresh install.
  • Style — early return may skip lockedDatabase detection: If isUpgrade is already true in the persisted config but lockedDatabase is null, autoDetectUpgrade returns early without attempting to detect the database, potentially leaving it unset.
  • Style — redundant regex fallback: The second foreach loop in detectDatabaseFromFiles checking for mariadb: / mongodb: / postgresql: YAML keys is effectively unreachable because the preceding preg_match_all regex already captures those same identifiers via its (\w+): alternative.

Confidence Score: 4/5

  • Safe to merge with minor style issues; no functional bugs or security concerns identified.
  • The frontend change is a straightforward, clean redirect fix. The backend additions are logically sound for the common case. Two style-level concerns exist: a potential gap when isUpgrade is pre-set without lockedDatabase, and a redundant regex loop — neither will cause a runtime error in typical scenarios.
  • src/Appwrite/Platform/Installer/Server.php — review the early-return logic in autoDetectUpgrade and the redundant fallback loop in detectDatabaseFromFiles.

Important Files Changed

Filename Overview
app/views/install/installer/js/modules/progress.js When an existing install ID cannot be resumed, the code now clears state and redirects to step 1 instead of immediately starting a fresh install — a clean, intentional UX fix with no issues.
src/Appwrite/Platform/Installer/Server.php Adds autoDetectUpgrade and detectDatabaseFromFiles to automatically detect existing installations at startup. Two style issues: an early return in autoDetectUpgrade may skip lockedDatabase detection when isUpgrade is already set, and a second regex loop in detectDatabaseFromFiles is unreachable under normal conditions.

Reviews (1): Last reviewed commit: "(fix): auto-detect upgrade mode and data..." | Re-trigger Greptile

Comment on lines +241 to +245
foreach ($dbServices as $db) {
if (preg_match('/^\s*' . preg_quote($db, '/') . ':\s*$/m', $composeData)) {
return $db;
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Redundant fallback regex loop

The second foreach loop (lines 241–245) is unreachable in practice. The first preg_match_all regex already includes the alternative (\w+): which will match any YAML key at the start of a line — including mariadb:, mongodb:, and postgresql:. In a valid docker-compose.yml, preg_match_all will almost always return a positive count (e.g. from version:, services:, etc.), enter the if block, and evaluate the same service names against $dbServices.

The second loop can only execute if preg_match_all returns false (a regex engine error) or 0 (no matches at all — essentially impossible in a non-empty compose file). Consider removing it to simplify the logic:

Suggested change
foreach ($dbServices as $db) {
if (preg_match('/^\s*' . preg_quote($db, '/') . ':\s*$/m', $composeData)) {
return $db;
}
}
}
$envData = @file_get_contents($envPath);

Comment on lines +203 to +205
if ($config->isUpgrade()) {
return;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Early return skips lockedDatabase detection when isUpgrade is already set

If isUpgrade is already true (set explicitly in the saved config) but lockedDatabase is null, this early return means the database auto-detection never runs. The lockedDatabase will remain null even though the installation files are present and the database could be inferred.

If there is a scenario where isUpgrade can be persisted as true without a corresponding lockedDatabase value, the installer may behave incorrectly. Consider checking lockedDatabase independently:

private function autoDetectUpgrade(Config $config): void
{
    $basePath = $config->isLocal() ? '/usr/src/code' : (getcwd() ?: '.');
    $composePath = $basePath . '/docker-compose.yml';
    $envPath = $basePath . '/.env';

    if (!file_exists($composePath) && !file_exists($envPath)) {
        return;
    }

    if (!$config->isUpgrade()) {
        $config->setIsUpgrade(true);
    }

    if ($config->getLockedDatabase() !== null) {
        return;
    }

    $database = $this->detectDatabaseFromFiles($composePath, $envPath);
    if ($database !== null) {
        $config->setLockedDatabase($database);
    }
}

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 24, 2026

🔄 PHP-Retry Summary

Flaky tests detected across commits:

Commit 10a6e88 - 4 flaky tests
Test Retries Total Time Details
TablesDBConsoleClientTest::testPatchAttribute 1 91ms Logs
TablesDBCustomServerTest::testManyToOneRelationship 1 1.45s Logs
TablesDBCustomServerTest::testUpdateWithExistingRelationships 1 240.84s Logs
UsageTest::testVectorsDBStats 1 10.34s Logs

@github-actions
Copy link
Copy Markdown

✨ Benchmark results

  • Requests per second: 1,705
  • Requests with 200 status code: 307,040
  • P99 latency: 0.099718856

⚡ Benchmark Comparison

Metric This PR Latest version
RPS 1,705 1,184
200 307,040 213,216
P99 0.099718856 0.187383953

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant