Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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 @@ -12,6 +12,10 @@ The command line interface for nns commands has been updated to:
- Not offer --network as a flag given that it is unused
- List nns subcommands

### 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 @@ -680,6 +680,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