Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package nelm for openSUSE:Factory checked in 
at 2026-07-06 12:34:12
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/nelm (Old)
 and      /work/SRC/openSUSE:Factory/.nelm.new.1982 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "nelm"

Mon Jul  6 12:34:12 2026 rev:29 rq:1363943 version:1.24.3

Changes:
--------
--- /work/SRC/openSUSE:Factory/nelm/nelm.changes        2026-06-28 
21:09:00.291071219 +0200
+++ /work/SRC/openSUSE:Factory/.nelm.new.1982/nelm.changes      2026-07-06 
12:36:53.660918491 +0200
@@ -1,0 +2,18 @@
+Mon Jul 06 05:09:45 UTC 2026 - Johannes Kastl 
<[email protected]>
+
+- Update to version 1.24.3:
+  * Bug Fixes
+    - autodetection of ServiceAccount dependencies for
+      ClusterRoleBinding and RoleBinding resources (#632) (e9ea5da)
+    - make pods/controllers depend on rolebindings (#634) (233e123)
+- Update to version 1.24.2:
+  * Bug Fixes
+    - better error message when kube client request timed out
+      (dc11213)
+    - close LegacyReportCh on action return (#629) (78033c6)
+    - deploy ns on pre-pre-install stage (#630) (816d8c1)
+    - panic if channel for legacy progress reporter closed (#618)
+      (0e6945c)
+    - pass NoPodLogs to kubedog (#622) (069609f)
+
+-------------------------------------------------------------------

Old:
----
  nelm-1.24.1.obscpio

New:
----
  nelm-1.24.3.obscpio

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ nelm.spec ++++++
--- /var/tmp/diff_new_pack.uxAAih/_old  2026-07-06 12:36:54.804958174 +0200
+++ /var/tmp/diff_new_pack.uxAAih/_new  2026-07-06 12:36:54.808958312 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           nelm
-Version:        1.24.1
+Version:        1.24.3
 Release:        0
 Summary:        Helm 3 alternative
 License:        Apache-2.0

++++++ _service ++++++
--- /var/tmp/diff_new_pack.uxAAih/_old  2026-07-06 12:36:54.860960116 +0200
+++ /var/tmp/diff_new_pack.uxAAih/_new  2026-07-06 12:36:54.868960394 +0200
@@ -1,9 +1,9 @@
 <services>
   <service name="obs_scm" mode="manual">
-    <param name="url">https://github.com/werf/nelm</param>
+    <param name="url">https://github.com/werf/nelm.git</param>
     <param name="scm">git</param>
     <param name="exclude">.git</param>
-    <param name="revision">v1.24.1</param>
+    <param name="revision">refs/tags/v1.24.3</param>
     <param name="versionformat">@PARENT_TAG@</param>
     <param name="versionrewrite-pattern">v(.*)</param>
     <param name="changesgenerate">enable</param>

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.uxAAih/_old  2026-07-06 12:36:54.896961365 +0200
+++ /var/tmp/diff_new_pack.uxAAih/_new  2026-07-06 12:36:54.900961504 +0200
@@ -1,6 +1,8 @@
 <servicedata>
 <service name="tar_scm">
                 <param name="url">https://github.com/werf/nelm</param>
-              <param 
name="changesrevision">9366af9135202b7d705c71fef6c7dbe0231c0345</param></service></servicedata>
+              <param 
name="changesrevision">9366af9135202b7d705c71fef6c7dbe0231c0345</param></service><service
 name="tar_scm">
+                <param name="url">https://github.com/werf/nelm.git</param>
+              <param 
name="changesrevision">c0c3c7ab1457fbf634acee9b2d2a29b9cdc101d4</param></service></servicedata>
 (No newline at EOF)
 

++++++ nelm-1.24.1.obscpio -> nelm-1.24.3.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nelm-1.24.1/CHANGELOG.md new/nelm-1.24.3/CHANGELOG.md
--- old/nelm-1.24.1/CHANGELOG.md        2026-05-12 15:56:02.000000000 +0200
+++ new/nelm-1.24.3/CHANGELOG.md        2026-06-08 18:00:18.000000000 +0200
@@ -1,5 +1,24 @@
 # Changelog
 
+## [1.24.3](https://github.com/werf/nelm/compare/v1.24.2...v1.24.3) 
(2026-06-08)
+
+
+### Bug Fixes
+
+* autodetection of ServiceAccount dependencies for ClusterRoleBinding and 
RoleBinding resources ([#632](https://github.com/werf/nelm/issues/632)) 
([e9ea5da](https://github.com/werf/nelm/commit/e9ea5da1e1ef7606979aab5a45ea058b48837476))
+* make pods/controllers depend on rolebindings 
([#634](https://github.com/werf/nelm/issues/634)) 
([233e123](https://github.com/werf/nelm/commit/233e1232890bff0682ba9bb2c1638657aff17297))
+
+## [1.24.2](https://github.com/werf/nelm/compare/v1.24.1...v1.24.2) 
(2026-06-04)
+
+
+### Bug Fixes
+
+* better error message when kube client request timed out 
([dc11213](https://github.com/werf/nelm/commit/dc11213b4fa89a749b5f7c5fb1199c611d646484))
+* close LegacyReportCh on action return 
([#629](https://github.com/werf/nelm/issues/629)) 
([78033c6](https://github.com/werf/nelm/commit/78033c656d87290b24c540ec292608bf3a21fb66))
+* deploy ns on pre-pre-install stage 
([#630](https://github.com/werf/nelm/issues/630)) 
([816d8c1](https://github.com/werf/nelm/commit/816d8c1fbc9610609bfdc61084b3b0848606b20d))
+* panic if channel for legacy progress reporter closed 
([#618](https://github.com/werf/nelm/issues/618)) 
([0e6945c](https://github.com/werf/nelm/commit/0e6945ce047c67c6e23a52de7ba06372ffcf383b))
+* pass NoPodLogs to kubedog ([#622](https://github.com/werf/nelm/issues/622)) 
([069609f](https://github.com/werf/nelm/commit/069609f63b214323d7ca1ebc9818e200818888ca))
+
 ## [1.24.1](https://github.com/werf/nelm/compare/v1.24.0...v1.24.1) 
(2026-04-29)
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nelm-1.24.1/README.md new/nelm-1.24.3/README.md
--- old/nelm-1.24.1/README.md   2026-05-12 15:56:02.000000000 +0200
+++ new/nelm-1.24.3/README.md   2026-06-08 18:00:18.000000000 +0200
@@ -1,3 +1,7 @@
+<p align="center">
+  <img src="resources/images/nelm-logo.png" style="max-height:100%;" 
height="100">
+</p>
+
 <!-- <p align="center">
   <a href="https://godoc.org/github.com/werf/nelm";><img 
src="https://godoc.org/github.com/werf/nelm?status.svg"; alt="GoDoc"></a>
   <a href="https://qlty.sh/gh/werf/projects/nelm";><img 
src="https://qlty.sh/gh/werf/projects/nelm/coverage.svg"; alt="Code Coverage" 
/></a>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nelm-1.24.1/pkg/action/release_install.go 
new/nelm-1.24.3/pkg/action/release_install.go
--- old/nelm-1.24.1/pkg/action/release_install.go       2026-05-12 
15:56:02.000000000 +0200
+++ new/nelm-1.24.3/pkg/action/release_install.go       2026-06-08 
18:00:18.000000000 +0200
@@ -432,6 +432,7 @@
                }, clientFactory, resource.BuildResourcesOptions{
                        Remote:                   true,
                        DefaultDeletePropagation: 
metav1.DeletionPropagation(opts.DefaultDeletePropagation),
+                       NoPodLogs:                opts.NoPodLogs,
                })
                if err != nil {
                        return fmt.Errorf("build resources: %w", err)
@@ -567,6 +568,9 @@
        var reporter *plan.LegacyProgressReporter
        if opts.LegacyProgressReportCh != nil {
                reporter = 
plan.NewLegacyProgressReporter(opts.LegacyProgressReportCh)
+               defer func() {
+                       close(opts.LegacyProgressReportCh)
+               }()
        }
 
        log.Default.Debug(ctx, "Execute release install plan")
@@ -848,6 +852,7 @@
        }, clientFactory, resource.BuildResourcesOptions{
                Remote:                   true,
                DefaultDeletePropagation: 
metav1.DeletionPropagation(opts.DefaultDeletePropagation),
+               NoPodLogs:                opts.NoPodLogs,
        })
        if err != nil {
                return nil, nonCritErrs, critErrs.Add(fmt.Errorf("build 
resources: %w", err))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nelm-1.24.1/pkg/action/release_rollback.go 
new/nelm-1.24.3/pkg/action/release_rollback.go
--- old/nelm-1.24.1/pkg/action/release_rollback.go      2026-05-12 
15:56:02.000000000 +0200
+++ new/nelm-1.24.3/pkg/action/release_rollback.go      2026-06-08 
18:00:18.000000000 +0200
@@ -274,6 +274,7 @@
        instResources, delResources, err := resource.BuildResources(ctx, 
deployType, releaseNamespace, prevRelResSpecs, newRelResSpecs, patchers, 
clientFactory, resource.BuildResourcesOptions{
                Remote:                   true,
                DefaultDeletePropagation: 
metav1.DeletionPropagation(opts.DefaultDeletePropagation),
+               NoPodLogs:                opts.NoPodLogs,
        })
        if err != nil {
                return fmt.Errorf("build resources: %w", err)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nelm-1.24.1/pkg/action/release_uninstall.go 
new/nelm-1.24.3/pkg/action/release_uninstall.go
--- old/nelm-1.24.1/pkg/action/release_uninstall.go     2026-05-12 
15:56:02.000000000 +0200
+++ new/nelm-1.24.3/pkg/action/release_uninstall.go     2026-06-08 
18:00:18.000000000 +0200
@@ -196,6 +196,7 @@
                }
 
                log.Default.Debug(ctx, "Build release history")
+
                history, err := release.BuildHistory(releaseName, 
releaseStorage, release.HistoryOptions{})
                if err != nil {
                        return fmt.Errorf("build release history: %w", err)
@@ -213,6 +214,7 @@
                deployType := common.DeployTypeUninstall
 
                log.Default.Debug(ctx, "Convert previous release to resource 
specs")
+
                prevRelResSpecs, err := 
release.ReleaseToResourceSpecs(prevRelease, releaseNamespace, false)
                if err != nil {
                        return fmt.Errorf("convert previous release to resource 
specs: %w", err)
@@ -227,15 +229,18 @@
                }
 
                log.Default.Debug(ctx, "Build resources")
+
                instResources, delResources, err := 
resource.BuildResources(ctx, deployType, releaseNamespace, prevRelResSpecs, 
nil, patchers, clientFactory, resource.BuildResourcesOptions{
                        Remote:                   true,
                        DefaultDeletePropagation: 
metav1.DeletionPropagation(opts.DefaultDeletePropagation),
+                       NoPodLogs:                opts.NoPodLogs,
                })
                if err != nil {
                        return fmt.Errorf("build resources: %w", err)
                }
 
                log.Default.Debug(ctx, "Build resource infos")
+
                instResInfos, delResInfos, err := plan.BuildResourceInfos(ctx, 
deployType, releaseName, releaseNamespace, instResources, delResources, 
prevReleaseFailed, clientFactory, plan.BuildResourceInfosOptions{
                        NetworkParallelism:                 
opts.NetworkParallelism,
                        NoRemoveManualChanges:              
opts.NoRemoveManualChanges,
@@ -246,12 +251,14 @@
                }
 
                log.Default.Debug(ctx, "Build release infos")
+
                relInfos, err := plan.BuildReleaseInfos(ctx, deployType, 
releases, nil)
                if err != nil {
                        return fmt.Errorf("build release infos: %w", err)
                }
 
                log.Default.Debug(ctx, "Build delete plan")
+
                deletePlan, err := plan.BuildPlan(instResInfos, delResInfos, 
relInfos, plan.BuildPlanOptions{
                        NoFinalTracking: opts.NoFinalTracking,
                })
@@ -271,6 +278,7 @@
                logStore := kdutil.NewConcurrent(logstore.NewLogStore())
 
                log.Default.Debug(ctx, "Start tracking")
+
                var progressPrinter *track.ProgressTablesPrinter
                if !opts.NoProgressTablePrint {
                        progressPrinter = 
track.NewProgressTablesPrinter(taskStore, logStore, 
track.ProgressTablesPrinterOptions{
@@ -285,9 +293,13 @@
                var reporter *plan.LegacyProgressReporter
                if opts.LegacyProgressReportCh != nil {
                        reporter = 
plan.NewLegacyProgressReporter(opts.LegacyProgressReportCh)
+                       defer func() {
+                               close(opts.LegacyProgressReportCh)
+                       }()
                }
 
                log.Default.Debug(ctx, "Execute release delete plan")
+
                executePlanErr := plan.ExecutePlan(ctx, releaseNamespace, 
deletePlan, taskStore, logStore, informerFactory, history, clientFactory, 
plan.ExecutePlanOptions{
                        LegacyProgressReporter: reporter,
                        TrackingOptions:        opts.TrackingOptions,
@@ -322,6 +334,7 @@
 
                        criticalErrs.Add(critErrs)
                        nonCriticalErrs.Add(nonCritErrs)
+
                        if runFailurePlanResult != nil {
                                completedResourceOps = 
append(completedResourceOps, runFailurePlanResult.CompletedResourceOps...)
                                canceledResourceOps = 
append(canceledResourceOps, runFailurePlanResult.CanceledResourceOps...)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nelm-1.24.1/pkg/common/common.go 
new/nelm-1.24.3/pkg/common/common.go
--- old/nelm-1.24.1/pkg/common/common.go        2026-05-12 15:56:02.000000000 
+0200
+++ new/nelm-1.24.3/pkg/common/common.go        2026-06-08 18:00:18.000000000 
+0200
@@ -105,6 +105,7 @@
        DefaultReleaseHistoryLimit   = 10
        // DefaultResourceValidationKubeVersion Kubernetes version to use 
during resource validation by kubeconform
        DefaultResourceValidationKubeVersion = "1.35.0"
+       DefaultWebhookRetryTimeout           = 2 * time.Minute
        KubectlEditFieldManager              = "kubectl-edit"
        OldFieldManagerPrefix                = "werf"
        OutputFormatJSON                     = "json"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nelm-1.24.1/pkg/kube/client_kube.go 
new/nelm-1.24.3/pkg/kube/client_kube.go
--- old/nelm-1.24.1/pkg/kube/client_kube.go     2026-05-12 15:56:02.000000000 
+0200
+++ new/nelm-1.24.3/pkg/kube/client_kube.go     2026-06-08 18:00:18.000000000 
+0200
@@ -349,7 +349,7 @@
 }
 
 func retryOnWebhookErr(ctx context.Context, fn func() error) error {
-       retryCtx, cancel := context.WithTimeout(ctx, 2*time.Minute)
+       retryCtx, cancel := context.WithTimeoutCause(ctx, 
common.DefaultWebhookRetryTimeout, fmt.Errorf("context timed out: webhook retry 
timed out after %s", common.DefaultWebhookRetryTimeout.String()))
        defer cancel()
 
        if err := kvwait.PollUntilContextCancel(retryCtx, 2*time.Second, true, 
func(ctx context.Context) (bool, error) {
@@ -365,7 +365,11 @@
 
                return true, nil
        }); err != nil {
-               return fmt.Errorf("retry on webhook error: %w", err)
+               if retryCtx.Err() != nil {
+                       return fmt.Errorf("retryable on webhook error: %w", 
context.Cause(retryCtx))
+               }
+
+               return fmt.Errorf("retryable on webhook error: %w", err)
        }
 
        return nil
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nelm-1.24.1/pkg/plan/legacy_progress_reporter.go 
new/nelm-1.24.3/pkg/plan/legacy_progress_reporter.go
--- old/nelm-1.24.1/pkg/plan/legacy_progress_reporter.go        2026-05-12 
15:56:02.000000000 +0200
+++ new/nelm-1.24.3/pkg/plan/legacy_progress_reporter.go        2026-06-08 
18:00:18.000000000 +0200
@@ -49,10 +49,14 @@
                report = buildProgressReport(s.frozen, s.ops)
        })
 
-       select {
-       case r.reportCh <- report:
-       case <-ctx.Done():
-       }
+       func() {
+               defer func() { _ = recover() }()
+
+               select {
+               case r.reportCh <- report:
+               case <-ctx.Done():
+               }
+       }()
 }
 
 func (r *LegacyProgressReporter) startStage(p *Plan, resolvedNamespaces 
map[string]string) {
@@ -124,6 +128,10 @@
        typ         progrep.OperationType
 }
 
+func sendNonBlocking(ch chan<- progrep.ProgressReport, report 
progrep.ProgressReport) {
+       safeSend(ch, report)
+}
+
 func buildProgressReport(frozen []progrep.StageReport, ops []opEntry) 
progrep.ProgressReport {
        stageReports := make([]progrep.StageReport, 0, len(frozen)+1)
 
@@ -183,9 +191,15 @@
        }
 }
 
-func sendNonBlocking(ch chan<- progrep.ProgressReport, report 
progrep.ProgressReport) {
+func safeSend(ch chan<- progrep.ProgressReport, report progrep.ProgressReport) 
(sent bool) {
+       defer func() {
+               _ = recover()
+       }()
+
        select {
        case ch <- report:
+               return true
        default:
+               return false
        }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/nelm-1.24.1/pkg/plan/legacy_progress_reporter_ai_test.go 
new/nelm-1.24.3/pkg/plan/legacy_progress_reporter_ai_test.go
--- old/nelm-1.24.1/pkg/plan/legacy_progress_reporter_ai_test.go        
2026-05-12 15:56:02.000000000 +0200
+++ new/nelm-1.24.3/pkg/plan/legacy_progress_reporter_ai_test.go        
2026-06-08 18:00:18.000000000 +0200
@@ -267,6 +267,26 @@
        assert.Equal(t, OperationStatusCompleted, op.Status)
 }
 
+func TestAI_ReportStatus_DoesNotPanicOnClosedChannel(t *testing.T) {
+       ch := make(chan progrep.ProgressReport, 1)
+       reporter := NewLegacyProgressReporter(ch)
+
+       ops := []*Operation{
+               {
+                       Type: OperationTypeCreate, Version: 
OperationVersionCreate, Category: OperationCategoryResource,
+                       Config: &OperationConfigCreate{ResourceSpec: 
makeResourceSpec("cm1", "", gvkConfigMap)},
+               },
+       }
+       p := buildTestPlan(ops, nil)
+       reporter.startStage(p, map[string]string{ops[0].ID(): "default"})
+
+       close(ch)
+
+       assert.NotPanics(t, func() {
+               reporter.ReportStatus(ops[0].ID(), 
progrep.OperationStatusCompleted)
+       })
+}
+
 func TestAI_ReportStatus_SendsSnapshot(t *testing.T) {
        ch := make(chan progrep.ProgressReport, 64)
        reporter := NewLegacyProgressReporter(ch)
@@ -446,6 +466,15 @@
        }
 }
 
+func TestAI_SendNonBlocking_DoesNotPanicOnClosedChannel(t *testing.T) {
+       ch := make(chan progrep.ProgressReport, 1)
+       close(ch)
+
+       assert.NotPanics(t, func() {
+               sendNonBlocking(ch, progrep.ProgressReport{})
+       })
+}
+
 func TestAI_SendNonBlocking_DropsWhenFull(t *testing.T) {
        ch := make(chan progrep.ProgressReport, 1)
 
@@ -528,6 +557,26 @@
        assert.Equal(t, progrep.OperationStatusPending, activeOps[0].Status)
 }
 
+func TestAI_Stop_DoesNotPanicOnClosedChannel(t *testing.T) {
+       ch := make(chan progrep.ProgressReport, 1)
+       reporter := NewLegacyProgressReporter(ch)
+
+       ops := []*Operation{
+               {
+                       Type: OperationTypeCreate, Version: 
OperationVersionCreate, Category: OperationCategoryResource,
+                       Config: &OperationConfigCreate{ResourceSpec: 
makeResourceSpec("cm1", "", gvkConfigMap)},
+               },
+       }
+       p := buildTestPlan(ops, nil)
+       reporter.startStage(p, map[string]string{ops[0].ID(): "default"})
+
+       close(ch)
+
+       assert.NotPanics(t, func() {
+               reporter.Stop(context.Background())
+       })
+}
+
 func TestAI_Stop_SendsFinalReport(t *testing.T) {
        ch := make(chan progrep.ProgressReport, 64)
        reporter := NewLegacyProgressReporter(ch)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nelm-1.24.1/pkg/resource/dependency.go 
new/nelm-1.24.3/pkg/resource/dependency.go
--- old/nelm-1.24.1/pkg/resource/dependency.go  2026-05-12 15:56:02.000000000 
+0200
+++ new/nelm-1.24.3/pkg/resource/dependency.go  2026-06-08 18:00:18.000000000 
+0200
@@ -24,7 +24,7 @@
 // Automatically detects internal dependencies on resources by examining 
specific fields in the
 // resource spec. As an example, examining "envFrom" in a Pod container spec 
produces an internal
 // dependency on a ConfigMap or a Secret.
-func internalDeployDependencies(unstruct *unstructured.Unstructured) 
[]*InternalDependency {
+func internalDeployDependencies(unstruct *unstructured.Unstructured, 
otherUnstructs []*unstructured.Unstructured) []*InternalDependency {
        gvk := unstruct.GroupVersionKind()
        gk := gvk.GroupKind()
 
@@ -32,41 +32,41 @@
        switch gk {
        case schema.GroupKind{Kind: "Deployment", Group: "apps"}:
                if pod, found := nestedMap(unstruct.Object, "spec", 
"template"); found {
-                       if deps, found := parsePod(unstruct, pod); found {
+                       if deps, found := parsePod(unstruct, pod, 
otherUnstructs); found {
                                dependencies = append(dependencies, deps...)
                        }
                }
        case schema.GroupKind{Kind: "CronJob", Group: "batch"}:
                if pod, found := nestedMap(unstruct.Object, "spec", 
"jobTemplate", "spec", "template"); found {
-                       if deps, found := parsePod(unstruct, pod); found {
+                       if deps, found := parsePod(unstruct, pod, 
otherUnstructs); found {
                                dependencies = append(dependencies, deps...)
                        }
                }
        case schema.GroupKind{Kind: "DaemonSet", Group: "apps"}:
                if pod, found := nestedMap(unstruct.Object, "spec", 
"template"); found {
-                       if deps, found := parsePod(unstruct, pod); found {
+                       if deps, found := parsePod(unstruct, pod, 
otherUnstructs); found {
                                dependencies = append(dependencies, deps...)
                        }
                }
        case schema.GroupKind{Kind: "Job", Group: "batch"}:
                if pod, found := nestedMap(unstruct.Object, "spec", 
"template"); found {
-                       if deps, found := parsePod(unstruct, pod); found {
+                       if deps, found := parsePod(unstruct, pod, 
otherUnstructs); found {
                                dependencies = append(dependencies, deps...)
                        }
                }
        case schema.GroupKind{Kind: "Pod", Group: ""}:
-               if deps, found := parsePod(unstruct, unstruct.Object); found {
+               if deps, found := parsePod(unstruct, unstruct.Object, 
otherUnstructs); found {
                        dependencies = append(dependencies, deps...)
                }
        case schema.GroupKind{Kind: "ReplicaSet", Group: "apps"}:
                if pod, found := nestedMap(unstruct.Object, "spec", 
"template"); found {
-                       if deps, found := parsePod(unstruct, pod); found {
+                       if deps, found := parsePod(unstruct, pod, 
otherUnstructs); found {
                                dependencies = append(dependencies, deps...)
                        }
                }
        case schema.GroupKind{Kind: "ReplicationController", Group: ""}:
                if pod, found := nestedMap(unstruct.Object, "spec", 
"template"); found {
-                       if deps, found := parsePod(unstruct, pod); found {
+                       if deps, found := parsePod(unstruct, pod, 
otherUnstructs); found {
                                dependencies = append(dependencies, deps...)
                        }
                }
@@ -76,7 +76,7 @@
                }
 
                if pod, found := nestedMap(unstruct.Object, "spec", 
"template"); found {
-                       if deps, found := parsePod(unstruct, pod); found {
+                       if deps, found := parsePod(unstruct, pod, 
otherUnstructs); found {
                                dependencies = append(dependencies, deps...)
                        }
                }
@@ -84,12 +84,16 @@
                if dep, found := parseRoleRef(*unstruct); found {
                        dependencies = append(dependencies, dep)
                }
+
+               if deps, found := parseBindingSubjects(unstruct); found {
+                       dependencies = append(dependencies, deps...)
+               }
        }
 
        return dependencies
 }
 
-func parsePod(unstruct *unstructured.Unstructured, pod interface{}) 
(dependencies []*InternalDependency, found bool) {
+func parsePod(unstruct *unstructured.Unstructured, pod interface{}, 
otherUnstructs []*unstructured.Unstructured) (dependencies 
[]*InternalDependency, found bool) {
        containers, _ := nestedSlice(pod, "spec", "containers")
        for _, container := range containers {
                if deps, found := parseContainer(unstruct, container); found {
@@ -145,6 +149,10 @@
                dependencies = append(dependencies, dep)
        }
 
+       if deps, found := parseBindingDependenciesForWorkload(pod, 
otherUnstructs); found {
+               dependencies = append(dependencies, deps...)
+       }
+
        volumes, _ := nestedSlice(pod, "spec", "volumes")
        for _, volume := range volumes {
                if dep, found := parseVolume(unstruct, volume); found {
@@ -205,6 +213,81 @@
        return dependencies, len(dependencies) > 0
 }
 
+func parseBindingDependenciesForWorkload(pod interface{}, otherUnstructs 
[]*unstructured.Unstructured) (dependencies []*InternalDependency, found bool) {
+       serviceAccountName, _ := nestedStringNotEmpty(pod, "spec", 
"serviceAccountName")
+       if serviceAccountName == "" {
+               serviceAccountName, _ = nestedStringNotEmpty(pod, "spec", 
"serviceAccount")
+       }
+
+       if serviceAccountName == "" {
+               return nil, false
+       }
+
+       bindingUnstructs := lo.Filter(otherUnstructs, func(u 
*unstructured.Unstructured, _ int) bool {
+               switch u.GroupVersionKind().GroupKind() {
+               case schema.GroupKind{Kind: "RoleBinding", Group: 
"rbac.authorization.k8s.io"},
+                       schema.GroupKind{Kind: "ClusterRoleBinding", Group: 
"rbac.authorization.k8s.io"}:
+                       return true
+               default:
+                       return false
+               }
+       })
+
+       for _, bindingUnstruct := range bindingUnstructs {
+               subjects, _ := nestedSlice(bindingUnstruct.Object, "subjects")
+               for _, subj := range subjects {
+                       kind, ok := nestedString(subj, "kind")
+                       if !ok || kind != "ServiceAccount" {
+                               continue
+                       }
+
+                       name, ok := nestedString(subj, "name")
+                       if !ok || name != serviceAccountName {
+                               continue
+                       }
+
+                       dep := &InternalDependency{
+                               ResourceMatcher: 
newExactResourceMatcher(bindingUnstruct),
+                               ResourceState:   common.ResourceStatePresent,
+                       }
+                       dependencies = append(dependencies, dep)
+
+                       break
+               }
+       }
+
+       return dependencies, len(dependencies) > 0
+}
+
+func parseBindingSubjects(unstruct *unstructured.Unstructured) (dependencies 
[]*InternalDependency, found bool) {
+       subjects, _ := nestedSlice(unstruct.Object, "subjects")
+       for _, subj := range subjects {
+               kind, found := nestedString(subj, "kind")
+               if !found || kind != "ServiceAccount" {
+                       continue
+               }
+
+               serviceAccountName, found := nestedString(subj, "name")
+               if !found {
+                       continue
+               }
+
+               dep := &InternalDependency{
+                       ResourceMatcher: &spec.ResourceMatcher{
+                               Names:      []string{serviceAccountName},
+                               Namespaces: []string{unstruct.GetNamespace()},
+                               Groups:     []string{""},
+                               Kinds:      []string{"ServiceAccount"},
+                       },
+                       ResourceState: common.ResourceStatePresent,
+               }
+
+               dependencies = append(dependencies, dep)
+       }
+
+       return dependencies, len(dependencies) > 0
+}
+
 func parseCRD(unstruct *unstructured.Unstructured) (dep *InternalDependency, 
found bool) {
        kind, found := nestedString(unstruct.Object, "spec", "names", "kind")
        if !found {
@@ -597,6 +680,30 @@
                        nestedPath = []string{"spec", "template", "spec", 
"serviceAccountName"}
                case schema.GroupKind{Kind: "CronJob", Group: "batch"}:
                        nestedPath = []string{"spec", "jobTemplate", "spec", 
"template", "spec", "serviceAccountName"}
+               case schema.GroupKind{Kind: "ClusterRoleBinding", Group: 
"rbac.authorization.k8s.io"},
+                       schema.GroupKind{Kind: "RoleBinding", Group: 
"rbac.authorization.k8s.io"}:
+                       subjects, _ := nestedSlice(otherUnstruct.Object, 
"subjects")
+                       for _, subj := range subjects {
+                               kind, ok := nestedString(subj, "kind")
+                               if !ok || kind != "ServiceAccount" {
+                                       continue
+                               }
+
+                               name, ok := nestedString(subj, "name")
+                               if !ok || name != unstruct.GetName() {
+                                       continue
+                               }
+
+                               dep := &InternalDependency{
+                                       ResourceMatcher: 
newExactResourceMatcher(otherUnstruct),
+                                       ResourceState:   
common.ResourceStateAbsent,
+                               }
+                               dependencies = append(dependencies, dep)
+
+                               break
+                       }
+
+                       continue
                default:
                        continue
                }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nelm-1.24.1/pkg/resource/helpers_ai_test.go 
new/nelm-1.24.3/pkg/resource/helpers_ai_test.go
--- old/nelm-1.24.1/pkg/resource/helpers_ai_test.go     2026-05-12 
15:56:02.000000000 +0200
+++ new/nelm-1.24.3/pkg/resource/helpers_ai_test.go     2026-06-08 
18:00:18.000000000 +0200
@@ -103,7 +103,7 @@
        unstruct := &unstructured.Unstructured{Object: obj}
        resSpec := spec.NewResourceSpec(unstruct, releaseNamespace, 
spec.ResourceSpecOptions{})
 
-       instRes, err := resource.NewInstallableResource(resSpec, 
releaseNamespace, nil, resource.InstallableResourceOptions{})
+       instRes, err := resource.NewInstallableResource(resSpec, nil, 
releaseNamespace, nil, resource.InstallableResourceOptions{})
        require.NoError(t, err)
 
        return instRes
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nelm-1.24.1/pkg/resource/metadata.go 
new/nelm-1.24.3/pkg/resource/metadata.go
--- old/nelm-1.24.1/pkg/resource/metadata.go    2026-05-12 15:56:02.000000000 
+0200
+++ new/nelm-1.24.3/pkg/resource/metadata.go    2026-06-08 18:00:18.000000000 
+0200
@@ -69,7 +69,7 @@
 
 func deployConditions(meta *spec.ResourceMeta, hasManualInternalDeps bool) 
map[common.On][]common.Stage {
        if conditions := deployConditionsForAnnotation(meta, 
common.AnnotationKeyPatternDeployOn); len(conditions) > 0 {
-               if spec.IsCRD(meta.GroupVersionKind.GroupKind()) {
+               if spec.IsCRD(meta.GroupVersionKind.GroupKind()) || 
spec.IsNamespace(meta.GroupVersionKind) {
                        for on := range conditions {
                                conditions[on] = 
[]common.Stage{common.StagePrePreInstall}
                        }
@@ -80,7 +80,7 @@
 
        if spec.IsHook(meta.Annotations) {
                if conditions := deployConditionsForAnnotation(meta, 
common.AnnotationKeyPatternHook); len(conditions) > 0 {
-                       if spec.IsCRD(meta.GroupVersionKind.GroupKind()) {
+                       if spec.IsCRD(meta.GroupVersionKind.GroupKind()) || 
spec.IsNamespace(meta.GroupVersionKind) {
                                for on := range conditions {
                                        conditions[on] = 
[]common.Stage{common.StagePrePreInstall}
                                }
@@ -90,6 +90,14 @@
                }
        }
 
+       if spec.IsNamespace(meta.GroupVersionKind) {
+               return map[common.On][]common.Stage{
+                       common.InstallOnInstall:  {common.StagePrePreInstall},
+                       common.InstallOnUpgrade:  {common.StagePrePreInstall},
+                       common.InstallOnRollback: {common.StagePrePreInstall},
+               }
+       }
+
        if spec.IsCRD(meta.GroupVersionKind.GroupKind()) {
                return map[common.On][]common.Stage{
                        common.InstallOnInstall:  {common.StagePrePreInstall},
@@ -711,7 +719,11 @@
        return regexByContainer
 }
 
-func skipLogs(meta *spec.ResourceMeta) bool {
+func skipLogs(meta *spec.ResourceMeta, noPodLogs bool) bool {
+       if noPodLogs {
+               return true
+       }
+
        _, value, found := 
spec.FindAnnotationOrLabelByKeyPattern(meta.Annotations, 
common.AnnotationKeyPatternSkipLogs)
        if !found {
                return false
@@ -1458,7 +1470,7 @@
                return nil
        }
 
-       if spec.IsCRD(meta.GroupVersionKind.GroupKind()) {
+       if spec.IsCRD(meta.GroupVersionKind.GroupKind()) || 
spec.IsNamespace(meta.GroupVersionKind) {
                return lo.ToPtr(0)
        }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nelm-1.24.1/pkg/resource/resource.go 
new/nelm-1.24.3/pkg/resource/resource.go
--- old/nelm-1.24.1/pkg/resource/resource.go    2026-05-12 15:56:02.000000000 
+0200
+++ new/nelm-1.24.3/pkg/resource/resource.go    2026-06-08 18:00:18.000000000 
+0200
@@ -54,7 +54,7 @@
 
 // Construct an InstallableResource from a ResourceSpec. Must never contact 
the cluster, because
 // this is called even when no cluster access allowed.
-func NewInstallableResource(res *spec.ResourceSpec, releaseNamespace string, 
clientFactory kube.ClientFactorier, opts InstallableResourceOptions) 
(*InstallableResource, error) {
+func NewInstallableResource(res *spec.ResourceSpec, otherResSpecs 
[]*spec.ResourceSpec, releaseNamespace string, clientFactory 
kube.ClientFactorier, opts InstallableResourceOptions) (*InstallableResource, 
error) {
        if err := validateHook(res.ResourceMeta); err != nil {
                return nil, fmt.Errorf("validate hook configuration: %w", err)
        }
@@ -114,9 +114,13 @@
 
        manIntDeps := manualInternalDeployDependencies(res.ResourceMeta)
 
+       otherUnstructs := lo.Map(otherResSpecs, func(resSpec 
*spec.ResourceSpec, _ int) *unstructured.Unstructured {
+               return resSpec.Unstruct
+       })
+
        return &InstallableResource{
                ResourceSpec:                           res,
-               AutoInternalDependencies:               
internalDeployDependencies(res.Unstruct),
+               AutoInternalDependencies:               
internalDeployDependencies(res.Unstruct, otherUnstructs),
                DefaultReplicasOnCreation:              
defaultReplicasOnCreation(res.ResourceMeta, releaseNamespace),
                DeleteOnFailed:                         
deleteOnFailed(res.ResourceMeta),
                DeleteOnSucceeded:                      
deleteOnSucceeded(res.ResourceMeta),
@@ -137,7 +141,7 @@
                ShowLogsOnlyForContainers:              
showLogsOnlyForContainers(res.ResourceMeta),
                ShowLogsOnlyForNumberOfReplicas:        
showLogsOnlyForNumberOfReplicas(res.ResourceMeta),
                ShowServiceMessages:                    
showServiceMessages(res.ResourceMeta),
-               SkipLogs:                               
skipLogs(res.ResourceMeta),
+               SkipLogs:                               
skipLogs(res.ResourceMeta, opts.NoPodLogs),
                SkipLogsForContainers:                  
skipLogsForContainers(res.ResourceMeta),
                SkipLogsRegex:                          
skipLogRegex(res.ResourceMeta),
                SkipLogsRegexForContainers:             
skipLogRegexesForContainers(res.ResourceMeta),
@@ -148,6 +152,7 @@
 
 type InstallableResourceOptions struct {
        DefaultDeletePropagation metav1.DeletionPropagation
+       NoPodLogs                bool
        Remote                   bool
 }
 
@@ -213,6 +218,7 @@
 
 type BuildResourcesOptions struct {
        DefaultDeletePropagation metav1.DeletionPropagation
+       NoPodLogs                bool
        Remote                   bool
 }
 
@@ -231,8 +237,9 @@
 
        var prevRelInstResources []*InstallableResource
        for _, resSpec := range prevRelResSpecs {
-               installableResource, err := NewInstallableResource(resSpec, 
releaseNamespace, clientFactory, InstallableResourceOptions{
+               installableResource, err := NewInstallableResource(resSpec, 
lo.Without(prevRelResSpecs, resSpec), releaseNamespace, clientFactory, 
InstallableResourceOptions{
                        DefaultDeletePropagation: opts.DefaultDeletePropagation,
+                       NoPodLogs:                opts.NoPodLogs,
                        Remote:                   opts.Remote,
                })
                if err != nil {
@@ -244,8 +251,9 @@
 
        var newRelInstResources []*InstallableResource
        for _, resSpec := range newRelResSpecs {
-               installableResource, err := NewInstallableResource(resSpec, 
releaseNamespace, clientFactory, InstallableResourceOptions{
+               installableResource, err := NewInstallableResource(resSpec, 
lo.Without(newRelResSpecs, resSpec), releaseNamespace, clientFactory, 
InstallableResourceOptions{
                        DefaultDeletePropagation: opts.DefaultDeletePropagation,
+                       NoPodLogs:                opts.NoPodLogs,
                        Remote:                   opts.Remote,
                })
                if err != nil {
@@ -340,8 +348,9 @@
                                FilePath: instRes.FilePath,
                        })
 
-                       instRes, err = NewInstallableResource(resSpec, 
releaseNamespace, clientFactory, InstallableResourceOptions{
+                       instRes, err = NewInstallableResource(resSpec, 
newRelResSpecs, releaseNamespace, clientFactory, InstallableResourceOptions{
                                DefaultDeletePropagation: 
opts.DefaultDeletePropagation,
+                               NoPodLogs:                opts.NoPodLogs,
                                Remote:                   opts.Remote,
                        })
                        if err != nil {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nelm-1.24.1/pkg/resource/resource_test.go 
new/nelm-1.24.3/pkg/resource/resource_test.go
--- old/nelm-1.24.1/pkg/resource/resource_test.go       2026-05-12 
15:56:02.000000000 +0200
+++ new/nelm-1.24.3/pkg/resource/resource_test.go       2026-06-08 
18:00:18.000000000 +0200
@@ -389,9 +389,10 @@
                        },
                        input: func() *spec.ResourceSpec {
                                resSpec := 
defaultResourceSpec(s.releaseNamespace)
-                               
resSpec.SetAnnotations(lo.Assign(resSpec.Annotations, map[string]string{
-                                       "werf.io/deploy-dependency-backend": 
"state=present,name=backend",
-                               },
+                               resSpec.SetAnnotations(lo.Assign(
+                                       resSpec.Annotations, map[string]string{
+                                               
"werf.io/deploy-dependency-backend": "state=present,name=backend",
+                                       },
                                ))
 
                                return resSpec
@@ -506,6 +507,212 @@
                        },
                        name: `for Deployment resource with auto internal 
dependency on configmap`,
                },
+               {
+                       expect: func(resSpec *spec.ResourceSpec) 
*resource.InstallableResource {
+                               res := defaultInstallableResource(resSpec)
+                               res.AutoInternalDependencies = 
[]*resource.InternalDependency{
+                                       {
+                                               ResourceMatcher: 
&spec.ResourceMatcher{
+                                                       Names:  
[]string{"test-cr"},
+                                                       Groups: 
[]string{"rbac.authorization.k8s.io"},
+                                                       Kinds:  
[]string{"ClusterRole"},
+                                               },
+                                               ResourceState: 
common.ResourceStatePresent,
+                                       },
+                                       {
+                                               ResourceMatcher: 
&spec.ResourceMatcher{
+                                                       Names:      
[]string{"test-sa"},
+                                                       Namespaces: 
[]string{""},
+                                                       Groups:     
[]string{""},
+                                                       Kinds:      
[]string{"ServiceAccount"},
+                                               },
+                                               ResourceState: 
common.ResourceStatePresent,
+                                       },
+                               }
+
+                               return res
+                       },
+                       input: func() *spec.ResourceSpec {
+                               return 
spec.NewResourceSpec(&unstructured.Unstructured{
+                                       Object: map[string]interface{}{
+                                               "apiVersion": 
"rbac.authorization.k8s.io/v1",
+                                               "kind":       
"ClusterRoleBinding",
+                                               "metadata": 
map[string]interface{}{
+                                                       "name": "test-crb",
+                                               },
+                                               "subjects": []interface{}{
+                                                       map[string]interface{}{
+                                                               "kind":      
"ServiceAccount",
+                                                               "name":      
"test-sa",
+                                                               "namespace": 
"test-namespace",
+                                                       },
+                                               },
+                                               "roleRef": 
map[string]interface{}{
+                                                       "apiGroup": 
"rbac.authorization.k8s.io",
+                                                       "kind":     
"ClusterRole",
+                                                       "name":     "test-cr",
+                                               },
+                                       },
+                               }, s.releaseNamespace, 
spec.ResourceSpecOptions{})
+                       },
+                       name: `for ClusterRoleBinding resource with auto 
internal dependency on ServiceAccount from subjects`,
+               },
+               {
+                       expect: func(resSpec *spec.ResourceSpec) 
*resource.InstallableResource {
+                               res := 
defaultDeploymentInstallableResource(resSpec)
+                               res.AutoInternalDependencies = 
[]*resource.InternalDependency{
+                                       {
+                                               ResourceMatcher: 
&spec.ResourceMatcher{
+                                                       Names:      
[]string{"my-sa"},
+                                                       Namespaces: 
[]string{""},
+                                                       Groups:     
[]string{""},
+                                                       Kinds:      
[]string{"ServiceAccount"},
+                                               },
+                                               ResourceState: 
common.ResourceStatePresent,
+                                       },
+                                       {
+                                               ResourceMatcher: 
&spec.ResourceMatcher{
+                                                       Names:      
[]string{"my-rb"},
+                                                       Namespaces: 
[]string{""},
+                                                       Groups:     
[]string{"rbac.authorization.k8s.io"},
+                                                       Kinds:      
[]string{"RoleBinding"},
+                                               },
+                                               ResourceState: 
common.ResourceStatePresent,
+                                       },
+                               }
+
+                               return res
+                       },
+                       input: func() *spec.ResourceSpec {
+                               resSpec := 
defaultDeploymentResourceSpec(s.releaseNamespace)
+                               err := 
unstructured.SetNestedField(resSpec.Unstruct.UnstructuredContent(), "my-sa", 
"spec", "template", "spec", "serviceAccountName")
+                               s.Require().NoError(err)
+
+                               return resSpec
+                       },
+                       name: `for Deployment with auto dependency on 
RoleBinding via shared ServiceAccount`,
+                       otherInput: func() []*spec.ResourceSpec {
+                               return []*spec.ResourceSpec{
+                                       
spec.NewResourceSpec(&unstructured.Unstructured{
+                                               Object: map[string]interface{}{
+                                                       "apiVersion": 
"rbac.authorization.k8s.io/v1",
+                                                       "kind":       
"RoleBinding",
+                                                       "metadata": 
map[string]interface{}{
+                                                               "name":      
"my-rb",
+                                                               "namespace": 
"test-namespace",
+                                                       },
+                                                       "subjects": 
[]interface{}{
+                                                               
map[string]interface{}{
+                                                                       "kind": 
     "ServiceAccount",
+                                                                       "name": 
     "my-sa",
+                                                                       
"namespace": "test-namespace",
+                                                               },
+                                                       },
+                                                       "roleRef": 
map[string]interface{}{
+                                                               "apiGroup": 
"rbac.authorization.k8s.io",
+                                                               "kind":     
"Role",
+                                                               "name":     
"my-role",
+                                                       },
+                                               },
+                                       }, s.releaseNamespace, 
spec.ResourceSpecOptions{}),
+                               }
+                       },
+               },
+               {
+                       expect: func(resSpec *spec.ResourceSpec) 
*resource.InstallableResource {
+                               res := 
defaultDeploymentInstallableResource(resSpec)
+                               res.AutoInternalDependencies = 
[]*resource.InternalDependency{
+                                       {
+                                               ResourceMatcher: 
&spec.ResourceMatcher{
+                                                       Names:      
[]string{"my-sa"},
+                                                       Namespaces: 
[]string{""},
+                                                       Groups:     
[]string{""},
+                                                       Kinds:      
[]string{"ServiceAccount"},
+                                               },
+                                               ResourceState: 
common.ResourceStatePresent,
+                                       },
+                                       {
+                                               ResourceMatcher: 
&spec.ResourceMatcher{
+                                                       Names:      
[]string{"my-crb"},
+                                                       Namespaces: 
[]string{""},
+                                                       Groups:     
[]string{"rbac.authorization.k8s.io"},
+                                                       Kinds:      
[]string{"ClusterRoleBinding"},
+                                               },
+                                               ResourceState: 
common.ResourceStatePresent,
+                                       },
+                               }
+
+                               return res
+                       },
+                       input: func() *spec.ResourceSpec {
+                               resSpec := 
defaultDeploymentResourceSpec(s.releaseNamespace)
+                               err := 
unstructured.SetNestedField(resSpec.Unstruct.UnstructuredContent(), "my-sa", 
"spec", "template", "spec", "serviceAccountName")
+                               s.Require().NoError(err)
+
+                               return resSpec
+                       },
+                       name: `for Deployment with auto dependency on 
ClusterRoleBinding via shared ServiceAccount`,
+                       otherInput: func() []*spec.ResourceSpec {
+                               return []*spec.ResourceSpec{
+                                       
spec.NewResourceSpec(&unstructured.Unstructured{
+                                               Object: map[string]interface{}{
+                                                       "apiVersion": 
"rbac.authorization.k8s.io/v1",
+                                                       "kind":       
"ClusterRoleBinding",
+                                                       "metadata": 
map[string]interface{}{
+                                                               "name": 
"my-crb",
+                                                       },
+                                                       "subjects": 
[]interface{}{
+                                                               
map[string]interface{}{
+                                                                       "kind": 
     "ServiceAccount",
+                                                                       "name": 
     "my-sa",
+                                                                       
"namespace": "test-namespace",
+                                                               },
+                                                       },
+                                                       "roleRef": 
map[string]interface{}{
+                                                               "apiGroup": 
"rbac.authorization.k8s.io",
+                                                               "kind":     
"ClusterRole",
+                                                               "name":     
"my-cr",
+                                                       },
+                                               },
+                                       }, s.releaseNamespace, 
spec.ResourceSpecOptions{}),
+                               }
+                       },
+               },
+               {
+                       expect: func(resSpec *spec.ResourceSpec) 
*resource.InstallableResource {
+                               return 
defaultDeploymentInstallableResource(resSpec)
+                       },
+                       input: func() *spec.ResourceSpec {
+                               return 
defaultDeploymentResourceSpec(s.releaseNamespace)
+                       },
+                       name: `for Deployment with no explicit ServiceAccount 
produces no binding dependency`,
+                       otherInput: func() []*spec.ResourceSpec {
+                               return []*spec.ResourceSpec{
+                                       
spec.NewResourceSpec(&unstructured.Unstructured{
+                                               Object: map[string]interface{}{
+                                                       "apiVersion": 
"rbac.authorization.k8s.io/v1",
+                                                       "kind":       
"RoleBinding",
+                                                       "metadata": 
map[string]interface{}{
+                                                               "name":      
"my-rb",
+                                                               "namespace": 
"test-namespace",
+                                                       },
+                                                       "subjects": 
[]interface{}{
+                                                               
map[string]interface{}{
+                                                                       "kind": 
     "ServiceAccount",
+                                                                       "name": 
     "other-sa",
+                                                                       
"namespace": "test-namespace",
+                                                               },
+                                                       },
+                                                       "roleRef": 
map[string]interface{}{
+                                                               "apiGroup": 
"rbac.authorization.k8s.io",
+                                                               "kind":     
"Role",
+                                                               "name":     
"my-role",
+                                                       },
+                                               },
+                                       }, s.releaseNamespace, 
spec.ResourceSpecOptions{}),
+                               }
+                       },
+               },
        }
 
        for _, tc := range testCases {
@@ -996,10 +1203,11 @@
 }
 
 type installableResourceTestCase struct {
-       expect func(resSpec *spec.ResourceSpec) *resource.InstallableResource
-       input  func() *spec.ResourceSpec
-       name   string
-       skip   bool
+       expect     func(resSpec *spec.ResourceSpec) 
*resource.InstallableResource
+       input      func() *spec.ResourceSpec
+       name       string
+       otherInput func() []*spec.ResourceSpec
+       skip       bool
 }
 
 type DeletableResourceSuite struct {
@@ -1016,6 +1224,68 @@
        }
 }
 
+func (s *DeletableResourceSuite) TestNewDeletableResourceForAutoDependencies() 
{
+       testCases := []deletableResourceTestCase{
+               {
+                       expectFunc: func(resSpec *spec.ResourceSpec) 
*resource.DeletableResource {
+                               res := 
defaultDeletableResource(resSpec.ResourceMeta)
+                               res.AutoInternalDependencies = 
[]*resource.InternalDependency{
+                                       {
+                                               ResourceMatcher: 
&spec.ResourceMatcher{
+                                                       Names:      
[]string{"test-crb"},
+                                                       Namespaces: 
[]string{""},
+                                                       Groups:     
[]string{"rbac.authorization.k8s.io"},
+                                                       Kinds:      
[]string{"ClusterRoleBinding"},
+                                               },
+                                               ResourceState: 
common.ResourceStateAbsent,
+                                       },
+                               }
+
+                               return res
+                       },
+                       inputFunc: func() *spec.ResourceSpec {
+                               return 
spec.NewResourceSpec(&unstructured.Unstructured{
+                                       Object: map[string]interface{}{
+                                               "apiVersion": "v1",
+                                               "kind":       "ServiceAccount",
+                                               "metadata": 
map[string]interface{}{
+                                                       "name": "test-sa",
+                                               },
+                                       },
+                               }, s.releaseNamespace, 
spec.ResourceSpecOptions{})
+                       },
+                       name: "for ServiceAccount resource with auto internal 
delete dependency on ClusterRoleBinding from subjects",
+                       otherInputSpec: []*spec.ResourceSpec{
+                               spec.NewResourceSpec(&unstructured.Unstructured{
+                                       Object: map[string]interface{}{
+                                               "apiVersion": 
"rbac.authorization.k8s.io/v1",
+                                               "kind":       
"ClusterRoleBinding",
+                                               "metadata": 
map[string]interface{}{
+                                                       "name": "test-crb",
+                                               },
+                                               "subjects": []interface{}{
+                                                       map[string]interface{}{
+                                                               "kind":      
"ServiceAccount",
+                                                               "name":      
"test-sa",
+                                                               "namespace": 
"test-namespace",
+                                                       },
+                                               },
+                                               "roleRef": 
map[string]interface{}{
+                                                       "apiGroup": 
"rbac.authorization.k8s.io",
+                                                       "kind":     
"ClusterRole",
+                                                       "name":     "test-cr",
+                                               },
+                                       },
+                               }, s.releaseNamespace, 
spec.ResourceSpecOptions{}),
+                       },
+               },
+       }
+
+       for _, tc := range testCases {
+               s.Run(tc.name, runDeletableResourceTest(tc, s))
+       }
+}
+
 func (s *DeletableResourceSuite) TestNewDeletableResourceForDefaults() {
        testCases := []deletableResourceTestCase{
                {
@@ -1087,10 +1357,11 @@
 }
 
 type deletableResourceTestCase struct {
-       expectFunc func(resSpec *spec.ResourceSpec) *resource.DeletableResource
-       inputFunc  func() *spec.ResourceSpec
-       name       string
-       skip       bool
+       expectFunc     func(resSpec *spec.ResourceSpec) 
*resource.DeletableResource
+       inputFunc      func() *spec.ResourceSpec
+       name           string
+       otherInputSpec []*spec.ResourceSpec
+       skip           bool
 }
 
 func TestResourceSuites(t *testing.T) {
@@ -1161,6 +1432,11 @@
        res := defaultInstallableResource(resSpec)
        res.Ownership = common.OwnershipAnyone
        res.KeepOnDelete = true
+       res.DeployConditions = map[common.On][]common.Stage{
+               common.InstallOnInstall:  {common.StagePrePreInstall},
+               common.InstallOnUpgrade:  {common.StagePrePreInstall},
+               common.InstallOnRollback: {common.StagePrePreInstall},
+       }
 
        return res
 }
@@ -1269,7 +1545,12 @@
 
                resSpec := tc.inputFunc()
 
-               res := resource.NewDeletableResource(resSpec, 
[]*spec.ResourceSpec{}, s.releaseNamespace, resource.DeletableResourceOptions{})
+               otherSpecs := tc.otherInputSpec
+               if otherSpecs == nil {
+                       otherSpecs = []*spec.ResourceSpec{}
+               }
+
+               res := resource.NewDeletableResource(resSpec, otherSpecs, 
s.releaseNamespace, resource.DeletableResourceOptions{})
 
                expectRes := tc.expectFunc(resSpec)
 
@@ -1287,7 +1568,12 @@
 
                resSpec := tc.input()
 
-               res, err := resource.NewInstallableResource(resSpec, 
s.releaseNamespace, s.clientFactory, resource.InstallableResourceOptions{})
+               var otherResSpecs []*spec.ResourceSpec
+               if tc.otherInput != nil {
+                       otherResSpecs = tc.otherInput()
+               }
+
+               res, err := resource.NewInstallableResource(resSpec, 
otherResSpecs, s.releaseNamespace, s.clientFactory, 
resource.InstallableResourceOptions{})
                s.Require().NoError(err)
 
                expectRes := tc.expect(resSpec)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nelm-1.24.1/pkg/resource/spec/util.go 
new/nelm-1.24.3/pkg/resource/spec/util.go
--- old/nelm-1.24.1/pkg/resource/spec/util.go   2026-05-12 15:56:02.000000000 
+0200
+++ new/nelm-1.24.3/pkg/resource/spec/util.go   2026-06-08 18:00:18.000000000 
+0200
@@ -91,6 +91,10 @@
        }
 }
 
+func IsNamespace(gvk schema.GroupVersionKind) bool {
+       return gvk.Group == "" && gvk.Kind == "Namespace"
+}
+
 func IsReleaseNamespace(resourceName string, resourceGVK 
schema.GroupVersionKind, releaseNamespace string) bool {
        return resourceGVK.Group == "" && resourceGVK.Kind == "Namespace" && 
resourceName == releaseNamespace
 }
Binary files old/nelm-1.24.1/resources/images/nelm-logo.png and 
new/nelm-1.24.3/resources/images/nelm-logo.png differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nelm-1.24.1/trdl_channels.yaml 
new/nelm-1.24.3/trdl_channels.yaml
--- old/nelm-1.24.1/trdl_channels.yaml  2026-05-12 15:56:02.000000000 +0200
+++ new/nelm-1.24.3/trdl_channels.yaml  2026-06-08 18:00:18.000000000 +0200
@@ -2,12 +2,12 @@
   - name: "1"
     channels:
       - name: alpha
-        version: 1.24.0
+        version: 1.24.1
       - name: beta
-        version: 1.23.2
+        version: 1.24.0
       - name: ea
-        version: 1.22.0
+        version: 1.23.2
       - name: stable
         version: 1.22.0
       - name: rock-solid
-        version: 1.21.0
+        version: 1.22.0

++++++ nelm.obsinfo ++++++
--- /var/tmp/diff_new_pack.uxAAih/_old  2026-07-06 12:36:56.681023248 +0200
+++ /var/tmp/diff_new_pack.uxAAih/_new  2026-07-06 12:36:56.689023526 +0200
@@ -1,5 +1,5 @@
 name: nelm
-version: 1.24.1
-mtime: 1778594162
-commit: 9366af9135202b7d705c71fef6c7dbe0231c0345
+version: 1.24.3
+mtime: 1780934418
+commit: c0c3c7ab1457fbf634acee9b2d2a29b9cdc101d4
 

++++++ vendor.tar.gz ++++++
/work/SRC/openSUSE:Factory/nelm/vendor.tar.gz 
/work/SRC/openSUSE:Factory/.nelm.new.1982/vendor.tar.gz differ: char 13, line 1

Reply via email to