feat: basic no-input node action support

This commit is contained in:
Marc 2024-09-02 11:13:59 -04:00
parent b197449f70
commit 42dfc12243
Signed by: marc
GPG key ID: 048E042F22B5DC79
3 changed files with 79 additions and 4 deletions

View file

@ -0,0 +1,37 @@
package actions
import (
"gopkg.in/yaml.v3"
"io/ioutil"
)
type ActionInput struct {
Description string `yaml:"description"`
Default string `yaml:"default"`
}
type ActionDefinition struct {
Name string `yaml:"name"`
Description string `yaml:"description"`
Inputs map[string]ActionInput `yaml:"inputs"`
Runs struct {
Using string `yaml:"using"`
Main string `yaml:"main"`
} `yaml:"runs"`
}
func GetDefinitionFromFile(defPath string) (*ActionDefinition, error) {
defRaw, err := ioutil.ReadFile(defPath)
if err != nil {
return nil, err
}
var def ActionDefinition
if yamlError := yaml.Unmarshal(defRaw, &def); yamlError != nil {
return nil, yamlError
}
return &def, nil
}

View file

@ -1,16 +1,23 @@
package actions package actions
import ( import (
driver "courgette/internal/driver"
logger "courgette/internal/logging" logger "courgette/internal/logging"
"errors"
"fmt"
"path/filepath"
) )
type ActionsManager struct { type ActionsManager struct {
git CliClient git CliClient
// Action cache location.
cacheRoot string
} }
func NewActionsManager() ActionsManager { func NewActionsManager(cacheRoot string) ActionsManager {
return ActionsManager{ return ActionsManager{
git: GitClient{}, git: GitClient{},
cacheRoot: cacheRoot,
} }
} }
@ -18,8 +25,32 @@ func NewActionsManager() ActionsManager {
// //
// <actionName> is expected to be the full url of the repository where // <actionName> is expected to be the full url of the repository where
// the action lives. // the action lives.
func (a ActionsManager) PrefetchAction(actionName string, destination string) error { func (a ActionsManager) PrefetchAction(actionName string) error {
destination := filepath.Join(a.cacheRoot, GetActionKey(actionName))
logger.Info("Prefetching action: %s to %s", actionName, destination) logger.Info("Prefetching action: %s to %s", actionName, destination)
return a.git.Clone(actionName, destination) return a.git.Clone(actionName, destination)
} }
func (a ActionsManager) UseAction(actionName string, containerId string, options driver.CommandOptions) error {
actionKey := GetActionKey(actionName)
hostActionRoot := filepath.Join(a.cacheRoot, actionKey)
actionDefPath := filepath.Join(hostActionRoot, "action.yml")
actionDef, _ := GetDefinitionFromFile(actionDefPath)
containerActionRoot := filepath.Join("/cache", actionKey)
actionMain := filepath.Join(containerActionRoot, actionDef.Runs.Main)
command := fmt.Sprintf("node %s", actionMain)
result := driver.PodmanDriver{}.Exec(containerId, command, options)
if result.Error != nil {
return result.Error
}
if result.ExitCode != 0 {
return errors.New("Action used returned non-zero exit code.")
}
return nil
}

View file

@ -49,7 +49,7 @@ func (r *Runner) RunWorkflow(workflow workflows.Workflow) TaskTracker {
switch n.(type) { switch n.(type) {
case workflows.Step: case workflows.Step:
if useAction := n.(workflows.Step).Use; useAction != "" { if useAction := n.(workflows.Step).Use; useAction != "" {
actions.NewActionsManager().PrefetchAction(useAction, r.Cache.Path(actions.GetActionKey(useAction))) actions.NewActionsManager(r.Cache.Root).PrefetchAction(useAction)
} }
} }
}) })
@ -164,6 +164,13 @@ func (r *Runner) RunJobInContainer(imageUri string, containerId string, jobConte
Shell: stepShell, Shell: stepShell,
} }
stepError = r.RunCommandInContainer(containerId, step.Run, commandOptions) stepError = r.RunCommandInContainer(containerId, step.Run, commandOptions)
} else if step.Use != "" {
commandOptions := driver.CommandOptions{
Cwd: stepCwd,
Env: stepEnv,
Shell: stepShell,
}
stepError = actions.NewActionsManager(r.Cache.Root).UseAction(step.Use, containerId, commandOptions)
} }
if stepError != nil && !step.ContinueOnError { if stepError != nil && !step.ContinueOnError {