1
0
Fork 0
mirror of https://code.forgejo.org/forgejo/runner.git synced 2025-09-05 18:40:59 +00:00

chore: modernize code (#857)

Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/857
Reviewed-by: earl-warren <earl-warren@noreply.code.forgejo.org>
Reviewed-by: Gusted <gusted@noreply.code.forgejo.org>
Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
Co-committed-by: Michael Kriese <michael.kriese@visualon.de>
This commit is contained in:
Michael Kriese 2025-08-15 04:54:13 +00:00 committed by Michael Kriese
parent 886bf2a4f3
commit 27f425987c
No known key found for this signature in database
GPG key ID: F128CBE6AB3A7201
49 changed files with 316 additions and 363 deletions

View file

@ -166,7 +166,7 @@ func (h *Handler) ExternalURL() string {
// The RunData contains the information about the repository. // The RunData contains the information about the repository.
// The function returns the 32-bit random key which the run will use to identify itself. // The function returns the 32-bit random key which the run will use to identify itself.
func (h *Handler) AddRun(data RunData) (string, error) { func (h *Handler) AddRun(data RunData) (string, error) {
for retries := 0; retries < 3; retries++ { for range 3 {
key := common.MustRandName(4) key := common.MustRandName(4)
_, loaded := h.runs.LoadOrStore(key, data) _, loaded := h.runs.LoadOrStore(key, data)
if !loaded { if !loaded {

View file

@ -1,9 +1,9 @@
package common package common
// CartesianProduct takes map of lists and returns list of unique tuples // CartesianProduct takes map of lists and returns list of unique tuples
func CartesianProduct(mapOfLists map[string][]interface{}) []map[string]interface{} { func CartesianProduct(mapOfLists map[string][]any) []map[string]any {
listNames := make([]string, 0) listNames := make([]string, 0)
lists := make([][]interface{}, 0) lists := make([][]any, 0)
for k, v := range mapOfLists { for k, v := range mapOfLists {
listNames = append(listNames, k) listNames = append(listNames, k)
lists = append(lists, v) lists = append(lists, v)
@ -11,9 +11,9 @@ func CartesianProduct(mapOfLists map[string][]interface{}) []map[string]interfac
listCart := cartN(lists...) listCart := cartN(lists...)
rtn := make([]map[string]interface{}, 0) rtn := make([]map[string]any, 0)
for _, list := range listCart { for _, list := range listCart {
vMap := make(map[string]interface{}) vMap := make(map[string]any)
for i, v := range list { for i, v := range list {
vMap[listNames[i]] = v vMap[listNames[i]] = v
} }
@ -22,7 +22,7 @@ func CartesianProduct(mapOfLists map[string][]interface{}) []map[string]interfac
return rtn return rtn
} }
func cartN(a ...[]interface{}) [][]interface{} { func cartN(a ...[]any) [][]any {
c := 1 c := 1
for _, a := range a { for _, a := range a {
c *= len(a) c *= len(a)
@ -30,8 +30,8 @@ func cartN(a ...[]interface{}) [][]interface{} {
if c == 0 || len(a) == 0 { if c == 0 || len(a) == 0 {
return nil return nil
} }
p := make([][]interface{}, c) p := make([][]any, c)
b := make([]interface{}, c*len(a)) b := make([]any, c*len(a))
n := make([]int, len(a)) n := make([]int, len(a))
s := 0 s := 0
for i := range p { for i := range p {

View file

@ -8,7 +8,7 @@ import (
func TestCartesianProduct(t *testing.T) { func TestCartesianProduct(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
input := map[string][]interface{}{ input := map[string][]any{
"foo": {1, 2, 3, 4}, "foo": {1, 2, 3, 4},
"bar": {"a", "b", "c"}, "bar": {"a", "b", "c"},
"baz": {false, true}, "baz": {false, true},
@ -25,7 +25,7 @@ func TestCartesianProduct(t *testing.T) {
assert.Contains(v, "baz") assert.Contains(v, "baz")
} }
input = map[string][]interface{}{ input = map[string][]any{
"foo": {1, 2, 3, 4}, "foo": {1, 2, 3, 4},
"bar": {}, "bar": {},
"baz": {false, true}, "baz": {false, true},
@ -33,7 +33,7 @@ func TestCartesianProduct(t *testing.T) {
output = CartesianProduct(input) output = CartesianProduct(input)
assert.Len(output, 0) assert.Len(output, 0)
input = map[string][]interface{}{} input = map[string][]any{}
output = CartesianProduct(input) output = CartesianProduct(input)
assert.Len(output, 0) assert.Len(output, 0)
} }

View file

@ -127,11 +127,8 @@ func (p *Pen) DrawBoxes(labels ...string) *Drawing {
// Draw to writer // Draw to writer
func (d *Drawing) Draw(writer io.Writer, centerOnWidth int) { func (d *Drawing) Draw(writer io.Writer, centerOnWidth int) {
padSize := (centerOnWidth - d.GetWidth()) / 2 padSize := max((centerOnWidth-d.GetWidth())/2, 0)
if padSize < 0 { for l := range strings.SplitSeq(d.buf.String(), "\n") {
padSize = 0
}
for _, l := range strings.Split(d.buf.String(), "\n") {
if len(l) > 0 { if len(l) > 0 {
padding := strings.Repeat(" ", padSize) padding := strings.Repeat(" ", padSize)
fmt.Fprintf(writer, "%s%s\n", padding, l) fmt.Fprintf(writer, "%s%s\n", padding, l)

View file

@ -18,7 +18,7 @@ func (w Warning) Error() string {
} }
// Warningf create a warning // Warningf create a warning
func Warningf(format string, args ...interface{}) Warning { func Warningf(format string, args ...any) Warning {
w := Warning{ w := Warning{
Message: fmt.Sprintf(format, args...), Message: fmt.Sprintf(format, args...),
} }
@ -32,7 +32,7 @@ type Executor func(ctx context.Context) error
type Conditional func(ctx context.Context) bool type Conditional func(ctx context.Context) bool
// NewInfoExecutor is an executor that logs messages // NewInfoExecutor is an executor that logs messages
func NewInfoExecutor(format string, args ...interface{}) Executor { func NewInfoExecutor(format string, args ...any) Executor {
return func(ctx context.Context) error { return func(ctx context.Context) error {
logger := Logger(ctx) logger := Logger(ctx)
logger.Infof(format, args...) logger.Infof(format, args...)
@ -41,7 +41,7 @@ func NewInfoExecutor(format string, args ...interface{}) Executor {
} }
// NewDebugExecutor is an executor that logs messages // NewDebugExecutor is an executor that logs messages
func NewDebugExecutor(format string, args ...interface{}) Executor { func NewDebugExecutor(format string, args ...any) Executor {
return func(ctx context.Context) error { return func(ctx context.Context) error {
logger := Logger(ctx) logger := Logger(ctx)
logger.Debugf(format, args...) logger.Debugf(format, args...)
@ -109,14 +109,14 @@ func NewParallelExecutor(parallel int, executors ...Executor) Executor {
}(work, errs) }(work, errs)
} }
for i := 0; i < len(executors); i++ { for i := range executors {
work <- executors[i] work <- executors[i]
} }
close(work) close(work)
// Executor waits all executors to cleanup these resources. // Executor waits all executors to cleanup these resources.
var firstErr error var firstErr error
for i := 0; i < len(executors); i++ { for range executors {
err := <-errs err := <-errs
if firstErr == nil { if firstErr == nil {
firstErr = err firstErr = err

View file

@ -166,8 +166,6 @@ func TestGitFindRef(t *testing.T) {
}, },
}, },
} { } {
tt := tt
name := name
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
dir := filepath.Join(basedir, name) dir := filepath.Join(basedir, name)
require.NoError(t, os.MkdirAll(dir, 0o755)) require.NoError(t, os.MkdirAll(dir, 0o755))

View file

@ -74,7 +74,7 @@ func logDockerResponse(logger logrus.FieldLogger, dockerResponse io.ReadCloser,
return nil return nil
} }
func writeLog(logger logrus.FieldLogger, isError bool, format string, args ...interface{}) { func writeLog(logger logrus.FieldLogger, isError bool, format string, args ...any) {
if isError { if isError {
logger.Errorf(format, args...) logger.Errorf(format, args...)
} else { } else {

View file

@ -12,7 +12,7 @@ type ExecutionsEnvironment interface {
GetPathVariableName() string GetPathVariableName() string
DefaultPathVariable() string DefaultPathVariable() string
JoinPathVariable(...string) string JoinPathVariable(...string) string
GetRunnerContext(ctx context.Context) map[string]interface{} GetRunnerContext(ctx context.Context) map[string]any
// On windows PATH and Path are the same key // On windows PATH and Path are the same key
IsEnvironmentCaseInsensitive() bool IsEnvironmentCaseInsensitive() bool
} }

View file

@ -485,8 +485,8 @@ func goOsToActionOs(os string) string {
return os return os
} }
func (e *HostEnvironment) GetRunnerContext(_ context.Context) map[string]interface{} { func (e *HostEnvironment) GetRunnerContext(_ context.Context) map[string]any {
return map[string]interface{}{ return map[string]any{
"os": goOsToActionOs(runtime.GOOS), "os": goOsToActionOs(runtime.GOOS),
"arch": goArchToActionArch(runtime.GOARCH), "arch": goArchToActionArch(runtime.GOARCH),
"temp": e.TmpDir, "temp": e.TmpDir,

View file

@ -76,8 +76,8 @@ func (*LinuxContainerEnvironmentExtensions) JoinPathVariable(paths ...string) st
return strings.Join(paths, ":") return strings.Join(paths, ":")
} }
func (l *LinuxContainerEnvironmentExtensions) GetRunnerContext(ctx context.Context) map[string]interface{} { func (l *LinuxContainerEnvironmentExtensions) GetRunnerContext(ctx context.Context) map[string]any {
return map[string]interface{}{ return map[string]any{
"os": "Linux", "os": "Linux",
"arch": RunnerArch(ctx), "arch": RunnerArch(ctx),
"temp": "/tmp", "temp": "/tmp",

View file

@ -165,12 +165,12 @@ func (impl *interperterImpl) toJSON(value reflect.Value) (string, error) {
return string(json), nil return string(json), nil
} }
func (impl *interperterImpl) fromJSON(value reflect.Value) (interface{}, error) { func (impl *interperterImpl) fromJSON(value reflect.Value) (any, error) {
if value.Kind() != reflect.String { if value.Kind() != reflect.String {
return nil, fmt.Errorf("Cannot parse non-string type %v as JSON", value.Kind()) return nil, fmt.Errorf("Cannot parse non-string type %v as JSON", value.Kind())
} }
var data interface{} var data any
err := json.Unmarshal([]byte(value.String()), &data) err := json.Unmarshal([]byte(value.String()), &data)
if err != nil { if err != nil {

View file

@ -11,7 +11,7 @@ import (
func TestFunctionContains(t *testing.T) { func TestFunctionContains(t *testing.T) {
table := []struct { table := []struct {
input string input string
expected interface{} expected any
name string name string
}{ }{
{"contains('search', 'item') }}", false, "contains-str-str"}, {"contains('search', 'item') }}", false, "contains-str-str"},
@ -58,7 +58,7 @@ func TestFunctionContains(t *testing.T) {
func TestFunctionStartsWith(t *testing.T) { func TestFunctionStartsWith(t *testing.T) {
table := []struct { table := []struct {
input string input string
expected interface{} expected any
name string name string
}{ }{
{"startsWith('search', 'se') }}", true, "startswith-string"}, {"startsWith('search', 'se') }}", true, "startswith-string"},
@ -90,7 +90,7 @@ func TestFunctionStartsWith(t *testing.T) {
func TestFunctionEndsWith(t *testing.T) { func TestFunctionEndsWith(t *testing.T) {
table := []struct { table := []struct {
input string input string
expected interface{} expected any
name string name string
}{ }{
{"endsWith('search', 'ch') }}", true, "endsWith-string"}, {"endsWith('search', 'ch') }}", true, "endsWith-string"},
@ -122,7 +122,7 @@ func TestFunctionEndsWith(t *testing.T) {
func TestFunctionJoin(t *testing.T) { func TestFunctionJoin(t *testing.T) {
table := []struct { table := []struct {
input string input string
expected interface{} expected any
name string name string
}{ }{
{"join(fromJSON('[\"a\", \"b\"]'), ',')", "a,b", "join-arr"}, {"join(fromJSON('[\"a\", \"b\"]'), ',')", "a,b", "join-arr"},
@ -152,7 +152,7 @@ func TestFunctionJoin(t *testing.T) {
func TestFunctionToJSON(t *testing.T) { func TestFunctionToJSON(t *testing.T) {
table := []struct { table := []struct {
input string input string
expected interface{} expected any
name string name string
}{ }{
{"toJSON(env) }}", "{\n \"key\": \"value\"\n}", "toJSON"}, {"toJSON(env) }}", "{\n \"key\": \"value\"\n}", "toJSON"},
@ -181,10 +181,10 @@ func TestFunctionToJSON(t *testing.T) {
func TestFunctionFromJSON(t *testing.T) { func TestFunctionFromJSON(t *testing.T) {
table := []struct { table := []struct {
input string input string
expected interface{} expected any
name string name string
}{ }{
{"fromJSON('{\"foo\":\"bar\"}') }}", map[string]interface{}{ {"fromJSON('{\"foo\":\"bar\"}') }}", map[string]any{
"foo": "bar", "foo": "bar",
}, "fromJSON"}, }, "fromJSON"},
} }
@ -207,7 +207,7 @@ func TestFunctionFromJSON(t *testing.T) {
func TestFunctionHashFiles(t *testing.T) { func TestFunctionHashFiles(t *testing.T) {
table := []struct { table := []struct {
input string input string
expected interface{} expected any
name string name string
}{ }{
{"hashFiles('**/non-extant-files') }}", "", "hash-non-existing-file"}, {"hashFiles('**/non-extant-files') }}", "", "hash-non-existing-file"},
@ -237,8 +237,8 @@ func TestFunctionHashFiles(t *testing.T) {
func TestFunctionFormat(t *testing.T) { func TestFunctionFormat(t *testing.T) {
table := []struct { table := []struct {
input string input string
expected interface{} expected any
error interface{} error any
name string name string
}{ }{
{"format('text')", "text", nil, "format-plain-string"}, {"format('text')", "text", nil, "format-plain-string"},

View file

@ -17,14 +17,14 @@ type EvaluationEnvironment struct {
Job *model.JobContext Job *model.JobContext
Jobs *map[string]*model.WorkflowCallResult Jobs *map[string]*model.WorkflowCallResult
Steps map[string]*model.StepResult Steps map[string]*model.StepResult
Runner map[string]interface{} Runner map[string]any
Secrets map[string]string Secrets map[string]string
Vars map[string]string Vars map[string]string
Strategy map[string]interface{} Strategy map[string]any
Matrix map[string]interface{} Matrix map[string]any
Needs map[string]Needs Needs map[string]Needs
Inputs map[string]interface{} Inputs map[string]any
HashFiles func([]reflect.Value) (interface{}, error) HashFiles func([]reflect.Value) (any, error)
} }
type Needs struct { type Needs struct {
@ -63,7 +63,7 @@ func (dsc DefaultStatusCheck) String() string {
} }
type Interpreter interface { type Interpreter interface {
Evaluate(input string, defaultStatusCheck DefaultStatusCheck) (interface{}, error) Evaluate(input string, defaultStatusCheck DefaultStatusCheck) (any, error)
} }
type interperterImpl struct { type interperterImpl struct {
@ -78,7 +78,7 @@ func NewInterpeter(env *EvaluationEnvironment, config Config) Interpreter {
} }
} }
func (impl *interperterImpl) Evaluate(input string, defaultStatusCheck DefaultStatusCheck) (interface{}, error) { func (impl *interperterImpl) Evaluate(input string, defaultStatusCheck DefaultStatusCheck) (any, error) {
input = strings.TrimPrefix(input, "${{") input = strings.TrimPrefix(input, "${{")
if defaultStatusCheck != DefaultStatusCheckNone && input == "" { if defaultStatusCheck != DefaultStatusCheckNone && input == "" {
input = "success()" input = "success()"
@ -117,7 +117,7 @@ func (impl *interperterImpl) Evaluate(input string, defaultStatusCheck DefaultSt
return result, err2 return result, err2
} }
func (impl *interperterImpl) evaluateNode(exprNode actionlint.ExprNode) (interface{}, error) { func (impl *interperterImpl) evaluateNode(exprNode actionlint.ExprNode) (any, error) {
switch node := exprNode.(type) { switch node := exprNode.(type) {
case *actionlint.VariableNode: case *actionlint.VariableNode:
return impl.evaluateVariable(node) return impl.evaluateVariable(node)
@ -150,7 +150,7 @@ func (impl *interperterImpl) evaluateNode(exprNode actionlint.ExprNode) (interfa
} }
} }
func (impl *interperterImpl) evaluateVariable(variableNode *actionlint.VariableNode) (interface{}, error) { func (impl *interperterImpl) evaluateVariable(variableNode *actionlint.VariableNode) (any, error) {
switch strings.ToLower(variableNode.Name) { switch strings.ToLower(variableNode.Name) {
case "github": case "github":
return impl.env.Github, nil return impl.env.Github, nil
@ -192,7 +192,7 @@ func (impl *interperterImpl) evaluateVariable(variableNode *actionlint.VariableN
} }
} }
func (impl *interperterImpl) evaluateIndexAccess(indexAccessNode *actionlint.IndexAccessNode) (interface{}, error) { func (impl *interperterImpl) evaluateIndexAccess(indexAccessNode *actionlint.IndexAccessNode) (any, error) {
left, err := impl.evaluateNode(indexAccessNode.Operand) left, err := impl.evaluateNode(indexAccessNode.Operand)
if err != nil { if err != nil {
return nil, err return nil, err
@ -240,7 +240,7 @@ func (impl *interperterImpl) evaluateObjectDeref(objectDerefNode *actionlint.Obj
return impl.getPropertyValue(reflect.ValueOf(left), objectDerefNode.Property) return impl.getPropertyValue(reflect.ValueOf(left), objectDerefNode.Property)
} }
func (impl *interperterImpl) evaluateArrayDeref(arrayDerefNode *actionlint.ArrayDerefNode) (interface{}, error) { func (impl *interperterImpl) evaluateArrayDeref(arrayDerefNode *actionlint.ArrayDerefNode) (any, error) {
left, err := impl.evaluateNode(arrayDerefNode.Receiver) left, err := impl.evaluateNode(arrayDerefNode.Receiver)
if err != nil { if err != nil {
return nil, err return nil, err
@ -249,7 +249,7 @@ func (impl *interperterImpl) evaluateArrayDeref(arrayDerefNode *actionlint.Array
return impl.getSafeValue(reflect.ValueOf(left)), nil return impl.getSafeValue(reflect.ValueOf(left)), nil
} }
func (impl *interperterImpl) getPropertyValue(left reflect.Value, property string) (value interface{}, err error) { func (impl *interperterImpl) getPropertyValue(left reflect.Value, property string) (value any, err error) {
switch left.Kind() { switch left.Kind() {
case reflect.Ptr: case reflect.Ptr:
return impl.getPropertyValue(left.Elem(), property) return impl.getPropertyValue(left.Elem(), property)
@ -303,7 +303,7 @@ func (impl *interperterImpl) getPropertyValue(left reflect.Value, property strin
return nil, nil return nil, nil
case reflect.Slice: case reflect.Slice:
var values []interface{} var values []any
for i := 0; i < left.Len(); i++ { for i := 0; i < left.Len(); i++ {
value, err := impl.getPropertyValue(left.Index(i).Elem(), property) value, err := impl.getPropertyValue(left.Index(i).Elem(), property)
@ -343,7 +343,7 @@ func (impl *interperterImpl) getPropertyValueDereferenced(left reflect.Value, pr
return nil, nil return nil, nil
} }
func (impl *interperterImpl) getMapValue(value reflect.Value) (interface{}, error) { func (impl *interperterImpl) getMapValue(value reflect.Value) (any, error) {
if value.Kind() == reflect.Ptr { if value.Kind() == reflect.Ptr {
return impl.getMapValue(value.Elem()) return impl.getMapValue(value.Elem())
} }
@ -351,7 +351,7 @@ func (impl *interperterImpl) getMapValue(value reflect.Value) (interface{}, erro
return value.Interface(), nil return value.Interface(), nil
} }
func (impl *interperterImpl) evaluateNot(notNode *actionlint.NotOpNode) (interface{}, error) { func (impl *interperterImpl) evaluateNot(notNode *actionlint.NotOpNode) (any, error) {
operand, err := impl.evaluateNode(notNode.Operand) operand, err := impl.evaluateNode(notNode.Operand)
if err != nil { if err != nil {
return nil, err return nil, err
@ -360,7 +360,7 @@ func (impl *interperterImpl) evaluateNot(notNode *actionlint.NotOpNode) (interfa
return !IsTruthy(operand), nil return !IsTruthy(operand), nil
} }
func (impl *interperterImpl) evaluateCompare(compareNode *actionlint.CompareOpNode) (interface{}, error) { func (impl *interperterImpl) evaluateCompare(compareNode *actionlint.CompareOpNode) (any, error) {
left, err := impl.evaluateNode(compareNode.Left) left, err := impl.evaluateNode(compareNode.Left)
if err != nil { if err != nil {
return nil, err return nil, err
@ -377,7 +377,7 @@ func (impl *interperterImpl) evaluateCompare(compareNode *actionlint.CompareOpNo
return impl.compareValues(leftValue, rightValue, compareNode.Kind) return impl.compareValues(leftValue, rightValue, compareNode.Kind)
} }
func (impl *interperterImpl) compareValues(leftValue, rightValue reflect.Value, kind actionlint.CompareOpNodeKind) (interface{}, error) { func (impl *interperterImpl) compareValues(leftValue, rightValue reflect.Value, kind actionlint.CompareOpNodeKind) (any, error) {
if leftValue.Kind() != rightValue.Kind() { if leftValue.Kind() != rightValue.Kind() {
if !impl.isNumber(leftValue) { if !impl.isNumber(leftValue) {
leftValue = impl.coerceToNumber(leftValue) leftValue = impl.coerceToNumber(leftValue)
@ -527,7 +527,7 @@ func (impl *interperterImpl) compareNumber(left, right float64, kind actionlint.
} }
} }
func IsTruthy(input interface{}) bool { func IsTruthy(input any) bool {
value := reflect.ValueOf(input) value := reflect.ValueOf(input)
switch value.Kind() { switch value.Kind() {
case reflect.Bool: case reflect.Bool:
@ -563,7 +563,7 @@ func (impl *interperterImpl) isNumber(value reflect.Value) bool {
} }
} }
func (impl *interperterImpl) getSafeValue(value reflect.Value) interface{} { func (impl *interperterImpl) getSafeValue(value reflect.Value) any {
switch value.Kind() { switch value.Kind() {
case reflect.Invalid: case reflect.Invalid:
return nil return nil
@ -577,7 +577,7 @@ func (impl *interperterImpl) getSafeValue(value reflect.Value) interface{} {
return value.Interface() return value.Interface()
} }
func (impl *interperterImpl) evaluateLogicalCompare(compareNode *actionlint.LogicalOpNode) (interface{}, error) { func (impl *interperterImpl) evaluateLogicalCompare(compareNode *actionlint.LogicalOpNode) (any, error) {
left, err := impl.evaluateNode(compareNode.Left) left, err := impl.evaluateNode(compareNode.Left)
if err != nil { if err != nil {
return nil, err return nil, err
@ -606,7 +606,7 @@ func (impl *interperterImpl) evaluateLogicalCompare(compareNode *actionlint.Logi
return nil, fmt.Errorf("Unable to compare incompatibles types '%s' and '%s'", leftValue.Kind(), rightValue.Kind()) return nil, fmt.Errorf("Unable to compare incompatibles types '%s' and '%s'", leftValue.Kind(), rightValue.Kind())
} }
func (impl *interperterImpl) evaluateFuncCall(funcCallNode *actionlint.FuncCallNode) (interface{}, error) { func (impl *interperterImpl) evaluateFuncCall(funcCallNode *actionlint.FuncCallNode) (any, error) {
args := make([]reflect.Value, 0) args := make([]reflect.Value, 0)
for _, arg := range funcCallNode.Args { for _, arg := range funcCallNode.Args {

View file

@ -11,7 +11,7 @@ import (
func TestLiterals(t *testing.T) { func TestLiterals(t *testing.T) {
table := []struct { table := []struct {
input string input string
expected interface{} expected any
name string name string
}{ }{
{"true", true, "true"}, {"true", true, "true"},
@ -40,7 +40,7 @@ func TestLiterals(t *testing.T) {
func TestOperators(t *testing.T) { func TestOperators(t *testing.T) {
table := []struct { table := []struct {
input string input string
expected interface{} expected any
name string name string
error string error string
}{ }{
@ -68,7 +68,7 @@ func TestOperators(t *testing.T) {
{`true && false`, false, "and", ""}, {`true && false`, false, "and", ""},
{`true || false`, true, "or", ""}, {`true || false`, true, "or", ""},
{`fromJSON('{}') && true`, true, "and-boolean-object", ""}, {`fromJSON('{}') && true`, true, "and-boolean-object", ""},
{`fromJSON('{}') || false`, make(map[string]interface{}), "or-boolean-object", ""}, {`fromJSON('{}') || false`, make(map[string]any), "or-boolean-object", ""},
{"github.event.commits[0].author.username != github.event.commits[1].author.username", true, "property-comparison1", ""}, {"github.event.commits[0].author.username != github.event.commits[1].author.username", true, "property-comparison1", ""},
{"github.event.commits[0].author.username1 != github.event.commits[1].author.username", true, "property-comparison2", ""}, {"github.event.commits[0].author.username1 != github.event.commits[1].author.username", true, "property-comparison2", ""},
{"github.event.commits[0].author.username != github.event.commits[1].author.username1", true, "property-comparison3", ""}, {"github.event.commits[0].author.username != github.event.commits[1].author.username1", true, "property-comparison3", ""},
@ -79,15 +79,15 @@ func TestOperators(t *testing.T) {
env := &EvaluationEnvironment{ env := &EvaluationEnvironment{
Github: &model.GithubContext{ Github: &model.GithubContext{
Action: "push", Action: "push",
Event: map[string]interface{}{ Event: map[string]any{
"commits": []interface{}{ "commits": []any{
map[string]interface{}{ map[string]any{
"author": map[string]interface{}{ "author": map[string]any{
"username": "someone", "username": "someone",
}, },
}, },
map[string]interface{}{ map[string]any{
"author": map[string]interface{}{ "author": map[string]any{
"username": "someone-else", "username": "someone-else",
}, },
}, },
@ -114,7 +114,7 @@ func TestOperators(t *testing.T) {
func TestOperatorsCompare(t *testing.T) { func TestOperatorsCompare(t *testing.T) {
table := []struct { table := []struct {
input string input string
expected interface{} expected any
name string name string
}{ }{
{"!null", true, "not-null"}, {"!null", true, "not-null"},
@ -162,7 +162,7 @@ func TestOperatorsCompare(t *testing.T) {
func TestOperatorsBooleanEvaluation(t *testing.T) { func TestOperatorsBooleanEvaluation(t *testing.T) {
table := []struct { table := []struct {
input string input string
expected interface{} expected any
name string name string
}{ }{
// true && // true &&
@ -529,7 +529,7 @@ func TestOperatorsBooleanEvaluation(t *testing.T) {
func TestContexts(t *testing.T) { func TestContexts(t *testing.T) {
table := []struct { table := []struct {
input string input string
expected interface{} expected any
name string name string
}{ }{
{"github.action", "push", "github-context"}, {"github.action", "push", "github-context"},
@ -588,7 +588,7 @@ func TestContexts(t *testing.T) {
Conclusion: model.StepStatusSkipped, Conclusion: model.StepStatusSkipped,
}, },
}, },
Runner: map[string]interface{}{ Runner: map[string]any{
"os": "Linux", "os": "Linux",
"temp": "/tmp", "temp": "/tmp",
"tool_cache": "/opt/hostedtoolcache", "tool_cache": "/opt/hostedtoolcache",
@ -599,10 +599,10 @@ func TestContexts(t *testing.T) {
Vars: map[string]string{ Vars: map[string]string{
"name": "value", "name": "value",
}, },
Strategy: map[string]interface{}{ Strategy: map[string]any{
"fail-fast": true, "fail-fast": true,
}, },
Matrix: map[string]interface{}{ Matrix: map[string]any{
"os": "Linux", "os": "Linux",
}, },
Needs: map[string]Needs{ Needs: map[string]Needs{
@ -619,7 +619,7 @@ func TestContexts(t *testing.T) {
Result: "success", Result: "success",
}, },
}, },
Inputs: map[string]interface{}{ Inputs: map[string]any{
"name": "value", "name": "value",
}, },
} }

View file

@ -26,7 +26,7 @@ func (mfs *memoryFs) walk(root string, fn filepath.WalkFunc) error {
if err != nil { if err != nil {
return err return err
} }
for i := 0; i < len(dir); i++ { for i := range dir {
filename := filepath.Join(root, dir[i].Name()) filename := filepath.Join(root, dir[i].Name())
err = fn(filename, dir[i], nil) err = fn(filename, dir[i], nil)
if dir[i].IsDir() { if dir[i].IsDir() {

View file

@ -19,7 +19,7 @@ func NewExpressionEvaluator(interpreter exprparser.Interpreter) *ExpressionEvalu
return &ExpressionEvaluator{interpreter: interpreter} return &ExpressionEvaluator{interpreter: interpreter}
} }
func (ee ExpressionEvaluator) evaluate(in string, defaultStatusCheck exprparser.DefaultStatusCheck) (interface{}, error) { func (ee ExpressionEvaluator) evaluate(in string, defaultStatusCheck exprparser.DefaultStatusCheck) (any, error) {
evaluated, err := ee.interpreter.Evaluate(in, defaultStatusCheck) evaluated, err := ee.interpreter.Evaluate(in, defaultStatusCheck)
return evaluated, err return evaluated, err

View file

@ -12,13 +12,13 @@ import (
func NewInterpeter( func NewInterpeter(
jobID string, jobID string,
job *model.Job, job *model.Job,
matrix map[string]interface{}, matrix map[string]any,
gitCtx *model.GithubContext, gitCtx *model.GithubContext,
results map[string]*JobResult, results map[string]*JobResult,
vars map[string]string, vars map[string]string,
inputs map[string]interface{}, inputs map[string]any,
) exprparser.Interpreter { ) exprparser.Interpreter {
strategy := make(map[string]interface{}) strategy := make(map[string]any)
if job.Strategy != nil { if job.Strategy != nil {
strategy["fail-fast"] = job.Strategy.FailFast strategy["fail-fast"] = job.Strategy.FailFast
strategy["max-parallel"] = job.Strategy.MaxParallel strategy["max-parallel"] = job.Strategy.MaxParallel

View file

@ -103,7 +103,7 @@ type parseContext struct {
type ParseOption func(c *parseContext) type ParseOption func(c *parseContext)
func getMatrixes(job *model.Job) ([]map[string]interface{}, error) { func getMatrixes(job *model.Job) ([]map[string]any, error) {
ret, err := job.GetMatrixes() ret, err := job.GetMatrixes()
if err != nil { if err != nil {
return nil, fmt.Errorf("GetMatrixes: %w", err) return nil, fmt.Errorf("GetMatrixes: %w", err)
@ -114,13 +114,13 @@ func getMatrixes(job *model.Job) ([]map[string]interface{}, error) {
return ret, nil return ret, nil
} }
func encodeMatrix(matrix map[string]interface{}) yaml.Node { func encodeMatrix(matrix map[string]any) yaml.Node {
if len(matrix) == 0 { if len(matrix) == 0 {
return yaml.Node{} return yaml.Node{}
} }
value := map[string][]interface{}{} value := map[string][]any{}
for k, v := range matrix { for k, v := range matrix {
value[k] = []interface{}{v} value[k] = []any{v}
} }
node := yaml.Node{} node := yaml.Node{}
_ = node.Encode(value) _ = node.Encode(value)
@ -137,7 +137,7 @@ func encodeRunsOn(runsOn []string) yaml.Node {
return node return node
} }
func nameWithMatrix(name string, m map[string]interface{}) string { func nameWithMatrix(name string, m map[string]any) string {
if len(m) == 0 { if len(m) == 0 {
return name return name
} }
@ -145,7 +145,7 @@ func nameWithMatrix(name string, m map[string]interface{}) string {
return name + " " + matrixName(m) return name + " " + matrixName(m)
} }
func matrixName(m map[string]interface{}) string { func matrixName(m map[string]any) string {
ks := make([]string, 0, len(m)) ks := make([]string, 0, len(m))
for k := range m { for k := range m {
ks = append(ks, k) ks = append(ks, k)

View file

@ -81,7 +81,7 @@ type Job struct {
Defaults Defaults `yaml:"defaults,omitempty"` Defaults Defaults `yaml:"defaults,omitempty"`
Outputs map[string]string `yaml:"outputs,omitempty"` Outputs map[string]string `yaml:"outputs,omitempty"`
Uses string `yaml:"uses,omitempty"` Uses string `yaml:"uses,omitempty"`
With map[string]interface{} `yaml:"with,omitempty"` With map[string]any `yaml:"with,omitempty"`
RawSecrets yaml.Node `yaml:"secrets,omitempty"` RawSecrets yaml.Node `yaml:"secrets,omitempty"`
RawConcurrency *model.RawConcurrency `yaml:"concurrency,omitempty"` RawConcurrency *model.RawConcurrency `yaml:"concurrency,omitempty"`
} }
@ -284,7 +284,7 @@ func ParseRawOn(rawOn *yaml.Node) ([]*Event, error) {
{Name: val}, {Name: val},
}, nil }, nil
case yaml.SequenceNode: case yaml.SequenceNode:
var val []interface{} var val []any
err := rawOn.Decode(&val) err := rawOn.Decode(&val)
if err != nil { if err != nil {
return nil, err return nil, err
@ -300,7 +300,7 @@ func ParseRawOn(rawOn *yaml.Node) ([]*Event, error) {
} }
return res, nil return res, nil
case yaml.MappingNode: case yaml.MappingNode:
events, triggers, err := parseMappingNode[interface{}](rawOn) events, triggers, err := parseMappingNode[any](rawOn)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -325,7 +325,7 @@ func ParseRawOn(rawOn *yaml.Node) ([]*Event, error) {
Name: k, Name: k,
acts: map[string][]string{}, acts: map[string][]string{},
}) })
case map[string]interface{}: case map[string]any:
acts := make(map[string][]string, len(t)) acts := make(map[string][]string, len(t))
for act, branches := range t { for act, branches := range t {
switch b := branches.(type) { switch b := branches.(type) {
@ -333,7 +333,7 @@ func ParseRawOn(rawOn *yaml.Node) ([]*Event, error) {
acts[act] = []string{b} acts[act] = []string{b}
case []string: case []string:
acts[act] = b acts[act] = b
case []interface{}: case []any:
acts[act] = make([]string, len(b)) acts[act] = make([]string, len(b))
for i, v := range b { for i, v := range b {
var ok bool var ok bool
@ -341,7 +341,7 @@ func ParseRawOn(rawOn *yaml.Node) ([]*Event, error) {
return nil, fmt.Errorf("unknown on type: %#v", branches) return nil, fmt.Errorf("unknown on type: %#v", branches)
} }
} }
case map[string]interface{}: case map[string]any:
if isInvalidOnType(k, act) { if isInvalidOnType(k, act) {
return nil, fmt.Errorf("unknown on type: %#v", v) return nil, fmt.Errorf("unknown on type: %#v", v)
} }
@ -356,13 +356,13 @@ func ParseRawOn(rawOn *yaml.Node) ([]*Event, error) {
Name: k, Name: k,
acts: acts, acts: acts,
}) })
case []interface{}: case []any:
if k != "schedule" { if k != "schedule" {
return nil, fmt.Errorf("unknown on type: %#v", v) return nil, fmt.Errorf("unknown on type: %#v", v)
} }
schedules := make([]map[string]string, len(t)) schedules := make([]map[string]string, len(t))
for i, tt := range t { for i, tt := range t {
vv, ok := tt.(map[string]interface{}) vv, ok := tt.(map[string]any)
if !ok { if !ok {
return nil, fmt.Errorf("unknown on type: %#v", v) return nil, fmt.Errorf("unknown on type: %#v", v)
} }
@ -431,7 +431,7 @@ func parseMappingNode[T any](node *yaml.Node) ([]string, []T, error) {
return scalars, datas, nil return scalars, datas, nil
} }
func asString(v interface{}) string { func asString(v any) string {
if v == nil { if v == nil {
return "" return ""
} else if s, ok := v.(string); ok { } else if s, ok := v.(string); ok {

View file

@ -261,66 +261,66 @@ func TestParseMappingNode(t *testing.T) {
tests := []struct { tests := []struct {
input string input string
scalars []string scalars []string
datas []interface{} datas []any
}{ }{
{ {
input: "on:\n push:\n branches:\n - master", input: "on:\n push:\n branches:\n - master",
scalars: []string{"push"}, scalars: []string{"push"},
datas: []interface{}{ datas: []any{
map[string]interface{}{ map[string]any{
"branches": []interface{}{"master"}, "branches": []any{"master"},
}, },
}, },
}, },
{ {
input: "on:\n branch_protection_rule:\n types: [created, deleted]", input: "on:\n branch_protection_rule:\n types: [created, deleted]",
scalars: []string{"branch_protection_rule"}, scalars: []string{"branch_protection_rule"},
datas: []interface{}{ datas: []any{
map[string]interface{}{ map[string]any{
"types": []interface{}{"created", "deleted"}, "types": []any{"created", "deleted"},
}, },
}, },
}, },
{ {
input: "on:\n project:\n types: [created, deleted]\n milestone:\n types: [opened, deleted]", input: "on:\n project:\n types: [created, deleted]\n milestone:\n types: [opened, deleted]",
scalars: []string{"project", "milestone"}, scalars: []string{"project", "milestone"},
datas: []interface{}{ datas: []any{
map[string]interface{}{ map[string]any{
"types": []interface{}{"created", "deleted"}, "types": []any{"created", "deleted"},
}, },
map[string]interface{}{ map[string]any{
"types": []interface{}{"opened", "deleted"}, "types": []any{"opened", "deleted"},
}, },
}, },
}, },
{ {
input: "on:\n pull_request:\n types:\n - opened\n branches:\n - 'releases/**'", input: "on:\n pull_request:\n types:\n - opened\n branches:\n - 'releases/**'",
scalars: []string{"pull_request"}, scalars: []string{"pull_request"},
datas: []interface{}{ datas: []any{
map[string]interface{}{ map[string]any{
"types": []interface{}{"opened"}, "types": []any{"opened"},
"branches": []interface{}{"releases/**"}, "branches": []any{"releases/**"},
}, },
}, },
}, },
{ {
input: "on:\n push:\n branches:\n - main\n pull_request:\n types:\n - opened\n branches:\n - '**'", input: "on:\n push:\n branches:\n - main\n pull_request:\n types:\n - opened\n branches:\n - '**'",
scalars: []string{"push", "pull_request"}, scalars: []string{"push", "pull_request"},
datas: []interface{}{ datas: []any{
map[string]interface{}{ map[string]any{
"branches": []interface{}{"main"}, "branches": []any{"main"},
}, },
map[string]interface{}{ map[string]any{
"types": []interface{}{"opened"}, "types": []any{"opened"},
"branches": []interface{}{"**"}, "branches": []any{"**"},
}, },
}, },
}, },
{ {
input: "on:\n schedule:\n - cron: '20 6 * * *'", input: "on:\n schedule:\n - cron: '20 6 * * *'",
scalars: []string{"schedule"}, scalars: []string{"schedule"},
datas: []interface{}{ datas: []any{
[]interface{}{map[string]interface{}{ []any{map[string]any{
"cron": "20 6 * * *", "cron": "20 6 * * *",
}}, }},
}, },
@ -332,7 +332,7 @@ func TestParseMappingNode(t *testing.T) {
workflow, err := model.ReadWorkflow(strings.NewReader(test.input), false) workflow, err := model.ReadWorkflow(strings.NewReader(test.input), false)
assert.NoError(t, err) assert.NoError(t, err)
scalars, datas, err := parseMappingNode[interface{}](&workflow.RawOn) scalars, datas, err := parseMappingNode[any](&workflow.RawOn)
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, test.scalars, scalars, fmt.Sprintf("%#v", scalars)) assert.EqualValues(t, test.scalars, scalars, fmt.Sprintf("%#v", scalars))
assert.EqualValues(t, test.datas, datas, fmt.Sprintf("%#v", datas)) assert.EqualValues(t, test.datas, datas, fmt.Sprintf("%#v", datas))
@ -423,15 +423,15 @@ func TestEvaluateConcurrency(t *testing.T) {
map[string]any{ map[string]any{
"workflow": "test_workflow", "workflow": "test_workflow",
"ref": "main", "ref": "main",
"event": map[string]interface{}{ "event": map[string]any{
"commits": []interface{}{ "commits": []any{
map[string]interface{}{ map[string]any{
"author": map[string]interface{}{ "author": map[string]any{
"username": "someone", "username": "someone",
}, },
}, },
map[string]interface{}{ map[string]any{
"author": map[string]interface{}{ "author": map[string]any{
"username": "someone-else", "username": "someone-else",
}, },
}, },

View file

@ -12,7 +12,7 @@ import (
// ActionRunsUsing is the type of runner for the action // ActionRunsUsing is the type of runner for the action
type ActionRunsUsing string type ActionRunsUsing string
func (a *ActionRunsUsing) UnmarshalYAML(unmarshal func(interface{}) error) error { func (a *ActionRunsUsing) UnmarshalYAML(unmarshal func(any) error) error {
var using string var using string
if err := unmarshal(&using); err != nil { if err := unmarshal(&using); err != nil {
return err return err

View file

@ -10,39 +10,39 @@ import (
) )
type GithubContext struct { type GithubContext struct {
Event map[string]interface{} `json:"event"` Event map[string]any `json:"event"`
EventPath string `json:"event_path"` EventPath string `json:"event_path"`
Workflow string `json:"workflow"` Workflow string `json:"workflow"`
RunAttempt string `json:"run_attempt"` RunAttempt string `json:"run_attempt"`
RunID string `json:"run_id"` RunID string `json:"run_id"`
RunNumber string `json:"run_number"` RunNumber string `json:"run_number"`
Actor string `json:"actor"` Actor string `json:"actor"`
Repository string `json:"repository"` Repository string `json:"repository"`
EventName string `json:"event_name"` EventName string `json:"event_name"`
Sha string `json:"sha"` Sha string `json:"sha"`
Ref string `json:"ref"` Ref string `json:"ref"`
RefName string `json:"ref_name"` RefName string `json:"ref_name"`
RefType string `json:"ref_type"` RefType string `json:"ref_type"`
HeadRef string `json:"head_ref"` HeadRef string `json:"head_ref"`
BaseRef string `json:"base_ref"` BaseRef string `json:"base_ref"`
Token string `json:"token"` Token string `json:"token"`
Workspace string `json:"workspace"` Workspace string `json:"workspace"`
Action string `json:"action"` Action string `json:"action"`
ActionPath string `json:"action_path"` ActionPath string `json:"action_path"`
ActionRef string `json:"action_ref"` ActionRef string `json:"action_ref"`
ActionRepository string `json:"action_repository"` ActionRepository string `json:"action_repository"`
Job string `json:"job"` Job string `json:"job"`
JobName string `json:"job_name"` JobName string `json:"job_name"`
RepositoryOwner string `json:"repository_owner"` RepositoryOwner string `json:"repository_owner"`
RetentionDays string `json:"retention_days"` RetentionDays string `json:"retention_days"`
RunnerPerflog string `json:"runner_perflog"` RunnerPerflog string `json:"runner_perflog"`
RunnerTrackingID string `json:"runner_tracking_id"` RunnerTrackingID string `json:"runner_tracking_id"`
ServerURL string `json:"server_url"` ServerURL string `json:"server_url"`
APIURL string `json:"api_url"` APIURL string `json:"api_url"`
GraphQLURL string `json:"graphql_url"` GraphQLURL string `json:"graphql_url"`
} }
func asString(v interface{}) string { func asString(v any) string {
if v == nil { if v == nil {
return "" return ""
} else if s, ok := v.(string); ok { } else if s, ok := v.(string); ok {
@ -51,7 +51,7 @@ func asString(v interface{}) string {
return "" return ""
} }
func nestedMapLookup(m map[string]interface{}, ks ...string) (rval interface{}) { func nestedMapLookup(m map[string]any, ks ...string) (rval any) {
var ok bool var ok bool
if len(ks) == 0 { // degenerate input if len(ks) == 0 { // degenerate input
@ -61,20 +61,20 @@ func nestedMapLookup(m map[string]interface{}, ks ...string) (rval interface{})
return nil return nil
} else if len(ks) == 1 { // we've reached the final key } else if len(ks) == 1 { // we've reached the final key
return rval return rval
} else if m, ok = rval.(map[string]interface{}); !ok { } else if m, ok = rval.(map[string]any); !ok {
return nil return nil
} }
// 1+ more keys // 1+ more keys
return nestedMapLookup(m, ks[1:]...) return nestedMapLookup(m, ks[1:]...)
} }
func withDefaultBranch(ctx context.Context, b string, event map[string]interface{}) map[string]interface{} { func withDefaultBranch(ctx context.Context, b string, event map[string]any) map[string]any {
repoI, ok := event["repository"] repoI, ok := event["repository"]
if !ok { if !ok {
repoI = make(map[string]interface{}) repoI = make(map[string]any)
} }
repo, ok := repoI.(map[string]interface{}) repo, ok := repoI.(map[string]any)
if !ok { if !ok {
common.Logger(ctx).Warnf("unable to set default branch to %v", b) common.Logger(ctx).Warnf("unable to set default branch to %v", b)
return event return event

View file

@ -27,19 +27,19 @@ func TestSetRef(t *testing.T) {
tables := []struct { tables := []struct {
eventName string eventName string
event map[string]interface{} event map[string]any
ref string ref string
refName string refName string
}{ }{
{ {
eventName: "pull_request_target", eventName: "pull_request_target",
event: map[string]interface{}{}, event: map[string]any{},
ref: "refs/heads/master", ref: "refs/heads/master",
refName: "master", refName: "master",
}, },
{ {
eventName: "pull_request", eventName: "pull_request",
event: map[string]interface{}{ event: map[string]any{
"number": 1234., "number": 1234.,
}, },
ref: "refs/pull/1234/merge", ref: "refs/pull/1234/merge",
@ -47,8 +47,8 @@ func TestSetRef(t *testing.T) {
}, },
{ {
eventName: "deployment", eventName: "deployment",
event: map[string]interface{}{ event: map[string]any{
"deployment": map[string]interface{}{ "deployment": map[string]any{
"ref": "refs/heads/somebranch", "ref": "refs/heads/somebranch",
}, },
}, },
@ -57,8 +57,8 @@ func TestSetRef(t *testing.T) {
}, },
{ {
eventName: "release", eventName: "release",
event: map[string]interface{}{ event: map[string]any{
"release": map[string]interface{}{ "release": map[string]any{
"tag_name": "v1.0.0", "tag_name": "v1.0.0",
}, },
}, },
@ -67,7 +67,7 @@ func TestSetRef(t *testing.T) {
}, },
{ {
eventName: "push", eventName: "push",
event: map[string]interface{}{ event: map[string]any{
"ref": "refs/heads/somebranch", "ref": "refs/heads/somebranch",
}, },
ref: "refs/heads/somebranch", ref: "refs/heads/somebranch",
@ -75,8 +75,8 @@ func TestSetRef(t *testing.T) {
}, },
{ {
eventName: "unknown", eventName: "unknown",
event: map[string]interface{}{ event: map[string]any{
"repository": map[string]interface{}{ "repository": map[string]any{
"default_branch": "main", "default_branch": "main",
}, },
}, },
@ -85,7 +85,7 @@ func TestSetRef(t *testing.T) {
}, },
{ {
eventName: "no-event", eventName: "no-event",
event: map[string]interface{}{}, event: map[string]any{},
ref: "refs/heads/master", ref: "refs/heads/master",
refName: "master", refName: "master",
}, },
@ -114,7 +114,7 @@ func TestSetRef(t *testing.T) {
ghc := &GithubContext{ ghc := &GithubContext{
EventName: "no-default-branch", EventName: "no-default-branch",
Event: map[string]interface{}{}, Event: map[string]any{},
} }
ghc.SetRef(t.Context(), "", "/some/dir") ghc.SetRef(t.Context(), "", "/some/dir")
@ -141,14 +141,14 @@ func TestSetSha(t *testing.T) {
tables := []struct { tables := []struct {
eventName string eventName string
event map[string]interface{} event map[string]any
sha string sha string
}{ }{
{ {
eventName: "pull_request_target", eventName: "pull_request_target",
event: map[string]interface{}{ event: map[string]any{
"pull_request": map[string]interface{}{ "pull_request": map[string]any{
"base": map[string]interface{}{ "base": map[string]any{
"sha": "pr-base-sha", "sha": "pr-base-sha",
}, },
}, },
@ -157,15 +157,15 @@ func TestSetSha(t *testing.T) {
}, },
{ {
eventName: "pull_request", eventName: "pull_request",
event: map[string]interface{}{ event: map[string]any{
"number": 1234., "number": 1234.,
}, },
sha: "1234fakesha", sha: "1234fakesha",
}, },
{ {
eventName: "deployment", eventName: "deployment",
event: map[string]interface{}{ event: map[string]any{
"deployment": map[string]interface{}{ "deployment": map[string]any{
"sha": "deployment-sha", "sha": "deployment-sha",
}, },
}, },
@ -173,12 +173,12 @@ func TestSetSha(t *testing.T) {
}, },
{ {
eventName: "release", eventName: "release",
event: map[string]interface{}{}, event: map[string]any{},
sha: "1234fakesha", sha: "1234fakesha",
}, },
{ {
eventName: "push", eventName: "push",
event: map[string]interface{}{ event: map[string]any{
"after": "push-sha", "after": "push-sha",
"deleted": false, "deleted": false,
}, },
@ -186,12 +186,12 @@ func TestSetSha(t *testing.T) {
}, },
{ {
eventName: "unknown", eventName: "unknown",
event: map[string]interface{}{}, event: map[string]any{},
sha: "1234fakesha", sha: "1234fakesha",
}, },
{ {
eventName: "no-event", eventName: "no-event",
event: map[string]interface{}{}, event: map[string]any{},
sha: "1234fakesha", sha: "1234fakesha",
}, },
} }

View file

@ -8,7 +8,7 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"regexp" "regexp"
"sort" "slices"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
) )
@ -286,11 +286,8 @@ func (wp *workflowPlanner) GetEvents() []string {
for _, w := range wp.workflows { for _, w := range wp.workflows {
found := false found := false
for _, e := range events { for _, e := range events {
for _, we := range w.On() { if slices.Contains(w.On(), e) {
if e == we { found = true
found = true
break
}
} }
if found { if found {
break break
@ -303,9 +300,7 @@ func (wp *workflowPlanner) GetEvents() []string {
} }
// sort the list based on depth of dependencies // sort the list based on depth of dependencies
sort.Slice(events, func(i, j int) bool { slices.Sort(events)
return events[i] < events[j]
})
return events return events
} }
@ -336,7 +331,7 @@ func (s *Stage) GetJobIDs() []string {
// Merge stages with existing stages in plan // Merge stages with existing stages in plan
func (p *Plan) mergeStages(stages []*Stage) { func (p *Plan) mergeStages(stages []*Stage) {
newStages := make([]*Stage, int(math.Max(float64(len(p.Stages)), float64(len(stages))))) newStages := make([]*Stage, int(math.Max(float64(len(p.Stages)), float64(len(stages)))))
for i := 0; i < len(newStages); i++ { for i := range newStages {
newStages[i] = new(Stage) newStages[i] = new(Stage)
if i >= len(p.Stages) { if i >= len(p.Stages) {
newStages[i].Runs = append(newStages[i].Runs, stages[i].Runs...) newStages[i].Runs = append(newStages[i].Runs, stages[i].Runs...)

View file

@ -4,9 +4,11 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"maps"
"path/filepath" "path/filepath"
"reflect" "reflect"
"regexp" "regexp"
"slices"
"strconv" "strconv"
"strings" "strings"
@ -47,7 +49,7 @@ func (w *Workflow) On() []string {
} }
return val return val
case yaml.MappingNode: case yaml.MappingNode:
var val map[string]interface{} var val map[string]any
err := w.RawOn.Decode(&val) err := w.RawOn.Decode(&val)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
@ -61,9 +63,9 @@ func (w *Workflow) On() []string {
return nil return nil
} }
func (w *Workflow) OnEvent(event string) interface{} { func (w *Workflow) OnEvent(event string) any {
if w.RawOn.Kind == yaml.MappingNode { if w.RawOn.Kind == yaml.MappingNode {
var val map[string]interface{} var val map[string]any
if !decodeNode(w.RawOn, &val) { if !decodeNode(w.RawOn, &val) {
return nil return nil
} }
@ -79,10 +81,10 @@ func (w *Workflow) OnSchedule() []string {
} }
switch val := schedules.(type) { switch val := schedules.(type) {
case []interface{}: case []any:
allSchedules := []string{} allSchedules := []string{}
for _, v := range val { for _, v := range val {
for k, cron := range v.(map[string]interface{}) { for k, cron := range v.(map[string]any) {
if k != "cron" { if k != "cron" {
continue continue
} }
@ -137,10 +139,8 @@ func (w *Workflow) WorkflowDispatchConfig() *WorkflowDispatch {
if !decodeNode(w.RawOn, &val) { if !decodeNode(w.RawOn, &val) {
return nil return nil
} }
for _, v := range val { if slices.Contains(val, "workflow_dispatch") {
if v == "workflow_dispatch" { return &WorkflowDispatch{}
return &WorkflowDispatch{}
}
} }
case yaml.MappingNode: case yaml.MappingNode:
var val map[string]yaml.Node var val map[string]yaml.Node
@ -215,7 +215,7 @@ type Job struct {
Defaults Defaults `yaml:"defaults"` Defaults Defaults `yaml:"defaults"`
Outputs map[string]string `yaml:"outputs"` Outputs map[string]string `yaml:"outputs"`
Uses string `yaml:"uses"` Uses string `yaml:"uses"`
With map[string]interface{} `yaml:"with"` With map[string]any `yaml:"with"`
RawSecrets yaml.Node `yaml:"secrets"` RawSecrets yaml.Node `yaml:"secrets"`
Result string Result string
} }
@ -393,9 +393,9 @@ func (j *Job) Environment() map[string]string {
} }
// Matrix decodes RawMatrix YAML node // Matrix decodes RawMatrix YAML node
func (j *Job) Matrix() map[string][]interface{} { func (j *Job) Matrix() map[string][]any {
if j.Strategy.RawMatrix.Kind == yaml.MappingNode { if j.Strategy.RawMatrix.Kind == yaml.MappingNode {
var val map[string][]interface{} var val map[string][]any
if !decodeNode(j.Strategy.RawMatrix, &val) { if !decodeNode(j.Strategy.RawMatrix, &val) {
return nil return nil
} }
@ -406,20 +406,20 @@ func (j *Job) Matrix() map[string][]interface{} {
// GetMatrixes returns the matrix cross product // GetMatrixes returns the matrix cross product
// It skips includes and hard fails excludes for non-existing keys // It skips includes and hard fails excludes for non-existing keys
func (j *Job) GetMatrixes() ([]map[string]interface{}, error) { func (j *Job) GetMatrixes() ([]map[string]any, error) {
matrixes := make([]map[string]interface{}, 0) matrixes := make([]map[string]any, 0)
if j.Strategy != nil { if j.Strategy != nil {
j.Strategy.FailFast = j.Strategy.GetFailFast() j.Strategy.FailFast = j.Strategy.GetFailFast()
j.Strategy.MaxParallel = j.Strategy.GetMaxParallel() j.Strategy.MaxParallel = j.Strategy.GetMaxParallel()
if m := j.Matrix(); m != nil { if m := j.Matrix(); m != nil {
includes := make([]map[string]interface{}, 0) includes := make([]map[string]any, 0)
extraIncludes := make([]map[string]interface{}, 0) extraIncludes := make([]map[string]any, 0)
for _, v := range m["include"] { for _, v := range m["include"] {
switch t := v.(type) { switch t := v.(type) {
case []interface{}: case []any:
for _, i := range t { for _, i := range t {
i := i.(map[string]interface{}) i := i.(map[string]any)
extraInclude := true extraInclude := true
for k := range i { for k := range i {
if _, ok := m[k]; ok { if _, ok := m[k]; ok {
@ -432,8 +432,8 @@ func (j *Job) GetMatrixes() ([]map[string]interface{}, error) {
extraIncludes = append(extraIncludes, i) extraIncludes = append(extraIncludes, i)
} }
} }
case interface{}: case any:
v := v.(map[string]interface{}) v := v.(map[string]any)
extraInclude := true extraInclude := true
for k := range v { for k := range v {
if _, ok := m[k]; ok { if _, ok := m[k]; ok {
@ -449,9 +449,9 @@ func (j *Job) GetMatrixes() ([]map[string]interface{}, error) {
} }
delete(m, "include") delete(m, "include")
excludes := make([]map[string]interface{}, 0) excludes := make([]map[string]any, 0)
for _, e := range m["exclude"] { for _, e := range m["exclude"] {
e := e.(map[string]interface{}) e := e.(map[string]any)
for k := range e { for k := range e {
if _, ok := m[k]; ok { if _, ok := m[k]; ok {
excludes = append(excludes, e) excludes = append(excludes, e)
@ -480,9 +480,7 @@ func (j *Job) GetMatrixes() ([]map[string]interface{}, error) {
if commonKeysMatch2(matrix, include, m) { if commonKeysMatch2(matrix, include, m) {
matched = true matched = true
log.Debugf("Adding include values '%v' to existing entry", include) log.Debugf("Adding include values '%v' to existing entry", include)
for k, v := range include { maps.Copy(matrix, include)
matrix[k] = v
}
} }
} }
if !matched { if !matched {
@ -494,19 +492,19 @@ func (j *Job) GetMatrixes() ([]map[string]interface{}, error) {
matrixes = append(matrixes, include) matrixes = append(matrixes, include)
} }
if len(matrixes) == 0 { if len(matrixes) == 0 {
matrixes = append(matrixes, make(map[string]interface{})) matrixes = append(matrixes, make(map[string]any))
} }
} else { } else {
matrixes = append(matrixes, make(map[string]interface{})) matrixes = append(matrixes, make(map[string]any))
} }
} else { } else {
matrixes = append(matrixes, make(map[string]interface{})) matrixes = append(matrixes, make(map[string]any))
log.Debugf("Empty Strategy, matrixes=%v", matrixes) log.Debugf("Empty Strategy, matrixes=%v", matrixes)
} }
return matrixes, nil return matrixes, nil
} }
func commonKeysMatch(a, b map[string]interface{}) bool { func commonKeysMatch(a, b map[string]any) bool {
for aKey, aVal := range a { for aKey, aVal := range a {
if bVal, ok := b[aKey]; ok && !reflect.DeepEqual(aVal, bVal) { if bVal, ok := b[aKey]; ok && !reflect.DeepEqual(aVal, bVal) {
return false return false
@ -515,7 +513,7 @@ func commonKeysMatch(a, b map[string]interface{}) bool {
return true return true
} }
func commonKeysMatch2(a, b map[string]interface{}, m map[string][]interface{}) bool { func commonKeysMatch2(a, b map[string]any, m map[string][]any) bool {
for aKey, aVal := range a { for aKey, aVal := range a {
_, useKey := m[aKey] _, useKey := m[aKey]
if bVal, ok := b[aKey]; useKey && ok && !reflect.DeepEqual(aVal, bVal) { if bVal, ok := b[aKey]; useKey && ok && !reflect.DeepEqual(aVal, bVal) {
@ -778,11 +776,11 @@ func (w *Workflow) GetJobIDs() []string {
return ids return ids
} }
var OnDecodeNodeError = func(node yaml.Node, out interface{}, err error) { var OnDecodeNodeError = func(node yaml.Node, out any, err error) {
log.Errorf("Failed to decode node %v into %T: %v", node, out, err) log.Errorf("Failed to decode node %v into %T: %v", node, out, err)
} }
func decodeNode(node yaml.Node, out interface{}) bool { func decodeNode(node yaml.Node, out any) bool {
if err := node.Decode(out); err != nil { if err := node.Decode(out); err != nil {
if OnDecodeNodeError != nil { if OnDecodeNodeError != nil {
OnDecodeNodeError(node, out, err) OnDecodeNodeError(node, out, err)
@ -825,7 +823,7 @@ func (r *RawConcurrency) UnmarshalYAML(n *yaml.Node) error {
return n.Decode((*objectConcurrency)(r)) return n.Decode((*objectConcurrency)(r))
} }
func (r *RawConcurrency) MarshalYAML() (interface{}, error) { func (r *RawConcurrency) MarshalYAML() (any, error) {
if r.RawExpression != "" { if r.RawExpression != "" {
return r.RawExpression, nil return r.RawExpression, nil
} }

View file

@ -493,24 +493,24 @@ func TestReadWorkflow_Strategy(t *testing.T) {
job := wf.Jobs["strategy-only-max-parallel"] job := wf.Jobs["strategy-only-max-parallel"]
matrixes, err := job.GetMatrixes() matrixes, err := job.GetMatrixes()
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, matrixes, []map[string]interface{}{{}}) assert.Equal(t, matrixes, []map[string]any{{}})
assert.Equal(t, job.Matrix(), map[string][]interface{}(nil)) assert.Equal(t, job.Matrix(), map[string][]any(nil))
assert.Equal(t, job.Strategy.MaxParallel, 2) assert.Equal(t, job.Strategy.MaxParallel, 2)
assert.Equal(t, job.Strategy.FailFast, true) assert.Equal(t, job.Strategy.FailFast, true)
job = wf.Jobs["strategy-only-fail-fast"] job = wf.Jobs["strategy-only-fail-fast"]
matrixes, err = job.GetMatrixes() matrixes, err = job.GetMatrixes()
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, matrixes, []map[string]interface{}{{}}) assert.Equal(t, matrixes, []map[string]any{{}})
assert.Equal(t, job.Matrix(), map[string][]interface{}(nil)) assert.Equal(t, job.Matrix(), map[string][]any(nil))
assert.Equal(t, job.Strategy.MaxParallel, 4) assert.Equal(t, job.Strategy.MaxParallel, 4)
assert.Equal(t, job.Strategy.FailFast, false) assert.Equal(t, job.Strategy.FailFast, false)
job = wf.Jobs["strategy-no-matrix"] job = wf.Jobs["strategy-no-matrix"]
matrixes, err = job.GetMatrixes() matrixes, err = job.GetMatrixes()
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, matrixes, []map[string]interface{}{{}}) assert.Equal(t, matrixes, []map[string]any{{}})
assert.Equal(t, job.Matrix(), map[string][]interface{}(nil)) assert.Equal(t, job.Matrix(), map[string][]any(nil))
assert.Equal(t, job.Strategy.MaxParallel, 2) assert.Equal(t, job.Strategy.MaxParallel, 2)
assert.Equal(t, job.Strategy.FailFast, false) assert.Equal(t, job.Strategy.FailFast, false)
@ -518,7 +518,7 @@ func TestReadWorkflow_Strategy(t *testing.T) {
matrixes, err = job.GetMatrixes() matrixes, err = job.GetMatrixes()
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, matrixes, assert.Equal(t, matrixes,
[]map[string]interface{}{ []map[string]any{
{"datacenter": "site-c", "node-version": "14.x", "site": "staging"}, {"datacenter": "site-c", "node-version": "14.x", "site": "staging"},
{"datacenter": "site-c", "node-version": "16.x", "site": "staging"}, {"datacenter": "site-c", "node-version": "16.x", "site": "staging"},
{"datacenter": "site-d", "node-version": "16.x", "site": "staging"}, {"datacenter": "site-d", "node-version": "16.x", "site": "staging"},
@ -528,15 +528,15 @@ func TestReadWorkflow_Strategy(t *testing.T) {
}, },
) )
assert.Equal(t, job.Matrix(), assert.Equal(t, job.Matrix(),
map[string][]interface{}{ map[string][]any{
"datacenter": {"site-c", "site-d"}, "datacenter": {"site-c", "site-d"},
"exclude": { "exclude": {
map[string]interface{}{"datacenter": "site-d", "node-version": "14.x", "site": "staging"}, map[string]any{"datacenter": "site-d", "node-version": "14.x", "site": "staging"},
}, },
"include": { "include": {
map[string]interface{}{"php-version": 5.4}, map[string]any{"php-version": 5.4},
map[string]interface{}{"datacenter": "site-a", "node-version": "10.x", "site": "prod"}, map[string]any{"datacenter": "site-a", "node-version": "10.x", "site": "prod"},
map[string]interface{}{"datacenter": "site-b", "node-version": "12.x", "site": "dev"}, map[string]any{"datacenter": "site-b", "node-version": "12.x", "site": "dev"},
}, },
"node-version": {"14.x", "16.x"}, "node-version": {"14.x", "16.x"},
"site": {"staging"}, "site": {"staging"},

View file

@ -286,8 +286,8 @@ func execAsDocker(ctx context.Context, step actionStep, actionName, basedir stri
var prepImage common.Executor var prepImage common.Executor
var image string var image string
forcePull := false forcePull := false
if strings.HasPrefix(action.Runs.Image, "docker://") { if after, ok := strings.CutPrefix(action.Runs.Image, "docker://"); ok {
image = strings.TrimPrefix(action.Runs.Image, "docker://") image = after
// Apply forcePull only for prebuild docker images // Apply forcePull only for prebuild docker images
forcePull = rc.Config.ForcePull forcePull = rc.Config.ForcePull
} else { } else {

View file

@ -139,8 +139,8 @@ func (rc *RunContext) addPath(ctx context.Context, arg string) {
func parseKeyValuePairs(kvPairs, separator string) map[string]string { func parseKeyValuePairs(kvPairs, separator string) map[string]string {
rtn := make(map[string]string) rtn := make(map[string]string)
kvPairList := strings.Split(kvPairs, separator) kvPairList := strings.SplitSeq(kvPairs, separator)
for _, kvPair := range kvPairList { for kvPair := range kvPairList {
kv := strings.Split(kvPair, "=") kv := strings.Split(kvPair, "=")
if len(kv) == 2 { if len(kv) == 2 {
rtn[kv[0]] = kv[1] rtn[kv[0]] = kv[1]

View file

@ -163,7 +163,7 @@ func TestCommandAddmaskUsemask(t *testing.T) {
re := captureOutput(t, func() { re := captureOutput(t, func() {
ctx := t.Context() ctx := t.Context()
ctx = WithJobLogger(ctx, "0", "testjob", config, &rc.Masks, map[string]interface{}{}) ctx = WithJobLogger(ctx, "0", "testjob", config, &rc.Masks, map[string]any{})
handler := rc.commandHandler(ctx) handler := rc.commandHandler(ctx)
handler("::add-mask::secret\n") handler("::add-mask::secret\n")

View file

@ -4,6 +4,7 @@ import (
"bytes" "bytes"
"context" "context"
"fmt" "fmt"
"maps"
"path" "path"
"reflect" "reflect"
"regexp" "regexp"
@ -21,7 +22,7 @@ import (
// ExpressionEvaluator is the interface for evaluating expressions // ExpressionEvaluator is the interface for evaluating expressions
type ExpressionEvaluator interface { type ExpressionEvaluator interface {
evaluate(context.Context, string, exprparser.DefaultStatusCheck) (interface{}, error) evaluate(context.Context, string, exprparser.DefaultStatusCheck) (any, error)
EvaluateYamlNode(context.Context, *yaml.Node) error EvaluateYamlNode(context.Context, *yaml.Node) error
Interpolate(context.Context, string) string Interpolate(context.Context, string) string
} }
@ -36,7 +37,7 @@ func (rc *RunContext) NewExpressionEvaluatorWithEnv(ctx context.Context, env map
// todo: cleanup EvaluationEnvironment creation // todo: cleanup EvaluationEnvironment creation
using := make(map[string]exprparser.Needs) using := make(map[string]exprparser.Needs)
strategy := make(map[string]interface{}) strategy := make(map[string]any)
if rc.Run != nil { if rc.Run != nil {
job := rc.Run.Job() job := rc.Run.Job()
if job != nil && job.Strategy != nil { if job != nil && job.Strategy != nil {
@ -64,9 +65,7 @@ func (rc *RunContext) NewExpressionEvaluatorWithEnv(ctx context.Context, env map
result := model.WorkflowCallResult{ result := model.WorkflowCallResult{
Outputs: map[string]string{}, Outputs: map[string]string{},
} }
for k, v := range job.Outputs { maps.Copy(result.Outputs, job.Outputs)
result.Outputs[k] = v
}
workflowCallResult[jobName] = &result workflowCallResult[jobName] = &result
} }
} }
@ -120,10 +119,10 @@ func (rc *RunContext) NewStepExpressionEvaluatorExt(ctx context.Context, step st
return rc.newStepExpressionEvaluator(ctx, step, ghc, getEvaluatorInputs(ctx, rc, step, ghc)) return rc.newStepExpressionEvaluator(ctx, step, ghc, getEvaluatorInputs(ctx, rc, step, ghc))
} }
func (rc *RunContext) newStepExpressionEvaluator(ctx context.Context, step step, ghc *model.GithubContext, inputs map[string]interface{}) ExpressionEvaluator { func (rc *RunContext) newStepExpressionEvaluator(ctx context.Context, step step, ghc *model.GithubContext, inputs map[string]any) ExpressionEvaluator {
// todo: cleanup EvaluationEnvironment creation // todo: cleanup EvaluationEnvironment creation
job := rc.Run.Job() job := rc.Run.Job()
strategy := make(map[string]interface{}) strategy := make(map[string]any)
if job.Strategy != nil { if job.Strategy != nil {
strategy["fail-fast"] = job.Strategy.FailFast strategy["fail-fast"] = job.Strategy.FailFast
strategy["max-parallel"] = job.Strategy.MaxParallel strategy["max-parallel"] = job.Strategy.MaxParallel
@ -167,8 +166,8 @@ func (rc *RunContext) newStepExpressionEvaluator(ctx context.Context, step step,
} }
} }
func getHashFilesFunction(ctx context.Context, rc *RunContext) func(v []reflect.Value) (interface{}, error) { func getHashFilesFunction(ctx context.Context, rc *RunContext) func(v []reflect.Value) (any, error) {
hashFiles := func(v []reflect.Value) (interface{}, error) { hashFiles := func(v []reflect.Value) (any, error) {
if rc.JobContainer != nil { if rc.JobContainer != nil {
timeed, cancel := context.WithTimeout(ctx, time.Minute) timeed, cancel := context.WithTimeout(ctx, time.Minute)
defer cancel() defer cancel()
@ -192,9 +191,7 @@ func getHashFilesFunction(ctx context.Context, rc *RunContext) func(v []reflect.
patterns = append(patterns, s) patterns = append(patterns, s)
} }
env := map[string]string{} env := map[string]string{}
for k, v := range rc.Env { maps.Copy(env, rc.Env)
env[k] = v
}
env["patterns"] = strings.Join(patterns, "\n") env["patterns"] = strings.Join(patterns, "\n")
if followSymlink { if followSymlink {
env["followSymbolicLinks"] = "true" env["followSymbolicLinks"] = "true"
@ -232,7 +229,7 @@ type expressionEvaluator struct {
interpreter exprparser.Interpreter interpreter exprparser.Interpreter
} }
func (ee expressionEvaluator) evaluate(ctx context.Context, in string, defaultStatusCheck exprparser.DefaultStatusCheck) (interface{}, error) { func (ee expressionEvaluator) evaluate(ctx context.Context, in string, defaultStatusCheck exprparser.DefaultStatusCheck) (any, error) {
logger := common.Logger(ctx) logger := common.Logger(ctx)
logger.Debugf("evaluating expression '%s'", in) logger.Debugf("evaluating expression '%s'", in)
evaluated, err := ee.interpreter.Evaluate(in, defaultStatusCheck) evaluated, err := ee.interpreter.Evaluate(in, defaultStatusCheck)
@ -479,8 +476,8 @@ func rewriteSubExpression(ctx context.Context, in string, forceFormat bool) (str
return out, nil return out, nil
} }
func getEvaluatorInputs(ctx context.Context, rc *RunContext, step step, ghc *model.GithubContext) map[string]interface{} { func getEvaluatorInputs(ctx context.Context, rc *RunContext, step step, ghc *model.GithubContext) map[string]any {
inputs := map[string]interface{}{} inputs := map[string]any{}
setupWorkflowInputs(ctx, &inputs, rc) setupWorkflowInputs(ctx, &inputs, rc)
@ -492,8 +489,8 @@ func getEvaluatorInputs(ctx context.Context, rc *RunContext, step step, ghc *mod
} }
for k, v := range env { for k, v := range env {
if strings.HasPrefix(k, "INPUT_") { if after, ok := strings.CutPrefix(k, "INPUT_"); ok {
inputs[strings.ToLower(strings.TrimPrefix(k, "INPUT_"))] = v inputs[strings.ToLower(after)] = v
} }
} }
@ -533,7 +530,7 @@ func getEvaluatorInputs(ctx context.Context, rc *RunContext, step step, ghc *mod
return inputs return inputs
} }
func setupWorkflowInputs(ctx context.Context, inputs *map[string]interface{}, rc *RunContext) { func setupWorkflowInputs(ctx context.Context, inputs *map[string]any, rc *RunContext) {
if rc.caller != nil { if rc.caller != nil {
config := rc.Run.Workflow.WorkflowCallConfig() config := rc.Run.Workflow.WorkflowCallConfig()

View file

@ -11,7 +11,7 @@ import (
func createRunContext(t *testing.T) *RunContext { func createRunContext(t *testing.T) *RunContext {
var yml yaml.Node var yml yaml.Node
err := yml.Encode(map[string][]interface{}{ err := yml.Encode(map[string][]any{
"os": {"Linux", "Windows"}, "os": {"Linux", "Windows"},
"foo": {"bar", "baz"}, "foo": {"bar", "baz"},
}) })
@ -43,7 +43,7 @@ func createRunContext(t *testing.T) *RunContext {
}, },
}, },
}, },
Matrix: map[string]interface{}{ Matrix: map[string]any{
"os": "Linux", "os": "Linux",
"foo": "bar", "foo": "bar",
}, },
@ -79,7 +79,7 @@ func TestExpressionEvaluateRunContext(t *testing.T) {
tables := []struct { tables := []struct {
in string in string
out interface{} out any
errMesg string errMesg string
}{ }{
{" 1 ", 1, ""}, {" 1 ", 1, ""},
@ -133,7 +133,6 @@ func TestExpressionEvaluateRunContext(t *testing.T) {
} }
for _, table := range tables { for _, table := range tables {
table := table
t.Run(table.in, func(t *testing.T) { t.Run(table.in, func(t *testing.T) {
assertObject := assert.New(t) assertObject := assert.New(t)
out, err := ee.evaluate(t.Context(), table.in, exprparser.DefaultStatusCheckNone) out, err := ee.evaluate(t.Context(), table.in, exprparser.DefaultStatusCheckNone)
@ -158,7 +157,7 @@ func TestExpressionEvaluateStep(t *testing.T) {
tables := []struct { tables := []struct {
in string in string
out interface{} out any
errMesg string errMesg string
}{ }{
{"steps.idwithnothing.conclusion", model.StepStatusSuccess.String(), ""}, {"steps.idwithnothing.conclusion", model.StepStatusSuccess.String(), ""},
@ -173,7 +172,6 @@ func TestExpressionEvaluateStep(t *testing.T) {
} }
for _, table := range tables { for _, table := range tables {
table := table
t.Run(table.in, func(t *testing.T) { t.Run(table.in, func(t *testing.T) {
assertObject := assert.New(t) assertObject := assert.New(t)
out, err := ee.evaluate(t.Context(), table.in, exprparser.DefaultStatusCheckNone) out, err := ee.evaluate(t.Context(), table.in, exprparser.DefaultStatusCheckNone)
@ -256,7 +254,6 @@ func TestExpressionInterpolate(t *testing.T) {
} }
for _, table := range tables { for _, table := range tables {
table := table
t.Run("interpolate", func(t *testing.T) { t.Run("interpolate", func(t *testing.T) {
assertObject := assert.New(t) assertObject := assert.New(t)
out := ee.Interpolate(t.Context(), table.in) out := ee.Interpolate(t.Context(), table.in)

View file

@ -11,7 +11,7 @@ import (
) )
type jobInfo interface { type jobInfo interface {
matrix() map[string]interface{} matrix() map[string]any
steps() []*model.Step steps() []*model.Step
startContainer() common.Executor startContainer() common.Executor
stopContainer() common.Executor stopContainer() common.Executor
@ -56,7 +56,6 @@ func newJobExecutor(info jobInfo, sf stepFactory, rc *RunContext) common.Executo
}) })
for i, stepModel := range infoSteps { for i, stepModel := range infoSteps {
stepModel := stepModel
if stepModel == nil { if stepModel == nil {
return func(ctx context.Context) error { return func(ctx context.Context) error {
return fmt.Errorf("invalid Step %v: missing run or uses key", i) return fmt.Errorf("invalid Step %v: missing run or uses key", i)

View file

@ -4,6 +4,7 @@ import (
"context" "context"
"fmt" "fmt"
"io" "io"
"slices"
"testing" "testing"
"code.forgejo.org/forgejo/runner/v9/act/common" "code.forgejo.org/forgejo/runner/v9/act/common"
@ -38,9 +39,9 @@ type jobInfoMock struct {
mock.Mock mock.Mock
} }
func (jim *jobInfoMock) matrix() map[string]interface{} { func (jim *jobInfoMock) matrix() map[string]any {
args := jim.Called() args := jim.Called()
return args.Get(0).(map[string]interface{}) return args.Get(0).(map[string]any)
} }
func (jim *jobInfoMock) steps() []*model.Step { func (jim *jobInfoMock) steps() []*model.Step {
@ -233,12 +234,7 @@ func TestJobExecutorNewJobExecutor(t *testing.T) {
} }
contains := func(needle string, haystack []string) bool { contains := func(needle string, haystack []string) bool {
for _, item := range haystack { return slices.Contains(haystack, needle)
if item == needle {
return true
}
}
return false
} }
for _, tt := range table { for _, tt := range table {
@ -273,9 +269,6 @@ func TestJobExecutorNewJobExecutor(t *testing.T) {
} }
for i, stepModel := range tt.steps { for i, stepModel := range tt.steps {
i := i
stepModel := stepModel
sm := &stepMock{} sm := &stepMock{}
sfm.On("newStep", stepModel, rc).Return(sm, nil) sfm.On("newStep", stepModel, rc).Return(sm, nil)
@ -306,7 +299,7 @@ func TestJobExecutorNewJobExecutor(t *testing.T) {
} }
if len(tt.steps) > 0 { if len(tt.steps) > 0 {
jim.On("matrix").Return(map[string]interface{}{}) jim.On("matrix").Return(map[string]any{})
jim.On("interpolateOutputs").Return(func(ctx context.Context) error { jim.On("interpolateOutputs").Return(func(ctx context.Context) error {
executorOrder = append(executorOrder, "interpolateOutputs") executorOrder = append(executorOrder, "interpolateOutputs")

View file

@ -73,7 +73,7 @@ func WithJobLoggerFactory(ctx context.Context, factory JobLoggerFactory) context
} }
// WithJobLogger attaches a new logger to context that is aware of steps // WithJobLogger attaches a new logger to context that is aware of steps
func WithJobLogger(ctx context.Context, jobID, jobName string, config *Config, masks *[]string, matrix map[string]interface{}) context.Context { func WithJobLogger(ctx context.Context, jobID, jobName string, config *Config, masks *[]string, matrix map[string]any) context.Context {
ctx = WithMasks(ctx, masks) ctx = WithMasks(ctx, masks)
var logger *logrus.Logger var logger *logrus.Logger

View file

@ -11,6 +11,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"maps"
"os" "os"
"path" "path"
"path/filepath" "path/filepath"
@ -33,7 +34,7 @@ import (
type RunContext struct { type RunContext struct {
Name string Name string
Config *Config Config *Config
Matrix map[string]interface{} Matrix map[string]any
Run *model.Run Run *model.Run
EventJSON string EventJSON string
Env map[string]string Env map[string]string
@ -645,9 +646,7 @@ func (rc *RunContext) sh(ctx context.Context, script string) (stdout, stderr str
herr := &bytes.Buffer{} herr := &bytes.Buffer{}
env := map[string]string{} env := map[string]string{}
for k, v := range rc.Env { maps.Copy(env, rc.Env)
env[k] = v
}
base := common.MustRandName(8) base := common.MustRandName(8)
name := base + ".sh" name := base + ".sh"
@ -912,7 +911,7 @@ func (rc *RunContext) closeContainer() common.Executor {
} }
} }
func (rc *RunContext) matrix() map[string]interface{} { func (rc *RunContext) matrix() map[string]any {
return rc.Matrix return rc.Matrix
} }
@ -1056,12 +1055,10 @@ func (rc *RunContext) isEnabled(ctx context.Context) (bool, error) {
return true, nil return true, nil
} }
func mergeMaps(maps ...map[string]string) map[string]string { func mergeMaps(args ...map[string]string) map[string]string {
rtnMap := make(map[string]string) rtnMap := make(map[string]string)
for _, m := range maps { for _, m := range args {
for k, v := range m { maps.Copy(rtnMap, m)
rtnMap[k] = v
}
} }
return rtnMap return rtnMap
} }
@ -1126,7 +1123,7 @@ func (rc *RunContext) getStepsContext() map[string]*model.StepResult {
func (rc *RunContext) getGithubContext(ctx context.Context) *model.GithubContext { func (rc *RunContext) getGithubContext(ctx context.Context) *model.GithubContext {
logger := common.Logger(ctx) logger := common.Logger(ctx)
ghc := &model.GithubContext{ ghc := &model.GithubContext{
Event: make(map[string]interface{}), Event: make(map[string]any),
Workflow: rc.Run.Workflow.Name, Workflow: rc.Run.Workflow.Name,
RunAttempt: rc.Config.Env["GITHUB_RUN_ATTEMPT"], RunAttempt: rc.Config.Env["GITHUB_RUN_ATTEMPT"],
RunID: rc.Config.Env["GITHUB_RUN_ID"], RunID: rc.Config.Env["GITHUB_RUN_ID"],
@ -1294,7 +1291,7 @@ func isLocalCheckout(ghc *model.GithubContext, step *model.Step) bool {
return true return true
} }
func nestedMapLookup(m map[string]interface{}, ks ...string) (rval interface{}) { func nestedMapLookup(m map[string]any, ks ...string) (rval any) {
var ok bool var ok bool
if len(ks) == 0 { // degenerate input if len(ks) == 0 { // degenerate input
@ -1304,7 +1301,7 @@ func nestedMapLookup(m map[string]interface{}, ks ...string) (rval interface{})
return nil return nil
} else if len(ks) == 1 { // we've reached the final key } else if len(ks) == 1 { // we've reached the final key
return rval return rval
} else if m, ok = rval.(map[string]interface{}); !ok { } else if m, ok = rval.(map[string]any); !ok {
return nil return nil
} }
// 1+ more keys // 1+ more keys

View file

@ -27,7 +27,7 @@ import (
func TestRunContext_EvalBool(t *testing.T) { func TestRunContext_EvalBool(t *testing.T) {
var yml yaml.Node var yml yaml.Node
err := yml.Encode(map[string][]interface{}{ err := yml.Encode(map[string][]any{
"os": {"Linux", "Windows"}, "os": {"Linux", "Windows"},
"foo": {"bar", "baz"}, "foo": {"bar", "baz"},
}) })
@ -55,7 +55,7 @@ func TestRunContext_EvalBool(t *testing.T) {
}, },
}, },
}, },
Matrix: map[string]interface{}{ Matrix: map[string]any{
"os": "Linux", "os": "Linux",
"foo": "bar", "foo": "bar",
}, },
@ -160,7 +160,6 @@ func TestRunContext_EvalBool(t *testing.T) {
} }
for _, table := range tables { for _, table := range tables {
table := table
t.Run(table.in, func(t *testing.T) { t.Run(table.in, func(t *testing.T) {
assertObject := assert.New(t) assertObject := assert.New(t)
b, err := EvalBool(t.Context(), rc.ExprEval, table.in, exprparser.DefaultStatusCheckSuccess) b, err := EvalBool(t.Context(), rc.ExprEval, table.in, exprparser.DefaultStatusCheckSuccess)
@ -203,11 +202,7 @@ func TestRunContext_GetBindsAndMounts(t *testing.T) {
isWindows := runtime.GOOS == "windows" isWindows := runtime.GOOS == "windows"
for _, testcase := range tests { for _, testcase := range tests {
// pin for scopelint
testcase := testcase
for _, bindWorkDir := range []bool{true, false} { for _, bindWorkDir := range []bool{true, false} {
// pin for scopelint
bindWorkDir := bindWorkDir
testBindSuffix := "" testBindSuffix := ""
if bindWorkDir { if bindWorkDir {
testBindSuffix = "Bind" testBindSuffix = "Bind"
@ -304,7 +299,7 @@ func TestRunContext_GetGitHubContext(t *testing.T) {
}, },
Name: "GitHubContextTest", Name: "GitHubContextTest",
CurrentStep: "step", CurrentStep: "step",
Matrix: map[string]interface{}{}, Matrix: map[string]any{},
Env: map[string]string{}, Env: map[string]string{},
ExtraPath: []string{}, ExtraPath: []string{},
StepResults: map[string]*model.StepResult{}, StepResults: map[string]*model.StepResult{},
@ -363,7 +358,6 @@ func TestRunContext_GetGithubContextRef(t *testing.T) {
} }
for _, data := range table { for _, data := range table {
data := data
t.Run(data.event, func(t *testing.T) { t.Run(data.event, func(t *testing.T) {
rc := &RunContext{ rc := &RunContext{
EventJSON: data.json, EventJSON: data.json,

View file

@ -178,7 +178,7 @@ func (runner *runnerImpl) NewPlanExecutor(plan *model.Plan) common.Executor {
} }
} }
var matrixes []map[string]interface{} var matrixes []map[string]any
if m, err := job.GetMatrixes(); err != nil { if m, err := job.GetMatrixes(); err != nil {
log.Errorf("Error while get job's matrix: %v", err) log.Errorf("Error while get job's matrix: %v", err)
} else { } else {
@ -198,7 +198,6 @@ func (runner *runnerImpl) NewPlanExecutor(plan *model.Plan) common.Executor {
} }
for i, matrix := range matrixes { for i, matrix := range matrixes {
matrix := matrix
rc := runner.newRunContext(ctx, run, matrix) rc := runner.newRunContext(ctx, run, matrix)
rc.JobName = rc.Name rc.JobName = rc.Name
if len(matrixes) > 1 { if len(matrixes) > 1 {
@ -219,10 +218,7 @@ func (runner *runnerImpl) NewPlanExecutor(plan *model.Plan) common.Executor {
} }
pipeline = append(pipeline, common.NewParallelExecutor(maxParallel, stageExecutor...)) pipeline = append(pipeline, common.NewParallelExecutor(maxParallel, stageExecutor...))
} }
ncpu := runtime.NumCPU() ncpu := max(1, runtime.NumCPU())
if 1 > ncpu {
ncpu = 1
}
log.Debugf("Detected CPUs: %d", ncpu) log.Debugf("Detected CPUs: %d", ncpu)
return common.NewParallelExecutor(ncpu, pipeline...)(ctx) return common.NewParallelExecutor(ncpu, pipeline...)(ctx)
}) })
@ -244,8 +240,8 @@ func handleFailure(plan *model.Plan) common.Executor {
} }
} }
func selectMatrixes(originalMatrixes []map[string]interface{}, targetMatrixValues map[string]map[string]bool) []map[string]interface{} { func selectMatrixes(originalMatrixes []map[string]any, targetMatrixValues map[string]map[string]bool) []map[string]any {
matrixes := make([]map[string]interface{}, 0) matrixes := make([]map[string]any, 0)
for _, original := range originalMatrixes { for _, original := range originalMatrixes {
flag := true flag := true
for key, val := range original { for key, val := range original {
@ -263,7 +259,7 @@ func selectMatrixes(originalMatrixes []map[string]interface{}, targetMatrixValue
return matrixes return matrixes
} }
func (runner *runnerImpl) newRunContext(ctx context.Context, run *model.Run, matrix map[string]interface{}) *RunContext { func (runner *runnerImpl) newRunContext(ctx context.Context, run *model.Run, matrix map[string]any) *RunContext {
rc := &RunContext{ rc := &RunContext{
Config: runner.config, Config: runner.config,
Run: run, Run: run,

View file

@ -6,6 +6,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"maps"
"path" "path"
"strconv" "strconv"
"strings" "strings"
@ -316,11 +317,9 @@ func mergeIntoMap(step step, target *map[string]string, maps ...map[string]strin
} }
} }
func mergeIntoMapCaseSensitive(target map[string]string, maps ...map[string]string) { func mergeIntoMapCaseSensitive(target map[string]string, args ...map[string]string) {
for _, m := range maps { for _, m := range args {
for k, v := range m { maps.Copy(target, m)
target[k] = v
}
} }
} }

View file

@ -46,7 +46,7 @@ func (sal *stepActionLocal) main() common.Executor {
_, cpath := getContainerActionPaths(sal.Step, path.Join(actionDir, ""), sal.RunContext) _, cpath := getContainerActionPaths(sal.Step, path.Join(actionDir, ""), sal.RunContext)
return func(filename string) (io.Reader, io.Closer, error) { return func(filename string) (io.Reader, io.Closer, error) {
spath := path.Join(cpath, filename) spath := path.Join(cpath, filename)
for i := 0; i < maxSymlinkDepth; i++ { for range maxSymlinkDepth {
tars, err := sal.RunContext.JobContainer.GetContainerArchive(ctx, spath) tars, err := sal.RunContext.JobContainer.GetContainerArchive(ctx, spath)
if errors.Is(err, fs.ErrNotExist) { if errors.Is(err, fs.ErrNotExist) {
return nil, nil, err return nil, nil, err

View file

@ -258,7 +258,7 @@ func TestStepActionLocalPost(t *testing.T) {
sal.RunContext.ExprEval = sal.RunContext.NewExpressionEvaluator(ctx) sal.RunContext.ExprEval = sal.RunContext.NewExpressionEvaluator(ctx)
if tt.mocks.exec { if tt.mocks.exec {
suffixMatcher := func(suffix string) interface{} { suffixMatcher := func(suffix string) any {
return mock.MatchedBy(func(array []string) bool { return mock.MatchedBy(func(array []string) bool {
return strings.HasSuffix(array[1], suffix) return strings.HasSuffix(array[1], suffix)
}) })

View file

@ -79,7 +79,7 @@ func (sar *stepActionRemote) prepareActionExecutor() common.Executor {
remoteReader := func(ctx context.Context) actionYamlReader { remoteReader := func(ctx context.Context) actionYamlReader {
return func(filename string) (io.Reader, io.Closer, error) { return func(filename string) (io.Reader, io.Closer, error) {
spath := path.Join(sar.remoteAction.Path, filename) spath := path.Join(sar.remoteAction.Path, filename)
for i := 0; i < maxSymlinkDepth; i++ { for range maxSymlinkDepth {
tars, err := cache.GetTarArchive(ctx, sar.cacheDir, sar.resolvedSha, spath) tars, err := cache.GetTarArchive(ctx, sar.cacheDir, sar.resolvedSha, spath)
if err != nil { if err != nil {
return nil, nil, os.ErrNotExist return nil, nil, os.ErrNotExist
@ -305,8 +305,8 @@ func (ra *remoteAction) IsCheckout() bool {
func newRemoteAction(action string) *remoteAction { func newRemoteAction(action string) *remoteAction {
// support http(s)://host/owner/repo@v3 // support http(s)://host/owner/repo@v3
for _, schema := range []string{"https://", "http://"} { for _, schema := range []string{"https://", "http://"} {
if strings.HasPrefix(action, schema) { if after, ok := strings.CutPrefix(action, schema); ok {
splits := strings.SplitN(strings.TrimPrefix(action, schema), "/", 2) splits := strings.SplitN(after, "/", 2)
if len(splits) != 2 { if len(splits) != 2 {
return nil return nil
} }

View file

@ -3,6 +3,7 @@ package runner
import ( import (
"context" "context"
"fmt" "fmt"
"maps"
"runtime" "runtime"
"strings" "strings"
@ -186,9 +187,7 @@ func (sr *stepRun) setupShell(ctx context.Context) {
} }
step.Shell = shellWithFallback[0] step.Shell = shellWithFallback[0]
lenv := &localEnv{env: map[string]string{}} lenv := &localEnv{env: map[string]string{}}
for k, v := range sr.env { maps.Copy(lenv.env, sr.env)
lenv.env[k] = v
}
sr.getRunContext().ApplyExtraPath(ctx, &lenv.env) sr.getRunContext().ApplyExtraPath(ctx, &lenv.env)
_, err := lookpath.LookPath2(shellWithFallback[0], lenv) _, err := lookpath.LookPath2(shellWithFallback[0], lenv)
if err != nil { if err != nil {

View file

@ -7,6 +7,7 @@ import (
"fmt" "fmt"
"math" "math"
"regexp" "regexp"
"slices"
"strconv" "strconv"
"strings" "strings"
@ -270,10 +271,8 @@ func (s *Node) UnmarshalYAML(node *yaml.Node) error {
return node.Decode(&b) return node.Decode(&b)
} else if def.AllowedValues != nil { } else if def.AllowedValues != nil {
s := node.Value s := node.Value
for _, v := range *def.AllowedValues { if slices.Contains(*def.AllowedValues, s) {
if s == v { return nil
return nil
}
} }
return fmt.Errorf("%sExpected one of %s got %s", formatLocation(node), strings.Join(*def.AllowedValues, ","), s) return fmt.Errorf("%sExpected one of %s got %s", formatLocation(node), strings.Join(*def.AllowedValues, ","), s)
} else if def.Null != nil { } else if def.Null != nil {

View file

@ -3,16 +3,16 @@ package workflowpattern
import "fmt" import "fmt"
type TraceWriter interface { type TraceWriter interface {
Info(string, ...interface{}) Info(string, ...any)
} }
type EmptyTraceWriter struct{} type EmptyTraceWriter struct{}
func (*EmptyTraceWriter) Info(string, ...interface{}) { func (*EmptyTraceWriter) Info(string, ...any) {
} }
type StdOutTraceWriter struct{} type StdOutTraceWriter struct{}
func (*StdOutTraceWriter) Info(format string, args ...interface{}) { func (*StdOutTraceWriter) Info(format string, args ...any) {
fmt.Printf(format+"\n", args...) fmt.Printf(format+"\n", args...)
} }

View file

@ -7,6 +7,7 @@ package cmd
import ( import (
"context" "context"
"fmt" "fmt"
"maps"
"os" "os"
"path/filepath" "path/filepath"
"strconv" "strconv"
@ -101,9 +102,7 @@ func readEnvs(path string, envs map[string]string) bool {
if err != nil { if err != nil {
log.Fatalf("Error loading from %s: %v", path, err) log.Fatalf("Error loading from %s: %v", path, err)
} }
for k, v := range env { maps.Copy(envs, env)
envs[k] = v
}
return true return true
} }
return false return false

View file

@ -9,6 +9,7 @@ import (
"encoding/hex" "encoding/hex"
"encoding/json" "encoding/json"
"fmt" "fmt"
"maps"
"path/filepath" "path/filepath"
"strconv" "strconv"
"strings" "strings"
@ -66,9 +67,7 @@ func NewRunner(cfg *config.Config, reg *config.Registration, cli client.Client)
cfg.Runner.Envs["GITHUB_SERVER_URL"] = reg.Address cfg.Runner.Envs["GITHUB_SERVER_URL"] = reg.Address
envs := make(map[string]string, len(cfg.Runner.Envs)) envs := make(map[string]string, len(cfg.Runner.Envs))
for k, v := range cfg.Runner.Envs { maps.Copy(envs, cfg.Runner.Envs)
envs[k] = v
}
var cacheProxy *cacheproxy.Handler var cacheProxy *cacheproxy.Handler
if cfg.Cache.Enabled == nil || *cfg.Cache.Enabled { if cfg.Cache.Enabled == nil || *cfg.Cache.Enabled {
@ -193,7 +192,7 @@ func explainFailedGenerateWorkflow(task *runnerv1.Task, log func(message string,
log("%5d: %s", n+1, line) log("%5d: %s", n+1, line)
} }
log("Errors were found and although they tend to be cryptic the line number they refer to gives a hint as to where the problem might be.") log("Errors were found and although they tend to be cryptic the line number they refer to gives a hint as to where the problem might be.")
for _, line := range strings.Split(err.Error(), "\n") { for line := range strings.SplitSeq(err.Error(), "\n") {
log("%s", line) log("%s", line)
} }
return fmt.Errorf("the workflow file is not usable") return fmt.Errorf("the workflow file is not usable")
@ -259,9 +258,7 @@ func (r *Runner) run(ctx context.Context, task *runnerv1.Task, reporter *report.
// Clone the runner default envs into a local envs map // Clone the runner default envs into a local envs map
runEnvs := make(map[string]string) runEnvs := make(map[string]string)
for id, v := range r.envs { maps.Copy(runEnvs, r.envs)
runEnvs[id] = v
}
runtimeToken := client.BackwardCompatibleContext(task, "runtime_token") runtimeToken := client.BackwardCompatibleContext(task, "runtime_token")
if runtimeToken == "" { if runtimeToken == "" {

View file

@ -5,6 +5,7 @@ package config
import ( import (
"fmt" "fmt"
"maps"
"os" "os"
"path/filepath" "path/filepath"
"time" "time"
@ -109,9 +110,7 @@ func LoadDefault(file string) (*Config, error) {
if cfg.Runner.Envs == nil { if cfg.Runner.Envs == nil {
cfg.Runner.Envs = map[string]string{} cfg.Runner.Envs = map[string]string{}
} }
for k, v := range envs { maps.Copy(cfg.Runner.Envs, envs)
cfg.Runner.Envs[k] = v
}
} }
} }

View file

@ -81,7 +81,7 @@ func NewReporter(ctx context.Context, cancel context.CancelFunc, c client.Client
func (r *Reporter) ResetSteps(l int) { func (r *Reporter) ResetSteps(l int) {
r.stateMu.Lock() r.stateMu.Lock()
defer r.stateMu.Unlock() defer r.stateMu.Unlock()
for i := 0; i < l; i++ { for i := range l {
r.state.Steps = append(r.state.Steps, &runnerv1.StepState{ r.state.Steps = append(r.state.Steps, &runnerv1.StepState{
Id: int64(i), Id: int64(i),
}) })
@ -189,14 +189,14 @@ func (r *Reporter) RunDaemon() {
time.AfterFunc(r.reportInterval, r.RunDaemon) time.AfterFunc(r.reportInterval, r.RunDaemon)
} }
func (r *Reporter) Logf(format string, a ...interface{}) { func (r *Reporter) Logf(format string, a ...any) {
r.stateMu.Lock() r.stateMu.Lock()
defer r.stateMu.Unlock() defer r.stateMu.Unlock()
r.logf(format, a...) r.logf(format, a...)
} }
func (r *Reporter) logf(format string, a ...interface{}) { func (r *Reporter) logf(format string, a ...any) {
if !r.duringSteps() { if !r.duringSteps() {
r.logRows = append(r.logRows, &runnerv1.LogRow{ r.logRows = append(r.logRows, &runnerv1.LogRow{
Time: timestamppb.Now(), Time: timestamppb.Now(),
@ -210,7 +210,7 @@ func (r *Reporter) SetOutputs(outputs map[string]string) error {
defer r.stateMu.Unlock() defer r.stateMu.Unlock()
var errs []error var errs []error
recordError := func(format string, a ...interface{}) { recordError := func(format string, a ...any) {
r.logf(format, a...) r.logf(format, a...)
errs = append(errs, fmt.Errorf(format, a...)) errs = append(errs, fmt.Errorf(format, a...))
} }
@ -341,7 +341,7 @@ func (r *Reporter) ReportState() error {
r.stateMu.RUnlock() r.stateMu.RUnlock()
outputs := make(map[string]string) outputs := make(map[string]string)
r.outputs.Range(func(k, v interface{}) bool { r.outputs.Range(func(k, v any) bool {
if val, ok := v.(string); ok { if val, ok := v.(string); ok {
outputs[k.(string)] = val outputs[k.(string)] = val
} }
@ -365,7 +365,7 @@ func (r *Reporter) ReportState() error {
} }
var noSent []string var noSent []string
r.outputs.Range(func(k, v interface{}) bool { r.outputs.Range(func(k, v any) bool {
if _, ok := v.(string); ok { if _, ok := v.(string); ok {
noSent = append(noSent, k.(string)) noSent = append(noSent, k.(string))
} }
@ -396,7 +396,7 @@ var stringToResult = map[string]runnerv1.Result{
"cancelled": runnerv1.Result_RESULT_CANCELLED, "cancelled": runnerv1.Result_RESULT_CANCELLED,
} }
func (r *Reporter) parseResult(result interface{}) (runnerv1.Result, bool) { func (r *Reporter) parseResult(result any) (runnerv1.Result, bool) {
str := "" str := ""
if v, ok := result.(string); ok { // for jobResult if v, ok := result.(string); ok { // for jobResult
str = v str = v

View file

@ -49,7 +49,7 @@ func mockReporter(t *testing.T) (*Reporter, *mocks.Client, func()) {
client := mocks.NewClient(t) client := mocks.NewClient(t)
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
taskCtx, err := structpb.NewStruct(map[string]interface{}{}) taskCtx, err := structpb.NewStruct(map[string]any{})
require.NoError(t, err) require.NoError(t, err)
reporter := NewReporter(ctx, cancel, client, &runnerv1.Task{ reporter := NewReporter(ctx, cancel, client, &runnerv1.Task{
Context: taskCtx, Context: taskCtx,
@ -64,7 +64,7 @@ func TestReporterSetOutputs(t *testing.T) {
assertEqual := func(t *testing.T, expected map[string]string, actual *sync.Map) { assertEqual := func(t *testing.T, expected map[string]string, actual *sync.Map) {
t.Helper() t.Helper()
actualMap := map[string]string{} actualMap := map[string]string{}
actual.Range(func(k, v interface{}) bool { actual.Range(func(k, v any) bool {
val, ok := v.(string) val, ok := v.(string)
require.True(t, ok) require.True(t, ok)
actualMap[k.(string)] = val actualMap[k.(string)] = val
@ -268,7 +268,7 @@ func TestReporter_Fire(t *testing.T) {
return connect_go.NewResponse(&runnerv1.UpdateTaskResponse{}), nil return connect_go.NewResponse(&runnerv1.UpdateTaskResponse{}), nil
}) })
dataStep0 := map[string]interface{}{ dataStep0 := map[string]any{
"stage": "Main", "stage": "Main",
"stepNumber": 0, "stepNumber": 0,
"raw_output": true, "raw_output": true,