@@ -482,22 +482,30 @@ func (woc *wfOperationCtx) operate(ctx context.Context) {
482482 }
483483}
484484
485+ // set Labels and Annotations for the Workflow
486+ // Also, since we're setting Labels and Annotations we need to find any
487+ // parameters formatted as "workflow.labels.<param>" or "workflow.annotations.<param>"
488+ // and perform substitution
485489func (woc * wfOperationCtx ) updateWorkflowMetadata () error {
490+ updatedParams := make (common.Parameters )
486491 if md := woc .execWf .Spec .WorkflowMetadata ; md != nil {
487- if woc .wf .ObjectMeta . Labels == nil {
488- woc .wf .ObjectMeta . Labels = make (map [string ]string )
492+ if woc .wf .Labels == nil {
493+ woc .wf .Labels = make (map [string ]string )
489494 }
490495 for n , v := range md .Labels {
491496 woc .wf .Labels [n ] = v
492497 woc .globalParams ["workflow.labels." + n ] = v
498+ updatedParams ["workflow.labels." + n ] = v
493499 }
494- if woc .wf .ObjectMeta . Annotations == nil {
495- woc .wf .ObjectMeta . Annotations = make (map [string ]string )
500+ if woc .wf .Annotations == nil {
501+ woc .wf .Annotations = make (map [string ]string )
496502 }
497503 for n , v := range md .Annotations {
498504 woc .wf .Annotations [n ] = v
499505 woc .globalParams ["workflow.annotations." + n ] = v
506+ updatedParams ["workflow.annotations." + n ] = v
500507 }
508+
501509 env := env .GetFuncMap (template .EnvMap (woc .globalParams ))
502510 for n , f := range md .LabelsFrom {
503511 r , err := expr .Eval (f .Expression , env )
@@ -510,8 +518,16 @@ func (woc *wfOperationCtx) updateWorkflowMetadata() error {
510518 }
511519 woc .wf .Labels [n ] = v
512520 woc .globalParams ["workflow.labels." + n ] = v
521+ updatedParams ["workflow.labels." + n ] = v
513522 }
514523 woc .updated = true
524+
525+ // Now we need to do any substitution that involves these labels
526+ err := woc .substituteGlobalVariables (updatedParams )
527+ if err != nil {
528+ return err
529+ }
530+
515531 }
516532 return nil
517533}
@@ -570,6 +586,23 @@ func (woc *wfOperationCtx) setGlobalParameters(executionParameters wfv1.Argument
570586 woc .globalParams ["workflow.parameters." + param .Name ] = param .Value .String ()
571587 }
572588 }
589+ if woc .wf .Status .Outputs != nil {
590+ for _ , param := range woc .wf .Status .Outputs .Parameters {
591+ if param .HasValue () {
592+ woc .globalParams ["workflow.outputs.parameters." + param .Name ] = param .GetValue ()
593+ }
594+ }
595+ }
596+
597+ /////////////////////////////////////////////////////////////////////////////////////////////////////////////
598+ // Set global parameters based on Labels and Annotations, both those that are defined in the execWf.ObjectMeta
599+ // and those that are defined in the execWf.Spec.WorkflowMetadata
600+ // Note: we no longer set globalParams based on LabelsFrom expressions here since they may themselves use parameters
601+ // and thus will need to be evaluated later based on the evaluation of those parameters
602+ /////////////////////////////////////////////////////////////////////////////////////////////////////////////
603+
604+ md := woc .execWf .Spec .WorkflowMetadata
605+
573606 if workflowAnnotations , err := json .Marshal (woc .wf .ObjectMeta .Annotations ); err == nil {
574607 woc .globalParams [common .GlobalVarWorkflowAnnotations ] = string (workflowAnnotations )
575608 }
@@ -580,15 +613,30 @@ func (woc *wfOperationCtx) setGlobalParameters(executionParameters wfv1.Argument
580613 woc .globalParams [common .GlobalVarWorkflowLabels ] = string (workflowLabels )
581614 }
582615 for k , v := range woc .wf .ObjectMeta .Labels {
583- woc .globalParams ["workflow.labels." + k ] = v
616+ // if the Label will get overridden by a LabelsFrom expression later, don't set it now
617+ if md != nil {
618+ _ , existsLabelsFrom := md .LabelsFrom [k ]
619+ if ! existsLabelsFrom {
620+ woc .globalParams ["workflow.labels." + k ] = v
621+ }
622+ } else {
623+ woc .globalParams ["workflow.labels." + k ] = v
624+ }
584625 }
585- if woc .wf .Status .Outputs != nil {
586- for _ , param := range woc .wf .Status .Outputs .Parameters {
587- if param .HasValue () {
588- woc .globalParams ["workflow.outputs.parameters." + param .Name ] = param .GetValue ()
626+
627+ if md != nil {
628+ for n , v := range md .Labels {
629+ // if the Label will get overridden by a LabelsFrom expression later, don't set it now
630+ _ , existsLabelsFrom := md .LabelsFrom [n ]
631+ if ! existsLabelsFrom {
632+ woc .globalParams ["workflow.labels." + n ] = v
589633 }
590634 }
635+ for n , v := range md .Annotations {
636+ woc .globalParams ["workflow.annotations." + n ] = v
637+ }
591638 }
639+
592640 return nil
593641}
594642
@@ -3532,16 +3580,17 @@ func (woc *wfOperationCtx) setExecWorkflow(ctx context.Context) error {
35323580 woc .markWorkflowFailed (ctx , fmt .Sprintf ("failed to set global parameters: %s" , err .Error ()))
35333581 return err
35343582 }
3583+
3584+ err = woc .substituteGlobalVariables (woc .globalParams )
3585+ if err != nil {
3586+ return err
3587+ }
35353588 if woc .wf .Status .Phase == wfv1 .WorkflowUnknown {
35363589 if err := woc .updateWorkflowMetadata (); err != nil {
35373590 woc .markWorkflowError (ctx , err )
35383591 return err
35393592 }
35403593 }
3541- err = woc .substituteGlobalVariables ()
3542- if err != nil {
3543- return err
3544- }
35453594
35463595 // runtime value will be set after the substitution, otherwise will not be reflected from stored wf spec
35473596 woc .setGlobalRuntimeParameters ()
@@ -3647,7 +3696,7 @@ func (woc *wfOperationCtx) mergedTemplateDefaultsInto(originalTmpl *wfv1.Templat
36473696 return nil
36483697}
36493698
3650- func (woc * wfOperationCtx ) substituteGlobalVariables () error {
3699+ func (woc * wfOperationCtx ) substituteGlobalVariables (params common. Parameters ) error {
36513700 execWfSpec := woc .execWf .Spec
36523701
36533702 // To Avoid the stale Global parameter value substitution to templates.
@@ -3659,7 +3708,7 @@ func (woc *wfOperationCtx) substituteGlobalVariables() error {
36593708 return err
36603709 }
36613710
3662- resolveSpec , err := template .Replace (string (wfSpec ), woc . globalParams , true )
3711+ resolveSpec , err := template .Replace (string (wfSpec ), params , true )
36633712 if err != nil {
36643713 return err
36653714 }
0 commit comments