feat: allow ctx overlay + case sensitive env ctx (#99)

* switch to fork of actionlint
This commit is contained in:
ChristopherHX
2025-05-18 11:35:05 +02:00
committed by GitHub
parent bb140f1a38
commit 1dc7a4d269
5 changed files with 99 additions and 37 deletions

View File

@@ -2,6 +2,7 @@ package exprparser
import (
"encoding"
"encoding/json"
"fmt"
"math"
"reflect"
@@ -25,8 +26,12 @@ type EvaluationEnvironment struct {
Needs map[string]Needs
Inputs map[string]interface{}
HashFiles func([]reflect.Value) (interface{}, error)
EnvCS bool
CtxData map[string]interface{}
}
type CaseSensitiveDict map[string]string
type Needs struct {
Outputs map[string]string `json:"outputs"`
Result string `json:"result"`
@@ -151,10 +156,17 @@ func (impl *interperterImpl) evaluateNode(exprNode actionlint.ExprNode) (interfa
}
func (impl *interperterImpl) evaluateVariable(variableNode *actionlint.VariableNode) (interface{}, error) {
switch strings.ToLower(variableNode.Name) {
lowerName := strings.ToLower(variableNode.Name)
if result, err := impl.evaluateOverriddenVariable(lowerName); result != nil || err != nil {
return result, err
}
switch lowerName {
case "github":
return impl.env.Github, nil
case "env":
if impl.env.EnvCS {
return CaseSensitiveDict(impl.env.Env), nil
}
return impl.env.Env, nil
case "job":
return impl.env.Job, nil
@@ -188,6 +200,33 @@ func (impl *interperterImpl) evaluateVariable(variableNode *actionlint.VariableN
}
}
func (impl *interperterImpl) evaluateOverriddenVariable(lowerName string) (interface{}, error) {
if cd, ok := impl.env.CtxData[lowerName]; ok {
if serverPayload, ok := cd.(map[string]interface{}); ok {
if lowerName == "github" {
var out map[string]interface{}
content, err := json.Marshal(impl.env.Github)
if err != nil {
return nil, err
}
err = json.Unmarshal(content, &out)
if err != nil {
return nil, err
}
for k, v := range serverPayload {
// skip empty values, because github.workspace was set by Gitea Actions to an empty string
if _, ok := out[k]; !ok || v != "" && v != nil {
out[k] = v
}
}
return out, nil
}
}
return cd, nil
}
return nil, nil
}
func (impl *interperterImpl) evaluateIndexAccess(indexAccessNode *actionlint.IndexAccessNode) (interface{}, error) {
left, err := impl.evaluateNode(indexAccessNode.Operand)
if err != nil {
@@ -280,6 +319,11 @@ func (impl *interperterImpl) getPropertyValue(left reflect.Value, property strin
return i, nil
case reflect.Map:
cd, ok := left.Interface().(CaseSensitiveDict)
if ok {
return cd[property], nil
}
iter := left.MapRange()
for iter.Next() {