diff --git a/bin/core/src/api/write/stack.rs b/bin/core/src/api/write/stack.rs index a3a9cca9e..0d958168c 100644 --- a/bin/core/src/api/write/stack.rs +++ b/bin/core/src/api/write/stack.rs @@ -775,7 +775,13 @@ pub async fn check_stack_for_update_inner( if image.is_empty() || // Images with a hardcoded digest can't have update. - image.contains('@') + image.contains('@') || + // Services explicitly excluded from global auto-update checks. + // Manual checks should still evaluate all services. + (wait_for_auto_update && + stack.config.auto_update_skip_services.contains( + &service.service_name, + )) { service.image_digest = None; continue; diff --git a/client/core/rs/src/entities/stack.rs b/client/core/rs/src/entities/stack.rs index 1cff045dd..c49aa608a 100644 --- a/client/core/rs/src/entities/stack.rs +++ b/client/core/rs/src/entities/stack.rs @@ -371,6 +371,17 @@ pub struct StackConfig { #[builder(default)] pub auto_update_all_services: bool, + /// Ignore certain services during Global Auto Update polling. + /// Services listed here are skipped only in the global auto-update flow. + /// Manual checks still include all services. + #[serde(default, deserialize_with = "string_list_deserializer")] + #[partial_attr(serde( + default, + deserialize_with = "option_string_list_deserializer" + ))] + #[builder(default)] + pub auto_update_skip_services: Vec, + /// Whether to run `docker compose down` before `compose up`. #[serde(default)] #[builder(default)] @@ -688,6 +699,7 @@ impl Default for StackConfig { poll_for_updates: Default::default(), auto_update: Default::default(), auto_update_all_services: Default::default(), + auto_update_skip_services: Default::default(), ignore_services: Default::default(), pre_deploy: Default::default(), post_deploy: Default::default(), diff --git a/client/core/ts/src/types.ts b/client/core/ts/src/types.ts index 4d4e0d186..ecf945045 100644 --- a/client/core/ts/src/types.ts +++ b/client/core/ts/src/types.ts @@ -2468,6 +2468,12 @@ export interface StackConfig { * Komodo will redeploy the whole Stack (all services). */ auto_update_all_services?: boolean; + /** + * Ignore certain services during Global Auto Update polling. + * Services listed here are skipped only in the global auto-update flow. + * Manual checks still include all services. + */ + auto_update_skip_services?: string[]; /** Whether to run `docker compose down` before `compose up`. */ destroy_before_deploy?: boolean; /** Whether to skip secret interpolation into the stack environment variables. */ diff --git a/ui/public/client/types.d.ts b/ui/public/client/types.d.ts index 4374fb160..c612beb26 100644 --- a/ui/public/client/types.d.ts +++ b/ui/public/client/types.d.ts @@ -2610,6 +2610,12 @@ export interface StackConfig { * Komodo will redeploy the whole Stack (all services). */ auto_update_all_services?: boolean; + /** + * Ignore certain services during Global Auto Update polling. + * Services listed here are skipped only in the global auto-update flow. + * Manual checks still include all services. + */ + auto_update_skip_services?: string[]; /** Whether to run `docker compose down` before `compose up`. */ destroy_before_deploy?: boolean; /** Whether to skip secret interpolation into the stack environment variables. */ diff --git a/ui/src/resources/stack/config/index.tsx b/ui/src/resources/stack/config/index.tsx index 456372872..fedef6f74 100644 --- a/ui/src/resources/stack/config/index.tsx +++ b/ui/src/resources/stack/config/index.tsx @@ -95,6 +95,8 @@ export default function StackConfig({ const disabled = global_disabled || !canWrite; const runBuild = update.run_build ?? config.run_build; + const poll_for_updates = update.poll_for_updates ?? config.poll_for_updates; + const mode = getStackMode(update, config); const gitProvider = update.git_provider ?? config.git_provider; @@ -390,6 +392,27 @@ export default function StackConfig({ /> ); }, + auto_update_skip_services: (values, set) => + poll_for_updates && ( + + } + placeholder={values?.length ? "Add services" : "Select services"} + value={values} + data={allServices} + onChange={(auto_update_skip_services) => + set({ auto_update_skip_services }) + } + disabled={disabled} + w="fit-content" + searchable + clearable + /> + + ), auto_update: { description: "Trigger a redeploy if a newer image is found.", },