Skip to content

feat: add --force to 'cd setup' to allow CD downgrades#1989

Merged
jordanstephens merged 1 commit intomainfrom
lio/force-cd
Mar 17, 2026
Merged

feat: add --force to 'cd setup' to allow CD downgrades#1989
jordanstephens merged 1 commit intomainfrom
lio/force-cd

Conversation

@lionello
Copy link
Copy Markdown
Member

@lionello lionello commented Mar 16, 2026

Description

defang cd setup --force allow one to update the CloudFormation template in an AWS account to match the CLI's. This is useful if the stack got accidentally upgraded by a nightly build, or the CLI must be downgrade to account for a regression, but the CloudFormation stack was too new.

We should release a new CLI with this flag before merging #1984

Also removing dead crun code to avoid having to update it for this PR.

Linked Issues

Checklist

  • I have performed a self-review of my code
  • I have added appropriate tests
  • I have updated the Defang CLI docs and/or README to reflect my changes, if necessary

Summary by CodeRabbit

  • New Features

    • Added force flag to CD resource installation to permit version downgrades.
  • Removed Features

    • Removed cloud run command-line interface and related implementations.
  • Chores

    • Updated CLI dependencies and refined cloud infrastructure driver architecture.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 16, 2026

📝 Walkthrough

Walkthrough

This PR introduces a "force" parameter throughout the CD installation flow to bypass CloudFormation template version mismatch errors, while simultaneously removing the entire crun package (local and Docker-based cloud runners) and its command-line entrypoint.

Changes

Cohort / File(s) Summary
Build and Nix Configuration
Makefile, pkgs/defang/cli.nix
Updated Makefile echo to wrap message in quotes preventing shell metacharacter interpretation; updated vendorHash for defang-cli Go module.
CD Installation Force Parameter - Interfaces & Core
src/pkg/cli/install_cd.go, src/pkg/cli/client/provider.go, src/pkg/clouds/driver.go
Added force bool parameter to InstallCD, Provider.SetUpCD, and Driver.SetUp interface methods to support forced installation bypassing version mismatches.
CD Installation Force Parameter - CLI Command Layer
src/cmd/cli/command/cd.go, src/cmd/cli/command/commands.go
Added "force" boolean flag to CD install subcommand and threaded it into InstallCD call.
CD Installation Force Parameter - Provider Implementations
src/pkg/cli/client/playground.go, src/pkg/cli/client/byoc/aws/byoc.go, src/pkg/cli/client/byoc/do/byoc.go, src/pkg/cli/client/byoc/gcp/byoc.go, src/pkg/cli/client/byoc/gcp/byoc_test.go
Updated SetUpCD method signatures across all provider implementations (Playground, AWS BYOC, DO BYOC, GCP BYOC) to accept force parameter; all call sites pass false preserving backward compatibility.
CD Installation Force Parameter - CloudFormation Driver
src/pkg/clouds/aws/ecs/cfn/setup.go, src/pkg/clouds/aws/ecs/cfn/setup_test.go
Updated SetUp, upsertStackAndWait, and updateStackAndWait to accept force parameter; added conditional logic to skip CloudFormation template version mismatch errors when force is true.
Dependency Updates
src/go.mod
Removed docker dependency (github.com/docker/docker v28.0.0) and related indirect dependencies; reorganized image-spec dependency from indirect to direct require block.
Crun Package Removal - CLI Entrypoint
src/cmd/crun/main.go
Removed entire Go-based crun command-line entrypoint including command parsing, subcommand dispatch (run, stop, logs, destroy, info), and environment variable handling.
Crun Package Removal - Core Utilities
src/pkg/crun/common.go, src/pkg/crun/common_test.go, src/pkg/crun/destroy.go, src/pkg/crun/factory.go, src/pkg/crun/info.go, src/pkg/crun/logs.go, src/pkg/crun/run.go, src/pkg/crun/stop.go
Removed shared utilities (memory/env parsing), driver factory with region-based dispatch, and top-level orchestration functions (Run, Stop, Logs, Destroy, PrintInfo).
Crun Package Removal - Docker Driver
src/pkg/crun/docker/common.go, src/pkg/crun/docker/info.go, src/pkg/crun/docker/run.go, src/pkg/crun/docker/run_test.go, src/pkg/crun/docker/setup.go, src/pkg/crun/docker/stop.go, src/pkg/crun/docker/tail.go, src/pkg/crun/docker/teardown.go
Removed entire Docker driver implementation including container lifecycle management (SetUp, Run, Stop, Tail), log streaming, platform parsing, and secret/upload stubs.
Crun Package Removal - Local Driver
src/pkg/crun/local/local.go, src/pkg/crun/local/local_test.go
Removed local (non-Windows) driver implementation for process-based execution including process lifecycle management, I/O piping, and signal handling.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • jordanstephens
  • edwardrf

Poem

🐰 A force flows through the CD's veins,
Threading parameters through domains—
While crun bids its final goodbye,
Docker drivers fade to the sky.
Interfaces bend to the new call's refrain! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately captures the main change: adding a --force flag to enable CD downgrades during setup operations.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch lio/force-cd
📝 Coding Plan
  • Generate coding plan for human review comments

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

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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/cmd/cli/command/cd.go (1)

198-203: ⚠️ Potential issue | 🟠 Major

Pass the --force flag to canIUseProvider to enable downgrade path.

Line 198 hardcodes allowUpgrade=false, which pins the version to previously deployed builds via resolveVersion() (caniuse.go:80). The --force flag (read at line 202) is meant to "allow downgrades" but is only passed to InstallCD()—not to the pre-check. Read force before the guard and pass it as allowUpgrade to canIUseProvider():

