Here is a minimal reproduction:
The environment logging code looks like this:
fn log_some_env_variables() {
ic_cdk::println!("{:?}", option_env!("DFX_NETWORK"));
ic_cdk::println!("{:?}", option_env!("CANISTER_ID_canister_1"));
ic_cdk::println!("{:?}", option_env!("CANISTER_ID_canister_2"));
}
and this:
fn log_some_env_variables() {
ic_cdk::println!("{:?}", option_env!("DFX_NETWORK"));
ic_cdk::println!("{:?}", option_env!("CANISTER_ID_canister_1"));
ic_cdk::println!("{:?}", option_env!("CANISTER_ID_canister_2"));
}
When the bundled deploy script that looks like this:
is run, we get output that looks like this
When the individual deploy script that looks like this:
is run, we get output that looks like this
Notice that the individual deploy script has None
returned for canister ID values other than itself. This is buggy behaviour and should be rectified.
In this simple example, we can get away with using dfx deploy --all
but in a large project that has dfx.json
entries for:
internet identity canister
dynamically created canisters that are not deployed with dfx
frontend canister that is deployed as part of a separate worflow
There is no other alternative but to selectively build canisters
Please help rectify this behaviour
Severin
September 21, 2022, 2:58pm
2
Thank you @saikatdas0790 for such a neat bug report. I wish all of them were as nicely packaged
I haven’t tried it, but maybe it works: what happens if you dfx build --network ic --all
and then just dfx canister install <one canister>
? Would that be an acceptable workaround for now?
Severin
September 21, 2022, 3:05pm
3
Comment from @ericswanson : If you set canisters as dependencies in dfx.json the ENV vars should be available. Example from dfx new
:
{
"canisters": {
"hello_backend": {
<snip>
},
"hello_frontend": {
"type": "assets",
"source": [
"src/hello_frontend/assets"
],
"dependencies": [
"hello_backend"
]
}
}
}
That being said, it’s worth considering setting the ENV vars anyways, even when no dependency is set.
1 Like
I will try this and get back. For now, I ended up setting the values myself.
My deployment script looks like this now:
cargo test
dfx canister create --no-wallet canister_1
dfx canister create --no-wallet canister_2
export CANISTER_ID_canister_1=$(dfx canister id canister_1)
export CANISTER_ID_canister_2=$(dfx canister id canister_2)
dfx build canister_1
dfx build canister_2
dfx canister install canister_1
dfx canister install canister_2
dfx generate canister_1
dfx generate canister_2
Not sure if there’s a drawback for re-setting the env variables but seems to be working for now.
But would love for dfx to set this automatically without having to jump through hoops.
I don’t believe there’s any disadvantages of setting all the available project canister IDs as env variables since dfx canister id
makes them available anyway
1 Like
Severin
September 21, 2022, 4:26pm
5
The only drawback I can see is if you switch networks - there you may run into problems if you still have the variables set from another one
Right, of course. So, we have separate bash scripts for deployment to local vs mainnet
Is there a sample Rust + env variable repo somewhere @Severin ?
In my project I got few constants which I manually have to edit to build for local development, I would be super happy to replace these with an environment variables.
No, we do not have an official example for this situation. Maybe someone else can share a sample repo?
My reproduction example above uses environment variables to make the point. What specifically are you trying to do?
Same as I would do with .env
in JavaScript.
// .env.local
HELLO=world
// => used with "npm run dev"
// .env.production
HELLO=yolo
// => used with "npm run build"
I would need different variables per environment with dfx.
// ??????
HELLO=world
// => used with "dfx deploy"
// ?????
HELLO=yolo
// => used with "dfx deploy --nework ic"
So not sure how to do that. As in your repo I know option_env
.
ic_cdk::println!("{:?}", option_env!("HELLO"));
But not sure where to set that in dfx for local and ic networks.
I do that in separate build.sh
files.
build.dev.sh
& build.prod.sh
Each one sets it something like this:
export HELLO="WORLD"
dfx ...
Gotcha! I was hoping it would be built-in dfx but seems like a nice workaround, thanks for the share.
1 Like