Skip to content

Feat: Auto-delete deployments#10959

Merged
Meldiron merged 6 commits intofeat-1.8.x-new-schemafrom
feat-auto-delete-depoyments
Dec 16, 2025
Merged

Feat: Auto-delete deployments#10959
Meldiron merged 6 commits intofeat-1.8.x-new-schemafrom
feat-auto-delete-depoyments

Conversation

@Meldiron
Copy link
Copy Markdown
Contributor

What does this PR do?

Adds support for auto-deleting old non-active deployments

Test Plan

New tests

Related PRs and Issues

x

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 Dec 15, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

Adds a new integer field deploymentRetention (days) to collections and public models: databases, functions, and sites (default 0). Introduces APP_COMPUTE_DEPLOYMENT_MAX_RETENTION (100 * 365). Extends Functions and Sites APIs (create/update) to accept, validate (Range 0..MAX), and persist deploymentRetention, and propagates it into deployment flows. Adds a development-only mock endpoint POST /v1/mock/time-travels to set a resource's createdAt for tests. Refactors Maintenance to accept a run type (loop vs triggered). Deletes worker gains retention-based pruning that enumerates old function/site deployments and enqueues deletions. Adds e2e tests for Functions and Sites covering creation, validation, update flows, and maintenance-driven pruning.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Areas needing extra attention:
    • Maintenance.php: verify new type parameter behavior, loop vs immediate execution, and preserved scheduling semantics.
    • Deletes.php: retention calculation, query correctness (exclude active deployments), pagination, and enqueue payload shape for delete events.
    • app/controllers/mock.php: environment guard, Datetime validation, project DB scoping, and preserve-dates update semantics.
    • Functions/Sites Create & Update: parameter registration, Range bounds using APP_COMPUTE_DEPLOYMENT_MAX_RETENTION, default handling, and propagation into deployment/template/VCS flows.
    • Collections/constants: ensure new deploymentRetention attributes for databases/functions/sites and the APP_COMPUTE_DEPLOYMENT_MAX_RETENTION value align with validators and defaults.
    • Response models and e2e tests: model rule additions, tests' use of the mock endpoint, and that maintenance invocation in tests triggers the intended deletion flow.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Feat: Auto-delete deployments' clearly and concisely summarizes the main feature added in this PR: automatic deletion of old non-active deployments.
Description check ✅ Passed The description explains the feature (auto-deleting old non-active deployments), mentions test coverage, and follows the contributing template; it is clearly related to the changeset.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat-auto-delete-depoyments

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a3a5e05 and c88a77a.

