diff --git a/cmd/piper.go b/cmd/piper.go
index 297b50a78..879faa41a 100644
--- a/cmd/piper.go
+++ b/cmd/piper.go
@@ -12,6 +12,7 @@ import (
 
 	"github.com/SAP/jenkins-library/pkg/config"
 	"github.com/SAP/jenkins-library/pkg/log"
+	"github.com/SAP/jenkins-library/pkg/orchestrator"
 	"github.com/SAP/jenkins-library/pkg/piperutils"
 	"github.com/pkg/errors"
 	"github.com/spf13/cobra"
@@ -223,10 +224,8 @@ func AccessTokensFromEnvJSON(env string) []string {
 	return accessTokens
 }
 
-const stageNameEnvKey = "STAGE_NAME"
-
 // initStageName initializes GeneralConfig.StageName from either GeneralConfig.ParametersJSON
-// or the environment variable 'STAGE_NAME', unless it has been provided as command line option.
+// or the environment variable (orchestrator specific), unless it has been provided as command line option.
 // Log output needs to be suppressed via outputToLog by the getConfig step.
 func initStageName(outputToLog bool) {
 	var stageNameSource string
@@ -243,15 +242,20 @@ func initStageName(outputToLog bool) {
 	}
 
 	// Use stageName from ENV as fall-back, for when extracting it from parametersJSON fails below
-	GeneralConfig.StageName = os.Getenv(stageNameEnvKey)
-	stageNameSource = fmt.Sprintf("env variable '%s'", stageNameEnvKey)
+	provider, err := orchestrator.NewOrchestratorSpecificConfigProvider()
+	if err != nil {
+		log.Entry().WithError(err).Warning("Cannot infer stage name from CI environment")
+	} else {
+		stageNameSource = "env variable"
+		GeneralConfig.StageName = provider.GetStageName()
+	}
 
 	if len(GeneralConfig.ParametersJSON) == 0 {
 		return
 	}
 
 	var params map[string]interface{}
-	err := json.Unmarshal([]byte(GeneralConfig.ParametersJSON), &params)
+	err = json.Unmarshal([]byte(GeneralConfig.ParametersJSON), &params)
 	if err != nil {
 		if outputToLog {
 			log.Entry().Infof("Failed to extract 'stageName' from parametersJSON: %v", err)
diff --git a/cmd/piper_test.go b/cmd/piper_test.go
index 1a3ac71c6..d976190d9 100644
--- a/cmd/piper_test.go
+++ b/cmd/piper_test.go
@@ -7,18 +7,27 @@ import (
 	"io/ioutil"
 	"os"
 	"path/filepath"
+	"strings"
 	"testing"
 
-	"github.com/SAP/jenkins-library/pkg/log"
-
-	"github.com/SAP/jenkins-library/pkg/config"
-	"github.com/SAP/jenkins-library/pkg/mock"
 	"github.com/ghodss/yaml"
 	"github.com/spf13/cobra"
 	flag "github.com/spf13/pflag"
 	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+
+	"github.com/SAP/jenkins-library/pkg/config"
+	"github.com/SAP/jenkins-library/pkg/log"
+	"github.com/SAP/jenkins-library/pkg/mock"
 )
 
+func resetEnv(e []string) {
+	for _, val := range e {
+		tmp := strings.Split(val, "=")
+		os.Setenv(tmp[0], tmp[1])
+	}
+}
+
 func TestAddRootFlags(t *testing.T) {
 	var testRootCmd = &cobra.Command{Use: "test", Short: "This is just a test"}
 	addRootFlags(testRootCmd)
@@ -49,16 +58,16 @@ func TestAdoptStageNameFromParametersJSON(t *testing.T) {
 	for _, test := range tt {
 		t.Run(test.name, func(t *testing.T) {
 			// init
+			defer resetEnv(os.Environ())
+			os.Clearenv()
+
+			//mock Jenkins env
+			os.Setenv("JENKINS_HOME", "anything")
+			require.NotEmpty(t, os.Getenv("JENKINS_HOME"))
+			os.Setenv("STAGE_NAME", test.stageNameEnv)
+
 			GeneralConfig.StageName = test.stageNameArg
 
-			resetValue := os.Getenv(stageNameEnvKey)
-			defer func() { _ = os.Setenv(stageNameEnvKey, resetValue) }()
-
-			err := os.Setenv(stageNameEnvKey, test.stageNameEnv)
-			if err != nil {
-				t.Fatalf("could not set env var %s", stageNameEnvKey)
-			}
-
 			if test.stageNameJSON != "" {
 				GeneralConfig.ParametersJSON = fmt.Sprintf("{\"stageName\":\"%s\"}", test.stageNameJSON)
 			} else {
diff --git a/pkg/orchestrator/azureDevOps.go b/pkg/orchestrator/azureDevOps.go
index e0e3e7a11..cf2a18ae9 100644
--- a/pkg/orchestrator/azureDevOps.go
+++ b/pkg/orchestrator/azureDevOps.go
@@ -7,6 +7,10 @@ import (
 
 type AzureDevOpsConfigProvider struct{}
 
+func (a *AzureDevOpsConfigProvider) GetStageName() string {
+	return os.Getenv("SYSTEM_STAGEDISPLAYNAME")
+}
+
 func (a *AzureDevOpsConfigProvider) GetBranch() string {
 	tmp := os.Getenv("BUILD_SOURCEBRANCH")
 	return strings.TrimPrefix(tmp, "refs/heads/")
diff --git a/pkg/orchestrator/gitHubActions.go b/pkg/orchestrator/gitHubActions.go
index 086736a5b..16606c3fa 100644
--- a/pkg/orchestrator/gitHubActions.go
+++ b/pkg/orchestrator/gitHubActions.go
@@ -7,6 +7,10 @@ import (
 
 type GitHubActionsConfigProvider struct{}
 
+func (g *GitHubActionsConfigProvider) GetStageName() string {
+	return "GITHUB_WORKFLOW" //TODO: is there something like is "stage" in GH Actions?
+}
+
 func (g *GitHubActionsConfigProvider) GetBranch() string {
 	return strings.TrimPrefix(os.Getenv("GITHUB_REF"), "refs/heads/")
 }
diff --git a/pkg/orchestrator/jenkins.go b/pkg/orchestrator/jenkins.go
index 6d030f1ad..82ba4d035 100644
--- a/pkg/orchestrator/jenkins.go
+++ b/pkg/orchestrator/jenkins.go
@@ -6,6 +6,10 @@ import (
 
 type JenkinsConfigProvider struct{}
 
+func (a *JenkinsConfigProvider) GetStageName() string {
+	return os.Getenv("STAGE_NAME")
+}
+
 func (j *JenkinsConfigProvider) GetBranch() string {
 	return os.Getenv("GIT_BRANCH")
 }
diff --git a/pkg/orchestrator/orchestrator.go b/pkg/orchestrator/orchestrator.go
index cf03aa2ea..dd386a3c8 100644
--- a/pkg/orchestrator/orchestrator.go
+++ b/pkg/orchestrator/orchestrator.go
@@ -15,6 +15,7 @@ const (
 )
 
 type OrchestratorSpecificConfigProviding interface {
+	GetStageName() string
 	GetBranch() string
 	GetBuildUrl() string
 	GetCommit() string