New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[SM-1129] Run command with secrets #621
base: main
Are you sure you want to change the base?
Conversation
No New Or Fixed Issues Found |
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #621 +/- ##
==========================================
- Coverage 61.77% 61.30% -0.48%
==========================================
Files 172 172
Lines 10927 11011 +84
==========================================
Hits 6750 6750
- Misses 4177 4261 +84 ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, looks like a great start to me, left some comments with a few small improvements.
let shell = match std::env::consts::OS { | ||
os if os == "linux" || os == "macos" || os.contains("bsd") => { | ||
shell.unwrap_or_else(|| "sh".to_string()) | ||
} | ||
"windows" => shell.unwrap_or_else(|| "powershell".to_string()), | ||
_ => unreachable!(), | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be better to invert this condition like this?
let shell = match std::env::consts::OS { | |
os if os == "linux" || os == "macos" || os.contains("bsd") => { | |
shell.unwrap_or_else(|| "sh".to_string()) | |
} | |
"windows" => shell.unwrap_or_else(|| "powershell".to_string()), | |
_ => unreachable!(), | |
}; | |
let shell = match std::env::consts::OS { | |
"windows" => shell.unwrap_or_else(|| "powershell".to_string()), | |
_ => shell.unwrap_or_else(|| "sh".to_string()) | |
}; |
Any other platform that might fall under the unreachable line (maybe android?) probably has some kind of basic sh
, so at least it would work.
@@ -222,6 +238,15 @@ enum DeleteCommand { | |||
Secret { secret_ids: Vec<Uuid> }, | |||
} | |||
|
|||
#[derive(Subcommand, Debug)] | |||
enum RunCommand { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This enum doesn't seem to be used anywhere, only the Run
variant above is used, right?
no_inherit_env, | ||
project_id, | ||
} => { | ||
let shell = match std::env::consts::OS { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The process_command
function is getting quite big already, do you mind splitting this to a separate function?
} | ||
|
||
let user_command = if command.is_empty() { | ||
if atty::is(Stream::Stdin) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes me think that when using the run command without extra arguments they'll be read from stdin, but for me it just prints the help. I tried running it as:
bws run
bws run --
bws run -- ""
bws run ""
Is there anything I'm missing?
.collect::<std::collections::HashMap<String, String>>(); | ||
|
||
let valid_key_regex = | ||
regex::Regex::new("^[a-zA-Z_][a-zA-Z0-9_]*$").expect("valid regex"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have the same regex in the render.rs
function, should we extract it to an is_valid_posix_name
function somewhere?
let environment = secrets | ||
.iter() | ||
.map(|s| (s.key.clone(), s.value.clone())) | ||
.collect::<std::collections::HashMap<String, String>>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you use into_iter
here, you can avoid the key and value clones
let environment = secrets | |
.iter() | |
.map(|s| (s.key.clone(), s.value.clone())) | |
.collect::<std::collections::HashMap<String, String>>(); | |
let environment = secrets | |
.into_iter() | |
.map(|s| (s.key, s.value)) | |
.collect::<std::collections::HashMap<String, String>>(); |
let exit_status = child.wait().expect("process failed to execute"); | ||
let exit_code = exit_status.code().unwrap_or(1); | ||
|
||
let _ = child.wait(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is needed, we're already calling child.wait() above, any other calls will just return immediately, I think
Type of change
Objective
Add a
run
command to allow running processes with secrets injected.Example:
bws run 'docker compose up -d'
,bws run -- docker compose up -d
, or from stdin:echo 'docker compose up -d' | bws run
Where the compose file is expecting secrets:
Any command can be run as well:
bws run -- npm run start
,bws run -- ./some_script.sh
, etc.A
--shell
option is provided to override the default shell (sh
on UNIX-like OSes, andpowershell
on Windows) where the process is executed.A
--no-inherit-env
option is provided for additional safety in cases where you want to pass the minimum amount of values into a process.$PATH
is always passed though, as omitting it would cause nearly every command to fail.Code changes
run
command and associated args.Before you submit