📒 Files selected for processing (2)
  • app/config/collections/projects.php (2 hunks)
  • src/Appwrite/Platform/Workers/Deletes.php (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/Appwrite/Platform/Workers/Deletes.php
  • app/config/collections/projects.php

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.


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.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Dec 15, 2025

Security Scan Results for PR

Docker Image Scan Results

Package Version Vulnerability Severity
imagemagick 7.1.2.3-r0 CVE-2025-62171 HIGH
imagemagick-c++ 7.1.2.3-r0 CVE-2025-62171 HIGH
imagemagick-dev 7.1.2.3-r0 CVE-2025-62171 HIGH
imagemagick-heic 7.1.2.3-r0 CVE-2025-62171 HIGH
imagemagick-jpeg 7.1.2.3-r0 CVE-2025-62171 HIGH
imagemagick-jxl 7.1.2.3-r0 CVE-2025-62171 HIGH
imagemagick-libs 7.1.2.3-r0 CVE-2025-62171 HIGH
imagemagick-openexr 7.1.2.3-r0 CVE-2025-62171 HIGH
imagemagick-webp 7.1.2.3-r0 CVE-2025-62171 HIGH
libecpg 17.6-r0 CVE-2025-12818 HIGH
libecpg-dev 17.6-r0 CVE-2025-12818 HIGH
libpng 1.6.47-r0 CVE-2025-64720 HIGH
libpng 1.6.47-r0 CVE-2025-65018 HIGH
libpng 1.6.47-r0 CVE-2025-66293 HIGH
libpng-dev 1.6.47-r0 CVE-2025-64720 HIGH
libpng-dev 1.6.47-r0 CVE-2025-65018 HIGH
libpng-dev 1.6.47-r0 CVE-2025-66293 HIGH
libpq 17.6-r0 CVE-2025-12818 HIGH
libpq-dev 17.6-r0 CVE-2025-12818 HIGH
libxml2 2.13.8-r0 CVE-2025-49794 CRITICAL
libxml2 2.13.8-r0 CVE-2025-49796 CRITICAL
libxml2 2.13.8-r0 CVE-2025-49795 HIGH
libxml2 2.13.8-r0 CVE-2025-6021 HIGH
postgresql17-dev 17.6-r0 CVE-2025-12818 HIGH
github.com/containerd/containerd/v2 v2.0.2 CVE-2024-25621 HIGH
golang.org/x/crypto v0.31.0 CVE-2025-22869 HIGH
golang.org/x/oauth2 v0.24.0 CVE-2025-22868 HIGH
stdlib 1.22.10 CVE-2025-47907 HIGH
stdlib 1.22.10 CVE-2025-58183 HIGH
stdlib 1.22.10 CVE-2025-58186 HIGH
stdlib 1.22.10 CVE-2025-58187 HIGH
stdlib 1.22.10 CVE-2025-61729 HIGH

Source Code Scan Results

🎉 No vulnerabilities found!

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (4)
docker-compose.yml (1)

74-75: Dev‑only vendor mount is fine; be aware of host–container coupling

Mounting ./vendor/utopia-php/database over the container’s vendor copy is handy for local development, but it assumes the host path exists and is up‑to‑date. If the directory is missing or contains a different version, PHP in the container will see that instead of the image’s dependencies.

If this becomes flaky across environments, consider guarding this mount behind a separate dev‑only compose override or documenting the expectation that composer install has been run on the host.

tests/e2e/Services/Functions/FunctionsConsoleClientTest.php (1)

9-10: Retention E2E test is valuable; consider tightening assertions and docker assumptions

The new testFunctionDeploymentRetentionWithMaintenance exercises the full retention path (time‑travel, maintenance trigger, delete worker), which is great.

Two optional robustness improvements:

  • After asserting total === 2, also assert that the remaining deployment IDs are the expected “active” and recent inactive ones, and that the time‑traveled old one is gone.
  • Because this test shells out to docker exec appwrite-task-maintenance ..., it implicitly assumes the docker CLI and that container name are available in the test environment. If you ever run this suite outside the dev docker‑compose setup, you may want a guard or skip condition when docker isn’t present.

Also applies to: 542-594

app/config/collections/projects.php (1)

570-580: Schema for deploymentRetention on functions/sites matches runtime expectations

The new deploymentRetention attributes on:

  • functions: integer, required, default null (but API always writes a value, defaulting to 0), and
  • sites: integer, optional, default 0

are consistent with how the feature is used (0 meaning “keep all deployments”) and with the delete worker reading via $resource->getAttribute('deploymentRetention', 0).

Just ensure your migration/patch path sets an explicit value for existing functions if you rely on required => true at the database level for new or updated documents.

Also applies to: 1095-1104

src/Appwrite/Platform/Modules/Functions/Http/Functions/Update.php (1)

49-105: Deployment retention wiring is correct; confirm desired update semantics

The new deploymentRetention parameter is correctly:

  • validated via Range(0, APP_COMPUTE_DEPLOYMENT_MAX_RETENTION),
  • threaded into action(...) as an int, and
  • persisted on the function document.

One behavioral point to confirm: because the param’s default is 0 and there’s no fallback to the existing value, calling updateFunction without specifying deploymentRetention will always reset it to 0 (unlimited). If the endpoint is intended as a full “PUT‑style” update this is fine; if you want PATCH‑like behavior where omitted fields remain unchanged, you’d instead use a nullable param and only overwrite when a value is explicitly provided.

If you decide you want PATCH‑style behavior later, we can switch the validator to new Nullable(new Range(...)) and only assign $deploymentRetention into the update payload when it’s non‑null.

Also applies to: 117-138, 267-292

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 914723c and 0ec7559.

📒 Files selected for processing (14)
  • app/config/collections/projects.php (2 hunks)
  • app/controllers/mock.php (2 hunks)
  • app/init/constants.php (1 hunks)
  • docker-compose.yml (1 hunks)
  • src/Appwrite/Platform/Modules/Functions/Http/Functions/Create.php (3 hunks)
  • src/Appwrite/Platform/Modules/Functions/Http/Functions/Update.php (4 hunks)
  • src/Appwrite/Platform/Modules/Sites/Http/Sites/Create.php (3 hunks)
  • src/Appwrite/Platform/Modules/Sites/Http/Sites/Update.php (3 hunks)
  • src/Appwrite/Platform/Tasks/Maintenance.php (4 hunks)
  • src/Appwrite/Platform/Workers/Deletes.php (5 hunks)
  • src/Appwrite/Utopia/Response/Model/Func.php (1 hunks)
  • src/Appwrite/Utopia/Response/Model/Site.php (1 hunks)
  • tests/e2e/Services/Functions/FunctionsConsoleClientTest.php (2 hunks)
  • tests/e2e/Services/Functions/FunctionsCustomServerTest.php (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (7)
src/Appwrite/Utopia/Response/Model/Func.php (1)
src/Appwrite/Utopia/Response/Model.php (1)
  • addRule (90-102)
src/Appwrite/Platform/Modules/Sites/Http/Sites/Create.php (1)
src/Appwrite/GraphQL/Types/Mapper.php (1)
  • param (255-363)
src/Appwrite/Utopia/Response/Model/Site.php (1)
src/Appwrite/Utopia/Response/Model.php (1)
  • addRule (90-102)
src/Appwrite/Platform/Workers/Deletes.php (2)
src/Appwrite/Event/Event.php (1)
  • Event (10-654)
src/Appwrite/Platform/Modules/Functions/Http/Functions/Delete.php (1)
  • Delete (21-100)
src/Appwrite/Platform/Modules/Sites/Http/Sites/Update.php (1)
src/Appwrite/GraphQL/Types/Mapper.php (1)
  • param (255-363)
src/Appwrite/Platform/Modules/Functions/Http/Functions/Create.php (1)
src/Appwrite/GraphQL/Types/Mapper.php (1)
  • param (255-363)
src/Appwrite/Platform/Modules/Functions/Http/Functions/Update.php (1)
src/Appwrite/GraphQL/Types/Mapper.php (1)
  • param (255-363)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Setup & Build Appwrite Image
  • GitHub Check: Setup & Build Appwrite Image
  • GitHub Check: scan
🔇 Additional comments (12)
src/Appwrite/Platform/Tasks/Maintenance.php (1)

16-35: Type‑driven maintenance execution (loop vs trigger) is wired correctly

The new type param, closure extraction, and conditional Console::loop vs direct $action() keep existing behavior for looped runs while enabling one‑shot triggers (used in tests) without side effects. Param/injection order is consistent with the callback signature.

Also applies to: 37-109

app/init/constants.php (1)

88-88: Deployment max retention constant is reasonable and consistent

APP_COMPUTE_DEPLOYMENT_MAX_RETENTION = 100 * 365 matches the “days” semantics used elsewhere and gives a sane upper bound for validation without being effectively unbounded.

src/Appwrite/Utopia/Response/Model/Func.php (1)

68-73: Function model exposes deploymentRetention consistently with API semantics

Adding deploymentRetention as an integer field with default 0 and “0 = keep all deployments” description lines up with the HTTP param and backend logic. This should give clients the right expectations when reading function documents.

src/Appwrite/Utopia/Response/Model/Site.php (1)

61-66: LGTM! Deployment retention field properly added to Site model.

The deploymentRetention rule is correctly defined with appropriate type, description, default value, and example. The positioning between framework and deploymentId maintains logical field ordering.

src/Appwrite/Platform/Modules/Sites/Http/Sites/Create.php (2)

94-94: LGTM! Deployment retention parameter properly integrated.

The parameter is correctly defined with Range validation using the global APP_COMPUTE_DEPLOYMENT_MAX_RETENTION constant, clear documentation, and appropriate default value.


124-124: LGTM! Parameter correctly wired through action.

The deploymentRetention parameter flows correctly from the action signature (line 124) to document persistence (line 159), maintaining consistency with other site attributes.

Also applies to: 159-159

app/controllers/mock.php (1)

202-242: LGTM! Useful mock endpoint for testing time-dependent features.

The time-travel endpoint provides a clean way to test deployment retention logic by manipulating timestamps. Key safeguards are in place:

  • Development-environment restriction (lines 215-219)
  • Project validation (lines 221-225)
  • Resource type whitelist (lines 227-230)
  • Proper use of preserveDates context (line 239)
src/Appwrite/Platform/Modules/Sites/Http/Sites/Update.php (2)

98-98: LGTM! Deployment retention update parameter properly defined.

The parameter follows the same validation pattern as the Create endpoint, maintaining API consistency.


132-132: LGTM! Update flow correctly handles deployment retention.

The parameter flows correctly from action signature (line 132) to document update (line 275), consistent with other updateable site attributes.

Also applies to: 275-275

src/Appwrite/Platform/Modules/Functions/Http/Functions/Create.php (2)

112-112: LGTM! Deployment retention parameter properly integrated for Functions.

The parameter definition mirrors the Sites module implementation, ensuring consistent API behavior across compute resources.


152-152: LGTM! Function creation correctly persists deployment retention.

The parameter flows correctly from action signature (line 152) to function document creation (line 223), maintaining consistency with the Sites module and other function attributes.

Also applies to: 223-223

tests/e2e/Services/Functions/FunctionsCustomServerTest.php (1)

2633-2746: Comprehensive test coverage for deployment retention feature.

The test effectively covers:

  • Default behavior validation
  • Successful creation with various retention values (0, 180)
  • Validation of boundary conditions (negative and excessive values)
  • Update workflow scenarios

The behavior at lines 2720-2728 where updating without the deploymentRetention parameter resets it to 0 is intentional by design—the parameter has a default value of 0 and is explicitly assigned on each update, rather than being conditionally preserved like some other optional parameters (e.g., runtime). The test correctly validates this implementation behavior.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
tests/e2e/Services/Sites/SitesConsoleClientTest.php (1)

144-196: Strengthen assertions to verify the correct deployments are retained/deleted

The maintenance retention flow is generally well covered, but the final check only asserts total === 2. That would still pass if the wrong deployment were deleted (e.g., the active one) as long as any two remain.

To make the test more robust, consider also asserting which IDs exist after maintenance, for example:

-        $this->assertEventually(function () use ($siteId) {
-            $response = $this->listDeployments($siteId);
-            $this->assertSame(200, $response['headers']['status-code']);
-            $this->assertSame(2, $response['body']['total']);
-        });
+        $this->assertEventually(function () use ($siteId, $deploymentIdInactive, $deploymentIdInactiveOld, $deploymentIdActive) {
+            $response = $this->listDeployments($siteId);
+            $this->assertSame(200, $response['headers']['status-code']);
+            $this->assertSame(2, $response['body']['total']);
+
+            // Old inactive deployment should be gone
+            $deleted = $this->getDeployment($siteId, $deploymentIdInactiveOld);
+            $this->assertSame(404, $deleted['headers']['status-code']);
+
+            // Recent inactive + active deployments should remain
+            $still1 = $this->getDeployment($siteId, $deploymentIdInactive);
+            $this->assertSame(200, $still1['headers']['status-code']);
+
+            $still2 = $this->getDeployment($siteId, $deploymentIdActive);
+            $this->assertSame(200, $still2['headers']['status-code']);
+        });

This guards both deletion correctness (only old non‑active is removed) and preservation of the active deployment.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0ec7559 and 6cbc790.

📒 Files selected for processing (2)
  • tests/e2e/Services/Sites/SitesConsoleClientTest.php (2 hunks)
  • tests/e2e/Services/Sites/SitesCustomServerTest.php (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
  • GitHub Check: Benchmark
  • GitHub Check: E2E Service Test (FunctionsSchedule)
  • GitHub Check: E2E Service Test (Messaging)
  • GitHub Check: E2E Service Test (VCS)
  • GitHub Check: E2E Service Test (Webhooks)
  • GitHub Check: E2E Service Test (Proxy)
  • GitHub Check: E2E Service Test (Projects)
  • GitHub Check: E2E Service Test (Teams)
  • GitHub Check: E2E Service Test (Locale)
  • GitHub Check: E2E Service Test (Realtime)
  • GitHub Check: E2E Service Test (Console)
  • GitHub Check: E2E Service Test (Functions)
  • GitHub Check: E2E Service Test (Databases/TablesDB)
  • GitHub Check: E2E Service Test (Databases/Legacy)
  • GitHub Check: E2E Service Test (GraphQL)
  • GitHub Check: E2E Service Test (Account)
  • GitHub Check: E2E Service Test (Site Screenshots)
  • GitHub Check: E2E General Test
  • GitHub Check: E2E Service Test (Dev Keys)
  • GitHub Check: scan
🔇 Additional comments (1)
tests/e2e/Services/Sites/SitesConsoleClientTest.php (1)

9-9: Import of Utopia\CLI\Console is appropriate

The new use Utopia\CLI\Console; import is required for Console::execute in the maintenance test and is correctly scoped here.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Dec 15, 2025

✨ Benchmark results

  • Requests per second: 1,197
  • Requests with 200 status code: 215,426
  • P99 latency: 0.162896187

⚡ Benchmark Comparison

Metric This PR Latest version
RPS 1,197 1,172
200 215,426 210,938
P99 0.162896187 0.174758783

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/Appwrite/Platform/Workers/Deletes.php (1)

315-374: Previous critical issues are now fixed. Consider adding explicit type cast for retention.

The implementation now correctly:

  1. Scopes deletions by resourceInternalId and resourceType (lines 338-339)
  2. Sets project context via setProject($project) before triggering (line 355)

However, there's a minor type safety concern:

-            $retention = $resource->getAttribute('deploymentRetention', 0);
+            $retention = (int) $resource->getAttribute('deploymentRetention', 0);

The strict equality check $retention === 0 on line 324 could behave unexpectedly if the attribute is stored/returned as a string "0" instead of integer 0.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6cbc790 and bd2db5e.

📒 Files selected for processing (3)
  • app/controllers/mock.php (2 hunks)
  • src/Appwrite/Platform/Workers/Deletes.php (5 hunks)
  • tests/e2e/Services/Sites/SitesCustomServerTest.php (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/Appwrite/Platform/Workers/Deletes.php (1)
src/Appwrite/Event/Event.php (1)
  • Event (10-654)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
  • GitHub Check: E2E Service Test (Messaging)
  • GitHub Check: E2E Service Test (Webhooks)
  • GitHub Check: E2E Service Test (Proxy)
  • GitHub Check: E2E Service Test (Teams)
  • GitHub Check: E2E Service Test (Functions)
  • GitHub Check: E2E Service Test (Health)
  • GitHub Check: E2E Service Test (Databases/TablesDB)
  • GitHub Check: E2E Service Test (Avatars)
  • GitHub Check: E2E Service Test (Databases/Legacy)
  • GitHub Check: E2E Service Test (Locale)
  • GitHub Check: E2E Service Test (Projects)
  • GitHub Check: E2E Service Test (GraphQL)
  • GitHub Check: E2E Service Test (Account)
  • GitHub Check: E2E Service Test (Realtime)
  • GitHub Check: E2E Service Test (Console)
  • GitHub Check: E2E Service Test (Site Screenshots)
  • GitHub Check: Unit Test
  • GitHub Check: E2E Service Test (Dev Keys)
  • GitHub Check: E2E General Test
  • GitHub Check: scan
🔇 Additional comments (2)
tests/e2e/Services/Sites/SitesCustomServerTest.php (1)

3080-3208: LGTM! The test comprehensively covers deploymentRetention lifecycle.

The test validates:

  • Default value (0) when not specified
  • Explicit valid values (0, 180)
  • Invalid boundary values (999999, -1) returning 400
  • Update flow including value changes
  • Cleanup of all created sites

The typo from the previous review ($siteId[] vs $siteIds[]) has been correctly fixed.

One behavior to verify: Lines 3176-3186 test that omitting deploymentRetention in an update request resets it to 0. Ensure this "reset to default on omission" is the intended API contract rather than "preserve existing value if not provided."

app/controllers/mock.php (1)

235-239: Potential issue: Partial document update may not work as intended.

The $update Document only contains $createdAt. Depending on how updateDocument behaves, this could either:

  1. Merge only the provided field (intended behavior)
  2. Overwrite the entire document, losing all other attributes

Consider fetching the existing document first and updating just the $createdAt field:

-        $update = new Document([
-            '$createdAt' => $createdAt,
-        ]);
-
-        $dbForProject->withPreserveDates(fn () => $dbForProject->updateDocument($collection, $resourceId, $update));
+        $resource = $dbForProject->getDocument($collection, $resourceId);
+
+        if ($resource->isEmpty()) {
+            throw new Exception(Exception::GENERAL_NOT_FOUND);
+        }
+
+        $resource->setAttribute('$createdAt', $createdAt);
+
+        $dbForProject->withPreserveDates(fn () => $dbForProject->updateDocument($collection, $resourceId, $resource));

Verify that passing a partial Document to updateDocument correctly merges only the provided attributes without affecting other fields.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
src/Appwrite/Platform/Workers/Deletes.php (2)

317-318: Consider using modern PHPDoc style or removing redundant annotation.

The inline /* @var */ comment is immediately followed by the assignment, making it redundant. Modern IDEs can infer the type from the callable return type.

Apply this diff to use standard PHPDoc:

-        /* @var $dbForProject Database */
-        $dbForProject = $getProjectDB($project);
+        /** @var Database $dbForProject */
+        $dbForProject = $getProjectDB($project);

Or simply remove it:

-        /* @var $dbForProject Database */
         $dbForProject = $getProjectDB($project);

321-321: Add defensive type casting for deploymentRetention attribute.

The getAttribute call should cast to int for safety. Without it, if the attribute is somehow stored as the string "0", the strict equality check on line 324 would fail, causing the code to proceed with deletion when retention should be unlimited.

Apply this diff:

-            $retention = $resource->getAttribute('deploymentRetention', 0);
+            $retention = (int) $resource->getAttribute('deploymentRetention', 0);
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bd2db5e and a3a5e05.

📒 Files selected for processing (1)
  • src/Appwrite/Platform/Workers/Deletes.php (5 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-05-13T12:02:08.071Z
Learnt from: ItzNotABug
Repo: appwrite/appwrite PR: 9752
File: app/config/collections/platform.php:1423-1423
Timestamp: 2025-05-13T12:02:08.071Z
Learning: In the Appwrite database schema, field names like 'resourceInternalId'/'resourceType' and 'deploymentInternalId'/'deploymentResourceType' are functionally equivalent and can coexist in the codebase without causing errors. The docker build and stack work fine with these naming inconsistencies.

Applied to files:

  • src/Appwrite/Platform/Workers/Deletes.php
📚 Learning: 2025-06-19T09:20:03.312Z
Learnt from: ItzNotABug
Repo: appwrite/appwrite PR: 9693
File: src/Appwrite/Platform/Modules/Databases/Http/Databases/Tables/Update.php:57-59
Timestamp: 2025-06-19T09:20:03.312Z
Learning: In table-related endpoints (such as `src/Appwrite/Platform/Modules/Databases/Http/Databases/Tables/Update.php`), parameter descriptions should use "table" and "row" terminology instead of "collection" and "document" for clarity and consistency.

Applied to files:

  • src/Appwrite/Platform/Workers/Deletes.php
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
  • GitHub Check: E2E Service Test (Messaging)
  • GitHub Check: E2E Service Test (VCS)
  • GitHub Check: E2E Service Test (Health)
  • GitHub Check: E2E Service Test (Migrations)
  • GitHub Check: E2E Service Test (Proxy)
  • GitHub Check: E2E Service Test (Tokens)
  • GitHub Check: E2E Service Test (Sites)
  • GitHub Check: E2E Service Test (Teams)
  • GitHub Check: E2E Service Test (Avatars)
  • GitHub Check: E2E Service Test (Projects)
  • GitHub Check: E2E Service Test (Console)
  • GitHub Check: E2E Service Test (Functions)
  • GitHub Check: E2E Service Test (GraphQL)
  • GitHub Check: E2E Service Test (FunctionsSchedule)
  • GitHub Check: E2E Service Test (Databases/TablesDB)
  • GitHub Check: Unit Test
  • GitHub Check: E2E Service Test (Site Screenshots)
  • GitHub Check: E2E Service Test (Dev Keys)
  • GitHub Check: E2E General Test
  • GitHub Check: scan
🔇 Additional comments (3)
src/Appwrite/Platform/Workers/Deletes.php (3)

9-9: LGTM: DeleteEvent dependency injection is correctly wired.

The import, injection, and action signature properly integrate the queueForDeletes event handler into the worker.

Also applies to: 67-67, 90-91


195-195: LGTM: Maintenance flow integration is correct.

The deleteOldDeployments call is properly placed within the maintenance workflow and receives the correct parameters.


315-368: Well-structured retention-based cleanup implementation.

The deleteOldDeployments method correctly:

  • Scopes deletions to each specific resource via resourceInternalId and resourceType (lines 332-333)
  • Sets project context on queued delete events (line 349)
  • Excludes active deployments (lines 337-339)
  • Processes both functions and sites collections (lines 355-367)

The critical issues from the previous review (missing resource scoping and project context) have been addressed.

@loks0n loks0n requested a review from Copilot December 16, 2025 11:38
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds support for auto-deleting old non-active deployments for both functions and sites. The feature allows users to configure a retention period (in days) for non-active deployments, with a value of 0 meaning unlimited retention. The auto-deletion is handled by the existing maintenance worker that runs periodically, with an enhanced capability to trigger manually for testing purposes.

Key Changes:

  • Added deploymentRetention field to functions and sites collections with configurable retention period (0-36,500 days)
  • Implemented automatic cleanup logic in the Deletes worker to remove deployments older than the specified retention period
  • Enhanced the Maintenance task with a --type parameter supporting both "loop" (continuous) and "trigger" (one-time) execution modes

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
app/config/collections/projects.php Added deploymentRetention field to both functions and sites collection schemas
app/init/constants.php Defined APP_COMPUTE_DEPLOYMENT_MAX_RETENTION constant (36,500 days = 100 years)
src/Appwrite/Utopia/Response/Model/Func.php Added deploymentRetention field to Function API response model
src/Appwrite/Utopia/Response/Model/Site.php Added deploymentRetention field to Site API response model
src/Appwrite/Platform/Modules/Functions/Http/Functions/Create.php Added deploymentRetention parameter to function creation endpoint
src/Appwrite/Platform/Modules/Functions/Http/Functions/Update.php Added deploymentRetention parameter to function update endpoint
src/Appwrite/Platform/Modules/Sites/Http/Sites/Create.php Added deploymentRetention parameter to site creation endpoint
src/Appwrite/Platform/Modules/Sites/Http/Sites/Update.php Added deploymentRetention parameter to site update endpoint
src/Appwrite/Platform/Workers/Deletes.php Implemented deleteOldDeployments method to clean up expired deployments during maintenance
src/Appwrite/Platform/Tasks/Maintenance.php Enhanced with type parameter to support both continuous loop and one-time trigger execution
app/controllers/mock.php Added /mock/time-travels endpoint for testing by manipulating deployment creation timestamps
tests/e2e/Services/Functions/FunctionsCustomServerTest.php Added comprehensive tests for deployment retention parameter validation
tests/e2e/Services/Functions/FunctionsConsoleClientTest.php Added integration test verifying deployment cleanup via maintenance task
tests/e2e/Services/Sites/SitesCustomServerTest.php Added comprehensive tests for deployment retention parameter validation
tests/e2e/Services/Sites/SitesConsoleClientTest.php Added integration test verifying deployment cleanup via maintenance task

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@Meldiron Meldiron merged commit 175b0d9 into feat-1.8.x-new-schema Dec 16, 2025
38 checks passed
@Meldiron Meldiron mentioned this pull request Dec 16, 2025
2 tasks
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.

3 participants