Skip to content
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

Add feature to skip upgrade if no changes detected #379

Merged
merged 33 commits into from
Aug 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
8652869
Implement no-upgrade-if-unchanged based on the --detailed-exit-code from
tylermaginnis Aug 25, 2024
f0fdbb3
Revert config.yaml
tylermaginnis Aug 25, 2024
793ef69
Merge pull request #1 from tylermaginnis/feature/TM_skip-upgrade-if-u…
tylermaginnis Aug 25, 2024
842f7ad
Add the comma causing the linting error from catgo fmt
tylermaginnis Aug 25, 2024
d28d488
Remove the trailing { for cargo linting
tylermaginnis Aug 25, 2024
c397d38
Align the comment for cargo linting
tylermaginnis Aug 25, 2024
d2f69c4
Align the comment for cargo linting
tylermaginnis Aug 25, 2024
e4d0a9e
Code formatting for cargo linting
tylermaginnis Aug 25, 2024
a991aaf
Add the ',' for cargo linting
tylermaginnis Aug 25, 2024
33ef24d
Remainder of cargo linting
tylermaginnis Aug 25, 2024
3431240
Merge pull request #2 from tylermaginnis/feature/TM_skip-upgrade-if-u…
tylermaginnis Aug 25, 2024
02c006e
Resolve CR
tylermaginnis Aug 26, 2024
a005974
Add -b --bypass-skip-upgrade-on-no-changes #clap flag
tylermaginnis Aug 26, 2024
c3c8554
Based on result of char cargo test, change chars to strings
tylermaginnis Aug 26, 2024
7ca50e1
Merge pull request #3 from tylermaginnis/feature/TM_skip-upgrade-if-u…
tylermaginnis Aug 27, 2024
60148ae
"Rust auto-linting, revert config.yaml context"
tylermaginnis Aug 27, 2024
f4accf1
Merge pull request #4 from tylermaginnis/feature/TM_skip-upgrade-if-u…
tylermaginnis Aug 27, 2024
bd41385
Implement --yes || -y for -b Upgrade suboption for CI environments
tylermaginnis Aug 27, 2024
bb0fd43
Implement -b -y || -n (--bypass-skip-upgrade-on-no-changes --no is the
tylermaginnis Aug 27, 2024
04adaec
Cargo linting fix
tylermaginnis Aug 27, 2024
c3f3e7b
Merge pull request #5 from tylermaginnis/feature/TM_skip-upgrade-if-u…
tylermaginnis Aug 27, 2024
6fb180e
Update documentation
tylermaginnis Aug 27, 2024
dc0299a
Merge pull request #6 from tylermaginnis/feature/TM_skip-upgrade-if-u…
tylermaginnis Aug 27, 2024
56b802c
Fix some clippy errors introduced - partial reversion in Main function
tylermaginnis Aug 27, 2024
da02726
Merge pull request #7 from tylermaginnis/feature/TM_skip-upgrade-if-u…
tylermaginnis Aug 27, 2024
ffbf8cc
Add the UpgradeControl enum
tylermaginnis Aug 27, 2024
f83eb5e
Merge pull request #8 from tylermaginnis/feature/TM_skip-upgrade-if-u…
tylermaginnis Aug 27, 2024
d6d3a31
Suppress exit_code 2
tylermaginnis Aug 27, 2024
762dd6c
Merge pull request #9 from tylermaginnis/feature/TM_skip-upgrade-if-u…
tylermaginnis Aug 27, 2024
12810ef
Suppress the single exit_code warning for unused variables in text.rs
tylermaginnis Aug 27, 2024
9ab3877
Merge pull request #10 from tylermaginnis/feature/TM_skip-upgrade-if-…
tylermaginnis Aug 27, 2024
b304ef8
Remove UI prompt intererfered with TUI. Alter the way specific debug
tylermaginnis Aug 27, 2024
92681e7
Merge pull request #11 from tylermaginnis/feature/TM_skip-upgrade-if-…
tylermaginnis Aug 27, 2024
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
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,35 @@ Only do this if you really want to deploy:
cargo run -- --vdir ./example/helm-values upgrade
```

## Additional Options

### Bypass Upgrade on No Changes

The `-b` or `--bypass-upgrade-on-no-changes` option allows you to bypass the upgrade process if no changes are detected. This can be useful to save time and resources when you are confident that no changes have been made to the release values.

### Suboptions

#### Yes

The `-y` or `--yes` suboption can be used in conjunction with the `--bypass-upgrade-on-no-changes` option to automatically proceed with the upgrade even if no changes are detected. This is useful for automated scripts where manual intervention is not possible.

#### No

The `-n` or `--no` suboption can be used in conjunction with the `--bypass-upgrade-on-no-changes` option to automatically skip the upgrade if no changes are detected. This is useful when you want to ensure that upgrades are only performed when necessary without manual intervention.

Example usage:

```sh
# Bypass upgrade on no changes and automatically proceed with the upgrade
cargo run -- --vdir ./example/helm-values upgrade --bypass-upgrade-on-no-changes --yes
cargo run -- --vdir ./example/helm-values upgrade -b -y


# Bypass upgrade on no changes and automatically skip the upgrade
cargo run -- --vdir ./example/helm-values upgrade --bypass-upgrade-on-no-changes --no
cargo run -- --vdir ./example/helm-values upgrade -b -y
```

## Config layout

You can have zero or more environments.
Expand Down
4 changes: 3 additions & 1 deletion src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub struct CommandSuccess {
pub stdout: String,
pub stderr: String,
pub duration: Duration,
pub exit_code: i32, // This field stores the exit code of the command to determine if it was successful or not, and whether or not there were any diffs.
}

impl CommandSuccess {
Expand Down Expand Up @@ -176,7 +177,7 @@ impl CommandLine {
let kind = match output {
Err(err) => Err(CommandErrorKind::FailedToStart { err }),
Ok(output) => {
if output.status.success() {
if output.status.success() || exit_code == 2 {
Ok(())
} else {
Err(CommandErrorKind::BadExitCode {})
Expand All @@ -189,6 +190,7 @@ impl CommandLine {
cmd: self.clone(),
stdout,
stderr,
exit_code,
duration,
}),
Err(kind) => Err(CommandError {
Expand Down
64 changes: 56 additions & 8 deletions src/helm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ pub struct HelmResult {
pub installation: Arc<Installation>,
pub result: CommandResult,
pub command: Command,
// The exit code contains information about whether there were any diffs.
pub exit_code: i32,
}

impl HelmResult {
Expand All @@ -130,6 +132,7 @@ impl HelmResult {
installation: installation.clone(),
result,
command,
exit_code: 0,
}
}

Expand Down Expand Up @@ -366,20 +369,35 @@ pub async fn template(
}
}

// The DiffResult struct is used to store the exit code of the diff command.
pub enum DiffResult {
NoChanges,
Changes,
Errors,
Unknown,
}
async fn log_debug_message(tx: &MultiOutput, message: &str) {
tx.send(Message::Log(log!(Level::DEBUG, message))).await;
}

/// Run the helm diff command.
pub async fn diff(
installation: &Arc<Installation>,
helm_repos: &HelmReposLock,
tx: &MultiOutput,
) -> Result<()> {
) -> Result<DiffResult> {
// Retrieve the helm chart for the given installation.
let chart = helm_repos.get_helm_chart(&installation.chart_reference)?;
// Get the chart arguments from the chart.
let (chart, mut chart_args) = get_args_from_chart(&chart);

// Construct the arguments for the helm diff command.
let mut args = vec![
"diff".into(),
"upgrade".into(),
installation.name.clone().into(),
chart,
"--detailed-exitcode".into(), // This flag ensures that the exit code will indicate if there are changes or errors.
"--context=3".into(),
"--no-color".into(),
"--allow-unreleased".into(),
Expand All @@ -389,22 +407,52 @@ pub async fn diff(
installation.clone().context.clone().into(),
];

// Append additional arguments from the installation configuration.
args.append(&mut add_values_files(installation));
args.append(&mut chart_args);
args.append(&mut get_template_parameters(installation));

// Create a CommandLine instance with the helm path and the constructed arguments.
let command_line = CommandLine(helm_path(), args);
// Run the command and await the result.
let result = command_line.run().await;
let has_errors = result.is_err();
let i_result = HelmResult::from_result(installation, result, Command::Diff);
// Check if there were any errors in the command execution.
let _has_errors = result.is_err();
// Create a HelmResult instance from the command result.
let mut i_result = HelmResult::from_result(installation, result, Command::Diff);

// Evaluate the detailed exit code - any non-zero exit code indicates changes (1) or errors (2).
let diff_result = if let Ok(command_success) = &i_result.result {
i_result.exit_code = command_success.exit_code;
match command_success.exit_code {
0 => {
log_debug_message(tx, "No changes detected!").await; // Exit code 0 indicates no changes.
DiffResult::NoChanges
}
1 => {
log_debug_message(tx, "Errors encountered!").await; // Exit code 1 indicates errors.
DiffResult::Errors
}
2 => {
log_debug_message(tx, "Changes detected!").await; // Exit code 2 indicates changes.
DiffResult::Changes
}
_ => {
log_debug_message(tx, "Unknown exit code").await; // Any other exit code is considered unknown.
DiffResult::Unknown
}
}
} else {
log_debug_message(tx, "Other exception encountered").await; // If the command result is an error, return Unknown.
DiffResult::Unknown
};

// Wrap the HelmResult in an Arc and send it via the MultiOutput channel.
let i_result = Arc::new(i_result);
tx.send(Message::InstallationResult(i_result)).await;

if has_errors {
Err(anyhow::anyhow!("diff operation failed"))
} else {
Ok(())
}
// Return the diff result.
Ok(diff_result)
}

/// Run the helm upgrade command.
Expand Down
Loading
Loading