@@ -68,9 +68,8 @@ var logGroupOut io.Writer = os.Stdout
6868var logGroupDepth int32
6969
7070// LogGroupSentinelEnv returns the "KEY=VALUE" environment entry that
71- // orchestrators append to a step/command subprocess's environment while
72- // grouping is enabled, so nested `atmos` invocations skip re-grouping. Callers
73- // append it only when GroupingEnabled reports true.
71+ // orchestrators append to a step/command subprocess's environment while that
72+ // subprocess is inside, or is about to be inside, a CI log group.
7473func LogGroupSentinelEnv () string {
7574 defer perf .Track (nil , "ci.LogGroupSentinelEnv" )()
7675
@@ -132,21 +131,32 @@ func grouper(atmosConfig *schema.AtmosConfiguration) (provider.LogGrouper, bool)
132131 return lg , true
133132}
134133
135- // GroupingEnabled reports whether CI log grouping is active for this run in any
136- // dimension: a grouping mode other than "off" is configured, a grouping-capable
137- // provider is detected, and no parent Atmos process already has grouping open.
138- //
139- // Orchestrators use it to decide whether to append LogGroupSentinelEnv to a
140- // child subprocess's environment — which must happen whenever grouping is
141- // enabled, regardless of which dimension the current command emits, so that a
142- // nested `atmos` invocation never emits its own (nested) groups.
134+ // GroupingEnabled reports whether CI log grouping is available for this run in
135+ // any dimension: a grouping mode other than "off" is configured, a
136+ // grouping-capable provider is detected, and no parent Atmos process already has
137+ // grouping open.
143138func GroupingEnabled (atmosConfig * schema.AtmosConfiguration ) bool {
144139 defer perf .Track (nil , "ci.GroupingEnabled" )()
145140
146141 _ , ok := grouper (atmosConfig )
147142 return ok
148143}
149144
145+ // ShouldPropagateLogGroupSentinel reports whether a subprocess launched at dim
146+ // should inherit LogGroupSentinelEnv. It is true when a group is already open in
147+ // this Atmos process, or when the configured mode/provider would open a group at
148+ // dim. This keeps child Atmos invocations from suppressing their own grouping
149+ // unless a parent group actually exists or will be opened for this boundary.
150+ func ShouldPropagateLogGroupSentinel (atmosConfig * schema.AtmosConfiguration , dim Dimension ) bool {
151+ defer perf .Track (nil , "ci.ShouldPropagateLogGroupSentinel" )()
152+
153+ if atomic .LoadInt32 (& logGroupDepth ) > 0 {
154+ return true
155+ }
156+ _ , ok := grouper (atmosConfig )
157+ return ok && dimensionActive (resolveGroupMode (atmosConfig ), dim )
158+ }
159+
150160// Group runs fn wrapped in the detected CI provider's log-group markers, named
151161// `name`, when the configured mode selects the given dimension; otherwise it
152162// simply calls fn. The group-end marker is always emitted (even when fn returns
0 commit comments