@@ -246,7 +246,7 @@ var (
246
246
EventTypeRunFinish EventType = "runFinish"
247
247
)
248
248
249
- func getContextInput (prg * types.Program , ref types.ToolReference , input string ) (string , error ) {
249
+ func getToolRefInput (prg * types.Program , ref types.ToolReference , input string ) (string , error ) {
250
250
if ref .Arg == "" {
251
251
return "" , nil
252
252
}
@@ -351,7 +351,7 @@ func (r *Runner) getContext(callCtx engine.Context, state *State, monitor Monito
351
351
continue
352
352
}
353
353
354
- contextInput , err := getContextInput (callCtx .Program , toolRef , input )
354
+ contextInput , err := getToolRefInput (callCtx .Program , toolRef , input )
355
355
if err != nil {
356
356
return nil , nil , err
357
357
}
@@ -842,7 +842,7 @@ func (r *Runner) handleCredentials(callCtx engine.Context, monitor Monitor, env
842
842
}
843
843
844
844
var (
845
- cred * credentials.Credential
845
+ c * credentials.Credential
846
846
exists bool
847
847
)
848
848
@@ -854,25 +854,39 @@ func (r *Runner) handleCredentials(callCtx engine.Context, monitor Monitor, env
854
854
// Only try to look up the cred if the tool is on GitHub or has an alias.
855
855
// If it is a GitHub tool and has an alias, the alias overrides the tool name, so we use it as the credential name.
856
856
if isGitHubTool (toolName ) && credentialAlias == "" {
857
- cred , exists , err = r .credStore .Get (toolName )
857
+ c , exists , err = r .credStore .Get (toolName )
858
858
if err != nil {
859
859
return nil , fmt .Errorf ("failed to get credentials for tool %s: %w" , toolName , err )
860
860
}
861
861
} else if credentialAlias != "" {
862
- cred , exists , err = r .credStore .Get (credentialAlias )
862
+ c , exists , err = r .credStore .Get (credentialAlias )
863
863
if err != nil {
864
864
return nil , fmt .Errorf ("failed to get credentials for tool %s: %w" , credentialAlias , err )
865
865
}
866
866
}
867
867
868
+ if c == nil {
869
+ c = & credentials.Credential {}
870
+ }
871
+
868
872
// If the credential doesn't already exist in the store, run the credential tool in order to get the value,
869
873
// and save it in the store.
870
- if ! exists {
874
+ if ! exists || c . IsExpired () {
871
875
credToolRefs , ok := callCtx .Tool .ToolMapping [credToolName ]
872
876
if ! ok || len (credToolRefs ) != 1 {
873
877
return nil , fmt .Errorf ("failed to find ID for tool %s" , credToolName )
874
878
}
875
879
880
+ // If the existing credential is expired, we need to provide it to the cred tool through the environment.
881
+ if exists && c .IsExpired () {
882
+ credJson , err := json .Marshal (c )
883
+ if err != nil {
884
+ return nil , fmt .Errorf ("failed to marshal credential: %w" , err )
885
+ }
886
+ env = append (env , fmt .Sprintf ("%s=%s" , credentials .ExistingCredential , string (credJson )))
887
+ }
888
+
889
+ // Get the input for the credential tool, if there is any.
876
890
var input string
877
891
if args != nil {
878
892
inputBytes , err := json .Marshal (args )
@@ -882,6 +896,7 @@ func (r *Runner) handleCredentials(callCtx engine.Context, monitor Monitor, env
882
896
input = string (inputBytes )
883
897
}
884
898
899
+ // Prepare and execute the subcall.
885
900
subCtx , err := callCtx .SubCall (callCtx .Ctx , input , credToolRefs [0 ].ToolID , "" , engine .CredentialToolCategory ) // leaving callID as "" will cause it to be set by the engine
886
901
if err != nil {
887
902
return nil , fmt .Errorf ("failed to create subcall context for tool %s: %w" , credToolName , err )
@@ -896,21 +911,13 @@ func (r *Runner) handleCredentials(callCtx engine.Context, monitor Monitor, env
896
911
return nil , fmt .Errorf ("invalid state: credential tool [%s] can not result in a continuation" , credToolName )
897
912
}
898
913
899
- var envMap struct {
900
- Env map [string ]string `json:"env"`
901
- }
902
- if err := json .Unmarshal ([]byte (* res .Result ), & envMap ); err != nil {
914
+ if err := json .Unmarshal ([]byte (* res .Result ), & c ); err != nil {
903
915
return nil , fmt .Errorf ("failed to unmarshal credential tool %s response: %w" , credToolName , err )
904
916
}
905
-
906
- cred = & credentials.Credential {
907
- Type : credentials .CredentialTypeTool ,
908
- Env : envMap .Env ,
909
- ToolName : credName ,
910
- }
917
+ c .ToolName = credName
911
918
912
919
isEmpty := true
913
- for _ , v := range cred .Env {
920
+ for _ , v := range c .Env {
914
921
if v != "" {
915
922
isEmpty = false
916
923
break
@@ -921,15 +928,15 @@ func (r *Runner) handleCredentials(callCtx engine.Context, monitor Monitor, env
921
928
if (isGitHubTool (toolName ) && callCtx .Program .ToolSet [credToolRefs [0 ].ToolID ].Source .Repo != nil ) || credentialAlias != "" {
922
929
if isEmpty {
923
930
log .Warnf ("Not saving empty credential for tool %s" , toolName )
924
- } else if err := r .credStore .Add (* cred ); err != nil {
931
+ } else if err := r .credStore .Add (* c ); err != nil {
925
932
return nil , fmt .Errorf ("failed to add credential for tool %s: %w" , toolName , err )
926
933
}
927
934
} else {
928
935
log .Warnf ("Not saving credential for tool %s - credentials will only be saved for tools from GitHub, or tools that use aliases." , toolName )
929
936
}
930
937
}
931
938
932
- for k , v := range cred .Env {
939
+ for k , v := range c .Env {
933
940
env = append (env , fmt .Sprintf ("%s=%s" , k , v ))
934
941
}
935
942
}
0 commit comments