feature: add post_deploy command (#288)

* feature: add post_deploy command

* review: do not run post_deploy if deploy failed
This commit is contained in:
unsync
2025-02-08 22:28:37 +01:00
committed by mbecker20
parent 4c9479a8bc
commit 5a8ed8b81d
6 changed files with 231 additions and 144 deletions

View File

@@ -152,6 +152,13 @@ impl Resolve<ExecuteArgs> for DeployStack {
&mut secret_replacers,
)?;
interpolate_variables_secrets_into_system_command(
&vars_and_secrets,
&mut stack.config.post_deploy,
&mut global_replacers,
&mut secret_replacers,
)?;
add_interp_update_log(
&mut update,
&global_replacers,

View File

@@ -371,7 +371,7 @@ pub async fn compose_up(
svi::Interpolator::DoubleBrackets,
true,
).context("failed to interpolate periphery secrets into stack run command")?;
replacers.extend(core_replacers);
replacers.extend(core_replacers.clone());
let mut log = run_komodo_command(
"compose up",
@@ -389,8 +389,64 @@ pub async fn compose_up(
};
res.deployed = log.success;
// push the compose up command logs to keep the correct order
res.logs.push(log);
if res.deployed && !stack.config.post_deploy.command.is_empty() {
let post_deploy_path =
run_directory.join(&stack.config.post_deploy.path);
if !stack.config.skip_secret_interp {
let (full_command, mut replacers) =
interpolate_variables(&stack.config.post_deploy.command)
.context(
"failed to interpolate secrets into post_deploy command",
)?;
replacers.extend(core_replacers);
let mut post_deploy_log = run_komodo_command(
"post deploy",
post_deploy_path.as_ref(),
&full_command,
true,
)
.await;
post_deploy_log.command =
svi::replace_in_string(&post_deploy_log.command, &replacers);
post_deploy_log.stdout =
svi::replace_in_string(&post_deploy_log.stdout, &replacers);
post_deploy_log.stderr =
svi::replace_in_string(&post_deploy_log.stderr, &replacers);
tracing::debug!(
"run Stack post_deploy command | command: {} | cwd: {:?}",
post_deploy_log.command,
post_deploy_path
);
res.logs.push(post_deploy_log);
} else {
let post_deploy_log = run_komodo_command(
"post deploy",
post_deploy_path.as_ref(),
&stack.config.post_deploy.command,
true,
)
.await;
tracing::debug!(
"run Stack post_deploy command | command: {} | cwd: {:?}",
&stack.config.post_deploy.command,
post_deploy_path
);
res.logs.push(post_deploy_log);
}
if !all_logs_success(&res.logs) {
return Err(anyhow!(
"Failed at running post_deploy command, stopping the run."
));
}
}
Ok(())
}

View File

@@ -382,6 +382,11 @@ pub struct StackConfig {
#[builder(default)]
pub pre_deploy: SystemCommand,
/// The optional command to run after the Stack is deployed.
#[serde(default)]
#[builder(default)]
pub post_deploy: SystemCommand,
/// The extra arguments to pass after `docker compose up -d`.
/// If empty, no extra arguments will be passed.
#[serde(default, deserialize_with = "string_list_deserializer")]
@@ -489,6 +494,7 @@ impl Default for StackConfig {
auto_update: Default::default(),
ignore_services: Default::default(),
pre_deploy: Default::default(),
post_deploy: Default::default(),
extra_args: Default::default(),
environment: Default::default(),
env_file_path: default_env_file_path(),

File diff suppressed because it is too large Load Diff

View File

@@ -104,7 +104,7 @@ export interface ResourceQuery<T> {
export interface ActionQuerySpecifics {
}
export type ActionQuery = ResourceQuery<ActionQuerySpecifics>;
export type AlerterEndpoint =
export type AlerterEndpoint =
/** Send alert serialized to JSON to an http endpoint. */
{
type: "Custom";
@@ -390,7 +390,7 @@ export interface BuildQuerySpecifics {
built_since?: I64;
}
export type BuildQuery = ResourceQuery<BuildQuerySpecifics>;
export type BuilderConfig =
export type BuilderConfig =
/** Use a Periphery address as a Builder. */
{
type: "Url";
@@ -421,7 +421,7 @@ export interface BuilderQuerySpecifics {
}
export type BuilderQuery = ResourceQuery<BuilderQuerySpecifics>;
/** A wrapper for all Komodo exections. */
export type Execution =
export type Execution =
/** The "null" execution. Does nothing. */
{
type: "None";
@@ -725,7 +725,7 @@ export interface JwtResponse {
export type CreateLocalUserResponse = JwtResponse;
export type CreateProcedureResponse = Procedure;
export type CreateRepoWebhookResponse = NoData;
export type UserConfig =
export type UserConfig =
/** User that logs in with username / password */
{
type: "Local";
@@ -833,7 +833,7 @@ export type DeleteStackWebhookResponse = NoData;
export type DeleteSyncWebhookResponse = NoData;
export type DeleteUserResponse = User;
export type DeleteVariableResponse = Variable;
export type DeploymentImage =
export type DeploymentImage =
/** Deploy any external image. */
{
type: "Image";
@@ -1010,7 +1010,7 @@ export declare enum SeverityLevel {
Critical = "CRITICAL"
}
/** The variants of data related to the alert. */
export type AlertData =
export type AlertData =
/** A null alert */
{
type: "None";
@@ -1476,7 +1476,7 @@ export interface ResourceSyncConfig {
/** Manage the file contents in the UI. */
file_contents?: string;
}
export type DiffData =
export type DiffData =
/** Resource will be created */
{
type: "Create";
@@ -1641,7 +1641,7 @@ export interface ServerConfig {
}
export type Server = Resource<ServerConfig, undefined>;
export type GetServerResponse = Server;
export type ServerTemplateConfig =
export type ServerTemplateConfig =
/** Template to launch an AWS EC2 instance */
{
type: "Aws";
@@ -1775,6 +1775,8 @@ export interface StackConfig {
registry_account?: string;
/** The optional command to run before the Stack is deployed. */
pre_deploy?: SystemCommand;
/** The optional command to run before the Stack is deployed. */
post_deploy?: SystemCommand;
/**
* The extra arguments to pass after `docker compose up -d`.
* If empty, no extra arguments will be passed.
@@ -3079,7 +3081,7 @@ export interface GitProvider {
accounts: ProviderAccount[];
}
export type ListGitProvidersFromConfigResponse = GitProvider[];
export type UserTarget =
export type UserTarget =
/** User Id */
{
type: "User";
@@ -7091,7 +7093,7 @@ export type ExecuteRequest = {
params: RunSync;
};
/** Configuration for the registry to push the built image to. */
export type ImageRegistryLegacy1_14 =
export type ImageRegistryLegacy1_14 =
/** Don't push the image to any registry */
{
type: "None";

View File

@@ -306,6 +306,20 @@ export const StackConfig = ({
),
},
},
{
label: "Post Deploy",
description:
"Execute a shell command after running docker compose up. The 'path' is relative to the Run Directory",
components: {
post_deploy: (value, set) => (
<SystemCommand
value={value}
set={(value) => set({ post_deploy: value })}
disabled={disabled}
/>
),
},
},
{
label: "Extra Args",
labelHidden: true,