55 "fmt"
66 "os"
77 "strconv"
8+ "strings"
89 "time"
910
1011 sdk "github.com/GoCodeAlone/workflow/plugin/external/sdk"
@@ -33,6 +34,7 @@ type actionStatusConfig struct {
3334 Owner string `yaml:"owner"`
3435 Repo string `yaml:"repo"`
3536 RunID int64 `yaml:"run_id"`
37+ RunIDRaw string // raw string value for dynamic {{.field}} resolution
3638 Token string `yaml:"token"`
3739 Wait bool `yaml:"wait"`
3840 PollInterval time.Duration `yaml:"poll_interval"`
@@ -70,6 +72,8 @@ func parseActionStatusConfig(raw map[string]any) (actionStatusConfig, error) {
7072 }
7173
7274 // run_id can be provided as int, int64, float64, or string.
75+ // When the string contains a template reference (e.g. {{.steps.trigger.run_id}})
76+ // the literal value is stored in RunIDRaw and resolved at Execute time.
7377 switch v := raw ["run_id" ].(type ) {
7478 case int :
7579 cfg .RunID = int64 (v )
@@ -79,14 +83,18 @@ func parseActionStatusConfig(raw map[string]any) (actionStatusConfig, error) {
7983 cfg .RunID = int64 (v )
8084 case string :
8185 if v != "" {
82- n , err := strconv .ParseInt (v , 10 , 64 )
83- if err != nil {
84- return cfg , fmt .Errorf ("config.run_id is not a valid integer: %w" , err )
86+ if strings .Contains (v , "{{" ) {
87+ cfg .RunIDRaw = v
88+ } else {
89+ n , err := strconv .ParseInt (v , 10 , 64 )
90+ if err != nil {
91+ return cfg , fmt .Errorf ("config.run_id is not a valid integer: %w" , err )
92+ }
93+ cfg .RunID = n
8594 }
86- cfg .RunID = n
8795 }
8896 }
89- if cfg .RunID == 0 {
97+ if cfg .RunID == 0 && cfg . RunIDRaw == "" {
9098 return cfg , fmt .Errorf ("config.run_id is required" )
9199 }
92100
@@ -118,27 +126,47 @@ func parseActionStatusConfig(raw map[string]any) (actionStatusConfig, error) {
118126}
119127
120128// Execute checks the status of the configured workflow run.
129+ // triggerData, stepOutputs, and current are used to resolve dynamic field
130+ // references (e.g. {{.steps.trigger.run_id}}) in owner, repo, and run_id.
121131// When wait=true it polls until the run completes or the timeout elapses.
122132func (s * actionStatusStep ) Execute (
123133 ctx context.Context ,
124- _ map [string ]any ,
125- _ map [string ]map [string ]any ,
126- _ map [string ]any ,
134+ triggerData map [string ]any ,
135+ stepOutputs map [string ]map [string ]any ,
136+ current map [string ]any ,
127137 _ map [string ]any ,
128138) (* sdk.StepResult , error ) {
129139 token := s .config .Token
130140 if token == "" {
131141 return errorResult ("GITHUB_TOKEN is not configured" ), nil
132142 }
133143
144+ // Resolve dynamic owner / repo.
145+ owner := resolveField (s .config .Owner , triggerData , stepOutputs , current )
146+ repo := resolveField (s .config .Repo , triggerData , stepOutputs , current )
147+
148+ // Resolve run_id — may be a static int or a dynamic template reference.
149+ runID := s .config .RunID
150+ if s .config .RunIDRaw != "" {
151+ resolved := resolveField (s .config .RunIDRaw , triggerData , stepOutputs , current )
152+ n , err := strconv .ParseInt (resolved , 10 , 64 )
153+ if err != nil {
154+ return errorResult (fmt .Sprintf ("run_id resolved to non-integer value %q: %v" , resolved , err )), nil
155+ }
156+ runID = n
157+ }
158+ if runID == 0 {
159+ return errorResult ("run_id resolved to zero — check pipeline context" ), nil
160+ }
161+
134162 if ! s .config .Wait {
135- return s .fetchStatus (ctx , token )
163+ return s .fetchStatusDynamic (ctx , owner , repo , runID , token )
136164 }
137165
138166 // Poll with timeout.
139167 deadline := time .Now ().Add (s .config .Timeout )
140168 for {
141- result , err := s .fetchStatus (ctx , token )
169+ result , err := s .fetchStatusDynamic (ctx , owner , repo , runID , token )
142170 if err != nil {
143171 return nil , err
144172 }
@@ -149,7 +177,7 @@ func (s *actionStatusStep) Execute(
149177 }
150178
151179 if time .Now ().After (deadline ) {
152- return errorResult (fmt .Sprintf ("timeout waiting for workflow run %d after %s" , s . config . RunID , s .config .Timeout )), nil
180+ return errorResult (fmt .Sprintf ("timeout waiting for workflow run %d after %s" , runID , s .config .Timeout )), nil
153181 }
154182
155183 select {
@@ -160,9 +188,10 @@ func (s *actionStatusStep) Execute(
160188 }
161189}
162190
163- // fetchStatus retrieves the current state of the workflow run from the GitHub API.
164- func (s * actionStatusStep ) fetchStatus (ctx context.Context , token string ) (* sdk.StepResult , error ) {
165- run , err := s .ghClient .GetWorkflowRun (ctx , s .config .Owner , s .config .Repo , s .config .RunID , token )
191+ // fetchStatusDynamic retrieves the current state of a workflow run from the
192+ // GitHub API using caller-supplied (already-resolved) owner, repo, and runID.
193+ func (s * actionStatusStep ) fetchStatusDynamic (ctx context.Context , owner , repo string , runID int64 , token string ) (* sdk.StepResult , error ) {
194+ run , err := s .ghClient .GetWorkflowRun (ctx , owner , repo , runID , token )
166195 if err != nil {
167196 return errorResult (fmt .Sprintf ("failed to get workflow run: %v" , err )), nil
168197 }
0 commit comments