Repository: nektos/act (language: go)

Issue:
Expressions interpreter doesn't support short circuit for `&&` and `||`
https://github.com/nektos/act/blob/37152664940eea09a6775daf5eff8ee0d7f31442/pkg/exprparser/interpreter.go#L546-L558

```yaml
on: push
jobs:
  _:
    runs-on: ubuntu-latest
    if: always() && (contains(needs.*.result, 'cancelled') && fromjson('throw') || !cancelled())
    steps:
    - run: echo "Never reach here"
```

`fromjson('throw')` should be unreachable if no job has result `cancelled`, but it still get executed.

_I will pick this up at some point of time_


Discussion / hints:

Fix patch:
diff --git a/pkg/exprparser/interpreter.go b/pkg/exprparser/interpreter.go
index 8bf4e57fe76..feff80f8300 100644
--- a/pkg/exprparser/interpreter.go
+++ b/pkg/exprparser/interpreter.go
@@ -554,6 +554,10 @@ func (impl *interperterImpl) evaluateLogicalCompare(compareNode *actionlint.Logi
 
 	leftValue := reflect.ValueOf(left)
 
+	if IsTruthy(left) == (compareNode.Kind == actionlint.LogicalOpNodeKindOr) {
+		return impl.getSafeValue(leftValue), nil
+	}
+
 	right, err := impl.evaluateNode(compareNode.Right)
 	if err != nil {
 		return nil, err
@@ -563,17 +567,8 @@ func (impl *interperterImpl) evaluateLogicalCompare(compareNode *actionlint.Logi
 
 	switch compareNode.Kind {
 	case actionlint.LogicalOpNodeKindAnd:
-		if IsTruthy(left) {
-			return impl.getSafeValue(rightValue), nil
-		}
-
-		return impl.getSafeValue(leftValue), nil
-
+		return impl.getSafeValue(rightValue), nil
 	case actionlint.LogicalOpNodeKindOr:
-		if IsTruthy(left) {
-			return impl.getSafeValue(leftValue), nil
-		}
-
 		return impl.getSafeValue(rightValue), nil
 	}
 


Test patch: