Pass extra CA certs to node process if env var exists (#23662)

Joe Sweeney created

Closes #8650

According to this comment:
https://github.com/zed-industries/zed/issues/8650#issuecomment-2125877549
it fixes the issue as described.

Happy to make adjustments!

Release Notes:
- Added passthrough of `NODE_EXTRA_CA_CERTS` if populated to node
commands

Change summary

crates/node_runtime/src/node_runtime.rs | 10 ++++++++++
1 file changed, 10 insertions(+)

Detailed changes

crates/node_runtime/src/node_runtime.rs 🔗

@@ -10,6 +10,7 @@ use semver::Version;
 use serde::Deserialize;
 use smol::io::BufReader;
 use smol::{fs, lock::Mutex};
+use std::env;
 use std::ffi::OsString;
 use std::io;
 use std::process::{Output, Stdio};
@@ -20,6 +21,8 @@ use std::{
 };
 use util::ResultExt;
 
+const NODE_CA_CERTS_ENV_VAR: &str = "NODE_EXTRA_CA_CERTS";
+
 #[derive(Clone, Debug, Default, Eq, PartialEq)]
 pub struct NodeBinaryOptions {
     pub allow_path_lookup: bool,
@@ -311,9 +314,11 @@ impl ManagedNodeRuntime {
         let node_dir = node_containing_dir.join(folder_name);
         let node_binary = node_dir.join(Self::NODE_PATH);
         let npm_file = node_dir.join(Self::NPM_PATH);
+        let node_ca_certs = env::var(NODE_CA_CERTS_ENV_VAR).unwrap_or_else(|_| String::new());
 
         let result = util::command::new_smol_command(&node_binary)
             .env_clear()
+            .env(NODE_CA_CERTS_ENV_VAR, node_ca_certs)
             .arg(npm_file)
             .arg("--version")
             .stdin(Stdio::null())
@@ -404,9 +409,12 @@ impl NodeRuntimeTrait for ManagedNodeRuntime {
                 return Err(anyhow!("missing npm file"));
             }
 
+            let node_ca_certs = env::var(NODE_CA_CERTS_ENV_VAR).unwrap_or_else(|_| String::new());
+
             let mut command = util::command::new_smol_command(node_binary);
             command.env_clear();
             command.env("PATH", env_path);
+            command.env(NODE_CA_CERTS_ENV_VAR, node_ca_certs);
             command.arg(npm_file).arg(subcommand);
             command.args(["--cache".into(), self.installation_path.join("cache")]);
             command.args([
@@ -535,10 +543,12 @@ impl NodeRuntimeTrait for SystemNodeRuntime {
         subcommand: &str,
         args: &[&str],
     ) -> anyhow::Result<Output> {
+        let node_ca_certs = env::var(NODE_CA_CERTS_ENV_VAR).unwrap_or_else(|_| String::new());
         let mut command = util::command::new_smol_command(self.npm.clone());
         command
             .env_clear()
             .env("PATH", std::env::var_os("PATH").unwrap_or_default())
+            .env(NODE_CA_CERTS_ENV_VAR, node_ca_certs)
             .arg(subcommand)
             .args(["--cache".into(), self.scratch_dir.join("cache")])
             .args([