From 77ddc89444d8cca5be47a3c83074dcb992382e68 Mon Sep 17 00:00:00 2001
From: ChristopherHX <christopher.homberger@web.de>
Date: Tue, 26 Apr 2022 22:24:13 +0200
Subject: [PATCH] fix: conclusion and outcome are no integers (#1136)

* fix: conclusion and outcome are no integers

* Change Test

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
---
 pkg/exprparser/interpreter.go      | 12 +++++++++++-
 pkg/exprparser/interpreter_test.go | 20 ++++++++++++++++++++
 pkg/runner/expression_test.go      | 12 ++++++------
 3 files changed, 37 insertions(+), 7 deletions(-)

diff --git a/pkg/exprparser/interpreter.go b/pkg/exprparser/interpreter.go
index 6287e70..a9f8faf 100644
--- a/pkg/exprparser/interpreter.go
+++ b/pkg/exprparser/interpreter.go
@@ -1,6 +1,7 @@
 package exprparser
 
 import (
+	"encoding"
 	"fmt"
 	"math"
 	"reflect"
@@ -224,7 +225,16 @@ func (impl *interperterImpl) getPropertyValue(left reflect.Value, property strin
 			return "", nil
 		}
 
-		return fieldValue.Interface(), nil
+		i := fieldValue.Interface()
+		// The type stepStatus int is an integer, but should be treated as string
+		if m, ok := i.(encoding.TextMarshaler); ok {
+			text, err := m.MarshalText()
+			if err != nil {
+				return nil, err
+			}
+			return string(text), nil
+		}
+		return i, nil
 
 	case reflect.Map:
 		iter := left.MapRange()
diff --git a/pkg/exprparser/interpreter_test.go b/pkg/exprparser/interpreter_test.go
index c6b15c3..4eae253 100644
--- a/pkg/exprparser/interpreter_test.go
+++ b/pkg/exprparser/interpreter_test.go
@@ -534,6 +534,22 @@ func TestContexts(t *testing.T) {
 		{"env.TEST", "value", "env-context"},
 		{"job.status", "success", "job-context"},
 		{"steps.step-id.outputs.name", "value", "steps-context"},
+		{"steps.step-id.conclusion", "success", "steps-context-conclusion"},
+		{"steps.step-id.conclusion && true", true, "steps-context-conclusion"},
+		{"steps.step-id2.conclusion", "skipped", "steps-context-conclusion"},
+		{"steps.step-id2.conclusion && true", true, "steps-context-conclusion"},
+		{"steps.step-id.outcome", "success", "steps-context-outcome"},
+		{"steps.step-id['outcome']", "success", "steps-context-outcome"},
+		{"steps.step-id.outcome == 'success'", true, "steps-context-outcome"},
+		{"steps.step-id['outcome'] == 'success'", true, "steps-context-outcome"},
+		{"steps.step-id.outcome && true", true, "steps-context-outcome"},
+		{"steps['step-id']['outcome'] && true", true, "steps-context-outcome"},
+		{"steps.step-id2.outcome", "failure", "steps-context-outcome"},
+		{"steps.step-id2.outcome && true", true, "steps-context-outcome"},
+		// Disabled, since the interpreter is still too broken
+		// {"contains(steps.*.outcome, 'success')", true, "steps-context-array-outcome"},
+		// {"contains(steps.*.outcome, 'failure')", true, "steps-context-array-outcome"},
+		// {"contains(steps.*.outputs.name, 'value')", true, "steps-context-array-outputs"},
 		{"runner.os", "Linux", "runner-context"},
 		{"secrets.name", "value", "secrets-context"},
 		{"strategy.fail-fast", true, "strategy-context"},
@@ -558,6 +574,10 @@ func TestContexts(t *testing.T) {
 					"name": "value",
 				},
 			},
+			"step-id2": {
+				Outcome:    model.StepStatusFailure,
+				Conclusion: model.StepStatusSkipped,
+			},
 		},
 		Runner: map[string]interface{}{
 			"os":         "Linux",
diff --git a/pkg/runner/expression_test.go b/pkg/runner/expression_test.go
index 9cbf3b6..944070c 100644
--- a/pkg/runner/expression_test.go
+++ b/pkg/runner/expression_test.go
@@ -160,14 +160,14 @@ func TestEvaluateStep(t *testing.T) {
 		out     interface{}
 		errMesg string
 	}{
-		{"steps.idwithnothing.conclusion", model.StepStatusSuccess, ""},
-		{"steps.idwithnothing.outcome", model.StepStatusFailure, ""},
+		{"steps.idwithnothing.conclusion", model.StepStatusSuccess.String(), ""},
+		{"steps.idwithnothing.outcome", model.StepStatusFailure.String(), ""},
 		{"steps.idwithnothing.outputs.foowithnothing", "barwithnothing", ""},
-		{"steps.id-with-hyphens.conclusion", model.StepStatusSuccess, ""},
-		{"steps.id-with-hyphens.outcome", model.StepStatusFailure, ""},
+		{"steps.id-with-hyphens.conclusion", model.StepStatusSuccess.String(), ""},
+		{"steps.id-with-hyphens.outcome", model.StepStatusFailure.String(), ""},
 		{"steps.id-with-hyphens.outputs.foo-with-hyphens", "bar-with-hyphens", ""},
-		{"steps.id_with_underscores.conclusion", model.StepStatusSuccess, ""},
-		{"steps.id_with_underscores.outcome", model.StepStatusFailure, ""},
+		{"steps.id_with_underscores.conclusion", model.StepStatusSuccess.String(), ""},
+		{"steps.id_with_underscores.outcome", model.StepStatusFailure.String(), ""},
 		{"steps.id_with_underscores.outputs.foo_with_underscores", "bar_with_underscores", ""},
 	}