Skip to content

feat: add removeOrphans option to project deploy/redeploy#2785

Merged
kmendell merged 2 commits into
getarcaneapp:mainfrom
khanhx:feat/redeploy-remove-orphans
Jun 2, 2026
Merged

feat: add removeOrphans option to project deploy/redeploy#2785
kmendell merged 2 commits into
getarcaneapp:mainfrom
khanhx:feat/redeploy-remove-orphans

Conversation

@khanhx
Copy link
Copy Markdown
Contributor

@khanhx khanhx commented Jun 2, 2026

Summary

Adds an opt-in, per-request removeOrphans flag to the project deploy/redeploy API so non-GitOps projects can remove orphan containers (services deleted from the compose file) on redeploy.

Today removeOrphans is hardcoded true only for GitOps-managed projects (project_service.go, derived from GitOpsManagedBy). Imperative, API-driven redeploys of regular projects therefore leave orphan containers running — there is no way to request their removal. This adds the missing knob, mirroring the existing forceRecreate option on DeployOptions.

Changes

  • types/project/project.go — add RemoveOrphans bool \json:"removeOrphans,omitempty"`toDeployOptions(mirrorsForceRecreate`).
  • backend/internal/services/project_service.go — extract resolveRemoveOrphans(gitOpsManaged, options): returns true if the project is GitOps-managed or the caller opted in. RedeployProject now accepts *project.DeployOptions and forwards it to DeployProject instead of nil.
  • backend/api/handlers/projects.goRedeployProjectInput gains an optional Body *project.DeployOptions (same shape as the existing DeployProjectInput.Body); passed through to the service.
  • gitops_sync_service.go, webhook_service.go — existing internal callers pass nil (behavior unchanged; GitOps projects still remove orphans via the GitOpsManagedBy condition).

Behavior

Purely additive and non-breaking. The flag can only turn removeOrphans from falsetrue, never the reverse. Empty/absent body ⇒ nil options ⇒ current default behavior preserved.

POST /environments/{id}/projects/{projectId}/redeploy with {"removeOrphans": true} now removes orphans; an empty body behaves exactly as before. /down is left as-is (already removes orphans unconditionally).

Tests

  • TestResolveRemoveOrphans — table test covering the precedence matrix (gitops × flag).
  • TestComposeUpOptions_RemoveOrphans — asserts the flag propagates into compose CreateOptions.RemoveOrphans.

go build, go vet, gofmt, and the services + pkg/projects test suites all pass.

Notes

  • Frontend/SDK wiring (a UI checkbox in the deploy-options store) is intentionally deferred — this is a backend-only, opt-in API addition. Happy to add it in a follow-up if desired.
  • Open to changing the design if maintainers would prefer redeploy to remove orphans unconditionally; chose the opt-in flag to stay non-breaking.

Disclaimer Greptiles Reviews use AI, make sure to check over its work.

To better help train Greptile on our codebase, if the comment is useful and valid Like the comment, if its not helpful or invalid Dislike

To have Greptile Re-Review the changes, mention greptileai.

Greptile Summary

This PR adds an opt-in removeOrphans field to DeployOptions and threads it through the redeploy API path, allowing non-GitOps projects to request removal of orphan containers on redeploy. The existing behavior for GitOps-managed projects and all other internal callers is fully preserved.

  • resolveRemoveOrphansInternal centralises the precedence logic (gitOpsManaged || options.RemoveOrphans), and the new TestResolveRemoveOrphans table test covers all six combinations of the flag matrix.
  • RedeployProjectInput gains an optional Body *project.DeployOptions, following the exact same pattern as the existing DeployProjectInput; absent/empty body remains nil and behaviour is unchanged.
  • As a side-effect, forceRecreate is now also accepted via the redeploy endpoint (since the full DeployOptions struct is forwarded), which is not called out in the PR description but is consistent with the deploy endpoint's API surface.

Confidence Score: 5/5

The change is purely additive: no existing call site is altered in behaviour, and all internal callers (GitOps sync, webhook) continue to pass nil options.

The logic is straightforward and well-tested. The resolveRemoveOrphansInternal helper is trivial and covered by a complete 6-case table test. Nil handling throughout is correct, and the HTTP handler follows an identical pattern already used by the deploy endpoint.

No files require special attention.

Reviews (2): Last reviewed commit: "refactor: rename resolveRemoveOrphans to..." | Re-trigger Greptile

Allow non-GitOps projects to opt into removing orphan containers
(services deleted from the compose file) on deploy/redeploy via a
per-request removeOrphans flag on DeployOptions, mirroring the existing
forceRecreate option.

Previously removeOrphans was hardcoded true only for GitOps-managed
projects, so imperative API-driven redeploys left orphan containers
running. The flag is additive and opt-in; default behavior is unchanged.

The redeploy endpoint now accepts an optional DeployOptions body, and
RedeployProject forwards options to DeployProject. Existing GitOps and
webhook callers pass nil, preserving their behavior (GitOps projects
still remove orphans via the GitOpsManagedBy condition).
@khanhx khanhx marked this pull request as ready for review June 2, 2026 02:35
@khanhx khanhx requested a review from a team June 2, 2026 02:35
Comment thread backend/internal/services/project_service.go Outdated
Follow the codebase convention of suffixing unexported helpers with
Internal (e.g. ensureProjectMutableInternal).
@kmendell kmendell enabled auto-merge (squash) June 2, 2026 14:25
@kmendell kmendell merged commit 1d808bb into getarcaneapp:main Jun 2, 2026
21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants