Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

## DFX

### feat: -y flag for canister installation

`dfx canister install` and `dfx deploy` now have a `-y` flag that will automatically confirm any y/n checks made during canister installation.

### fix: Compute Motoko dependencies in linear (not exponential) time by detecting visited imports.

### fix(generate): add missing typescript types and fix issues with bindings array in dfx.json
Expand Down
8 changes: 8 additions & 0 deletions e2e/tests-dfx/install.bash
Original file line number Diff line number Diff line change
Expand Up @@ -163,3 +163,11 @@ teardown() {
assert_command dfx canister install e2e_project_backend --mode auto --upgrade-unchanged
assert_command dfx canister call e2e_project_backend greet dfx
}

@test "-y skips compat check" {
dfx_start
assert_command dfx canister create e2e_project_backend
assert_command dfx build e2e_project_backend
assert_command dfx canister install e2e_project_backend
assert_command timeout -s9 20s dfx canister install e2e_project_backend --mode reinstall -y # if -y does not work, hangs without stdin
}
8 changes: 8 additions & 0 deletions src/dfx/src/commands/canister/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ pub struct CanisterInstallOpts {
/// Specifies a particular WASM file to install, bypassing the dfx.json project settings.
#[clap(long, conflicts_with("all"))]
wasm: Option<PathBuf>,

/// Skips yes/no checks by answering 'yes'. Such checks usually result in data loss,
/// so this is not recommended outside of CI.
#[clap(long, short)]
yes: bool,
}

pub async fn exec(
Expand Down Expand Up @@ -113,6 +118,7 @@ pub async fn exec(
call_sender,
fs::read(&wasm_path)
.with_context(|| format!("Unable to read {}", wasm_path.display()))?,
opts.yes,
)
.await
} else {
Expand All @@ -132,6 +138,7 @@ pub async fn exec(
call_sender,
opts.upgrade_unchanged,
None,
opts.yes,
)
.await
}
Expand Down Expand Up @@ -170,6 +177,7 @@ pub async fn exec(
call_sender,
opts.upgrade_unchanged,
None,
opts.yes,
)
.await?;
}
Expand Down
6 changes: 6 additions & 0 deletions src/dfx/src/commands/deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ pub struct DeployOpts {
/// Bypasses the Wallet canister.
#[clap(long, conflicts_with("wallet"))]
no_wallet: bool,

/// Skips yes/no checks by answering 'yes'. Such checks usually result in data loss,
/// so this is not recommended outside of CI.
#[clap(long, short)]
yes: bool,
}

pub fn exec(env: &dyn Environment, opts: DeployOpts) -> DfxResult {
Expand Down Expand Up @@ -129,6 +134,7 @@ pub fn exec(env: &dyn Environment, opts: DeployOpts) -> DfxResult {
with_cycles,
&call_sender,
create_call_sender,
opts.yes,
))?;

display_urls(&env)
Expand Down
1 change: 1 addition & 0 deletions src/dfx/src/lib/nns/install_nns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,7 @@ pub async fn install_canister(
timeout,
&call_sender,
fs::read(&wasm_path).with_context(|| format!("Unable to read {:?}", wasm_path))?,
true,
)
.await?;

Expand Down
4 changes: 4 additions & 0 deletions src/dfx/src/lib/operations/canister/deploy_canisters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ pub async fn deploy_canisters(
with_cycles: Option<&str>,
call_sender: &CallSender,
create_call_sender: &CallSender,
skip_consent: bool,
) -> DfxResult {
let log = env.get_logger();

Expand Down Expand Up @@ -102,6 +103,7 @@ pub async fn deploy_canisters(
timeout,
call_sender,
pool,
skip_consent,
)
.await?;

Expand Down Expand Up @@ -217,6 +219,7 @@ async fn install_canisters(
timeout: Duration,
call_sender: &CallSender,
pool: CanisterPool,
skip_consent: bool,
) -> DfxResult {
info!(env.get_logger(), "Installing canisters...");

Expand Down Expand Up @@ -254,6 +257,7 @@ async fn install_canisters(
call_sender,
upgrade_unchanged,
Some(&pool),
skip_consent,
)
.await?;
}
Expand Down
9 changes: 6 additions & 3 deletions src/dfx/src/lib/operations/canister/install_canister.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ pub async fn install_canister(
call_sender: &CallSender,
upgrade_unchanged: bool,
pool: Option<&CanisterPool>,
skip_consent: bool,
) -> DfxResult {
let log = env.get_logger();
let network = env.get_network_descriptor();
Expand All @@ -67,7 +68,7 @@ pub async fn install_canister(
InstallMode::Install
}
});
if matches!(mode, InstallMode::Reinstall | InstallMode::Upgrade) {
if !skip_consent && matches!(mode, InstallMode::Reinstall | InstallMode::Upgrade) {
let candid = read_module_metadata(agent, canister_id, "candid:service").await;
if let Some(candid) = &candid {
match check_candid_compatibility(canister_info, candid) {
Expand All @@ -83,7 +84,7 @@ pub async fn install_canister(
}
}
}
if canister_info.is_motoko() && matches!(mode, InstallMode::Upgrade) {
if !skip_consent && canister_info.is_motoko() && matches!(mode, InstallMode::Upgrade) {
let stable_types = read_module_metadata(agent, canister_id, "motoko:stable-types").await;
if let Some(stable_types) = &stable_types {
match check_stable_compatibility(canister_info, env, stable_types) {
Expand Down Expand Up @@ -124,6 +125,7 @@ pub async fn install_canister(
timeout,
call_sender,
wasm_module,
skip_consent,
)
.await?;
}
Expand Down Expand Up @@ -357,10 +359,11 @@ pub async fn install_canister_wasm(
timeout: Duration,
call_sender: &CallSender,
wasm_module: Vec<u8>,
skip_consent: bool,
) -> DfxResult {
let log = env.get_logger();
let mgr = ManagementCanister::create(agent);
if mode == InstallMode::Reinstall {
if !skip_consent && mode == InstallMode::Reinstall {
let msg = if let Some(name) = canister_name {
format!("You are about to reinstall the {name} canister")
} else {
Expand Down