Suggested fix:
force, _ := cmd.Flags().GetBool("force")

if err := canIUseProvider(ctx, session.Provider, "", 0, force); err != nil {
    return err
}

return cli.InstallCD(ctx, session.Provider, force)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/cmd/cli/command/cd.go` around lines 198 - 203, Read the --force flag
before the provider pre-check and pass it into canIUseProvider so downgrades are
allowed during the guard; specifically, call cmd.Flags().GetBool("force") before
invoking canIUseProvider(ctx, session.Provider, "", 0, ...) and pass that
boolean as the allowUpgrade argument, then continue to call cli.InstallCD(ctx,
session.Provider, force) as before; this touches canIUseProvider, InstallCD and
the force variable used instead of the hardcoded false that interacts with
resolveVersion().
🧹 Nitpick comments (1)
src/pkg/clouds/aws/ecs/cfn/setup_test.go (1)

37-37: Test updated correctly for the new signature.

Consider adding a test case with force=true to verify the forced downgrade behavior. The PR description mentions recovering from accidental upgrades as a use case, which would benefit from explicit test coverage.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pkg/clouds/aws/ecs/cfn/setup_test.go` at line 37, Add a new test case
invoking aws.SetUp(ctx, testContainers, true) alongside the existing call to
aws.SetUp(..., false) to validate forced-downgrade behavior; in that case mock
or arrange the container state to simulate an upgraded version, call aws.SetUp
with force=true, and assert the expected outcome (no error and that the
downgrade path/state-change was executed) using the same test helpers/mocks as
the current test so the behavior is explicitly verified.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@src/cmd/cli/command/cd.go`:
- Around line 198-203: Read the --force flag before the provider pre-check and
pass it into canIUseProvider so downgrades are allowed during the guard;
specifically, call cmd.Flags().GetBool("force") before invoking
canIUseProvider(ctx, session.Provider, "", 0, ...) and pass that boolean as the
allowUpgrade argument, then continue to call cli.InstallCD(ctx,
session.Provider, force) as before; this touches canIUseProvider, InstallCD and
the force variable used instead of the hardcoded false that interacts with
resolveVersion().

---

Nitpick comments:
In `@src/pkg/clouds/aws/ecs/cfn/setup_test.go`:
- Line 37: Add a new test case invoking aws.SetUp(ctx, testContainers, true)
alongside the existing call to aws.SetUp(..., false) to validate
forced-downgrade behavior; in that case mock or arrange the container state to
simulate an upgraded version, call aws.SetUp with force=true, and assert the
expected outcome (no error and that the downgrade path/state-change was
executed) using the same test helpers/mocks as the current test so the behavior
is explicitly verified.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 87359425-2b6b-4ee6-82ed-cd25ea1d75f0

📥 Commits

Reviewing files that changed from the base of the PR and between fd97f97 and f4763fd.

⛔ Files ignored due to path filters (1)
  • src/go.sum is excluded by !**/*.sum
📒 Files selected for processing (34)
  • Makefile
  • pkgs/defang/cli.nix
  • src/cmd/cli/command/cd.go
  • src/cmd/cli/command/commands.go
  • src/cmd/crun/main.go
  • src/go.mod
  • src/pkg/cli/client/byoc/aws/byoc.go
  • src/pkg/cli/client/byoc/do/byoc.go
  • src/pkg/cli/client/byoc/gcp/byoc.go
  • src/pkg/cli/client/byoc/gcp/byoc_test.go
  • src/pkg/cli/client/playground.go
  • src/pkg/cli/client/provider.go
  • src/pkg/cli/install_cd.go
  • src/pkg/clouds/aws/ecs/cfn/setup.go
  • src/pkg/clouds/aws/ecs/cfn/setup_test.go
  • src/pkg/clouds/driver.go
  • src/pkg/crun/common.go
  • src/pkg/crun/common_test.go
  • src/pkg/crun/destroy.go
  • src/pkg/crun/docker/common.go
  • src/pkg/crun/docker/info.go
  • src/pkg/crun/docker/run.go
  • src/pkg/crun/docker/run_test.go
  • src/pkg/crun/docker/setup.go
  • src/pkg/crun/docker/stop.go
  • src/pkg/crun/docker/tail.go
  • src/pkg/crun/docker/teardown.go
  • src/pkg/crun/factory.go
  • src/pkg/crun/info.go
  • src/pkg/crun/local/local.go
  • src/pkg/crun/local/local_test.go
  • src/pkg/crun/logs.go
  • src/pkg/crun/run.go
  • src/pkg/crun/stop.go
💤 Files with no reviewable changes (19)
  • src/cmd/crun/main.go
  • src/pkg/crun/logs.go
  • src/pkg/crun/docker/run_test.go
  • src/pkg/crun/destroy.go
  • src/pkg/crun/docker/info.go
  • src/pkg/crun/docker/teardown.go
  • src/pkg/crun/docker/stop.go
  • src/pkg/crun/common.go
  • src/pkg/crun/stop.go
  • src/pkg/crun/info.go
  • src/pkg/crun/factory.go
  • src/pkg/crun/docker/tail.go
  • src/pkg/crun/docker/common.go
  • src/pkg/crun/run.go
  • src/pkg/crun/docker/setup.go
  • src/pkg/crun/docker/run.go
  • src/pkg/crun/common_test.go
  • src/pkg/crun/local/local.go
  • src/pkg/crun/local/local_test.go

@jordanstephens jordanstephens merged commit 30bb2b7 into main Mar 17, 2026
14 checks passed
@jordanstephens jordanstephens deleted the lio/force-cd branch March 17, 2026 00:01
@coderabbitai coderabbitai Bot mentioned this pull request Apr 8, 2026
3 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.

2 participants