1
0
Fork 0
mirror of https://code.forgejo.org/forgejo/runner.git synced 2025-08-06 17:40:58 +00:00

feat: allow to spawn and run a local reusable workflow (#1423)

* feat: allow to spawn and run a local reusable workflow

This change contains the ability to parse/plan/run a local
reusable workflow.
There are still numerous things missing:

- inputs
- secrets
- outputs

* feat: add workflow_call inputs

* test: improve inputs test

* feat: add input defaults

* feat: allow expressions in inputs

* feat: use context specific expression evaluator

* refactor: prepare for better re-usability

* feat: add secrets for reusable workflows

* test: use secrets during test run

* feat: handle reusable workflow outputs

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
This commit is contained in:
Markus Wolf 2022-12-15 17:45:22 +01:00 committed by GitHub
parent 4f1ccbd47a
commit 67aa596008
10 changed files with 470 additions and 137 deletions

View file

@ -100,6 +100,44 @@ func (w *Workflow) WorkflowDispatchConfig() *WorkflowDispatch {
return &config
}
type WorkflowCallInput struct {
Description string `yaml:"description"`
Required bool `yaml:"required"`
Default string `yaml:"default"`
Type string `yaml:"type"`
}
type WorkflowCallOutput struct {
Description string `yaml:"description"`
Value string `yaml:"value"`
}
type WorkflowCall struct {
Inputs map[string]WorkflowCallInput `yaml:"inputs"`
Outputs map[string]WorkflowCallOutput `yaml:"outputs"`
}
func (w *Workflow) WorkflowCallConfig() *WorkflowCall {
if w.RawOn.Kind != yaml.MappingNode {
return nil
}
var val map[string]yaml.Node
err := w.RawOn.Decode(&val)
if err != nil {
log.Fatal(err)
}
var config WorkflowCall
node := val["workflow_call"]
err = node.Decode(&config)
if err != nil {
log.Fatal(err)
}
return &config
}
// Job is the structure of one job in a workflow
type Job struct {
Name string `yaml:"name"`
@ -115,6 +153,8 @@ type Job struct {
Defaults Defaults `yaml:"defaults"`
Outputs map[string]string `yaml:"outputs"`
Uses string `yaml:"uses"`
With map[string]interface{} `yaml:"with"`
RawSecrets yaml.Node `yaml:"secrets"`
Result string
}
@ -169,6 +209,34 @@ func (s Strategy) GetFailFast() bool {
return failFast
}
func (j *Job) InheritSecrets() bool {
if j.RawSecrets.Kind != yaml.ScalarNode {
return false
}
var val string
err := j.RawSecrets.Decode(&val)
if err != nil {
log.Fatal(err)
}
return val == "inherit"
}
func (j *Job) Secrets() map[string]string {
if j.RawSecrets.Kind != yaml.MappingNode {
return nil
}
var val map[string]string
err := j.RawSecrets.Decode(&val)
if err != nil {
log.Fatal(err)
}
return val
}
// Container details for the job
func (j *Job) Container() *ContainerSpec {
var val *ContainerSpec