You've already forked sap-jenkins-library
							
							
				mirror of
				https://github.com/SAP/jenkins-library.git
				synced 2025-10-30 23:57:50 +02:00 
			
		
		
		
	RFC Upload GO (#2903)
* RFC Upload GO - yaml review - add cpe - harmonize with solman
This commit is contained in:
		| @@ -34,25 +34,30 @@ func newTransportRequestUploadRFCUtils() transportRequestUploadRFCUtils { | ||||
| 	return &utils | ||||
| } | ||||
|  | ||||
| func transportRequestUploadRFC(config transportRequestUploadRFCOptions, telemetryData *telemetry.CustomData) { | ||||
| func transportRequestUploadRFC(config transportRequestUploadRFCOptions, | ||||
| 	telemetryData *telemetry.CustomData, | ||||
| 	commonPipelineEnvironment *transportRequestUploadRFCCommonPipelineEnvironment) { | ||||
| 	// Utils can be used wherever the command.ExecRunner interface is expected. | ||||
| 	// It can also be used for example as a mavenExecRunner. | ||||
| 	utils := newTransportRequestUploadRFCUtils() | ||||
|  | ||||
| 	action := rfc.UploadAction{} | ||||
| 	// For HTTP calls import  piperhttp "github.com/SAP/jenkins-library/pkg/http" | ||||
| 	// and use a  &piperhttp.Client{} in a custom system | ||||
| 	// Example: step checkmarxExecuteScan.go | ||||
|  | ||||
| 	// Error situations should be bubbled up until they reach the line below which will then stop execution | ||||
| 	// through the log.Entry().Fatal() call leading to an os.Exit(1) in the end. | ||||
| 	err := runTransportRequestUploadRFC(&config, &action, telemetryData, utils) | ||||
| 	err := runTransportRequestUploadRFC(&config, &rfc.UploadAction{}, telemetryData, utils, commonPipelineEnvironment) | ||||
| 	if err != nil { | ||||
| 		log.Entry().WithError(err).Fatal("step execution failed") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func runTransportRequestUploadRFC(config *transportRequestUploadRFCOptions, action rfc.Upload, telemetryData *telemetry.CustomData, cmd rfc.Exec) error { | ||||
| func runTransportRequestUploadRFC(config *transportRequestUploadRFCOptions, | ||||
| 	action rfc.Upload, | ||||
| 	telemetryData *telemetry.CustomData, | ||||
| 	utils rfc.Exec, | ||||
| 	commonPipelineEnvironment *transportRequestUploadRFCCommonPipelineEnvironment) error { | ||||
|  | ||||
| 	action.WithConnection( | ||||
| 		rfc.Connection{ | ||||
| @@ -81,5 +86,15 @@ func runTransportRequestUploadRFC(config *transportRequestUploadRFCOptions, acti | ||||
| 	action.WithTransportRequestID(config.TransportRequestID) | ||||
| 	action.WithApplicationURL(config.ApplicationURL) | ||||
|  | ||||
| 	return action.Perform(cmd) | ||||
| 	commonPipelineEnvironment.custom.transportRequestID = config.TransportRequestID | ||||
|  | ||||
| 	err := action.Perform(utils) | ||||
|  | ||||
| 	if err == nil { | ||||
| 		log.Entry().Infof("Upload of artifact '%s' to ABAP backend succeeded (TransportRequestId: '%s').", | ||||
| 			config.ApplicationURL, | ||||
| 			config.TransportRequestID, | ||||
| 		) | ||||
| 	} | ||||
| 	return err | ||||
| } | ||||
|   | ||||
| @@ -5,10 +5,12 @@ package cmd | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/SAP/jenkins-library/pkg/config" | ||||
| 	"github.com/SAP/jenkins-library/pkg/log" | ||||
| 	"github.com/SAP/jenkins-library/pkg/piperenv" | ||||
| 	"github.com/SAP/jenkins-library/pkg/splunk" | ||||
| 	"github.com/SAP/jenkins-library/pkg/telemetry" | ||||
| 	"github.com/spf13/cobra" | ||||
| @@ -16,10 +18,10 @@ import ( | ||||
|  | ||||
| type transportRequestUploadRFCOptions struct { | ||||
| 	Endpoint                   string `json:"endpoint,omitempty"` | ||||
| 	Client                     string `json:"client,omitempty"` | ||||
| 	Instance                   string `json:"instance,omitempty"` | ||||
| 	Username                   string `json:"username,omitempty"` | ||||
| 	Password                   string `json:"password,omitempty"` | ||||
| 	Client                     string `json:"client,omitempty"` | ||||
| 	ApplicationName            string `json:"applicationName,omitempty"` | ||||
| 	ApplicationDescription     string `json:"applicationDescription,omitempty"` | ||||
| 	AbapPackage                string `json:"abapPackage,omitempty"` | ||||
| @@ -30,19 +32,48 @@ type transportRequestUploadRFCOptions struct { | ||||
| 	TransportRequestID         string `json:"transportRequestId,omitempty"` | ||||
| } | ||||
|  | ||||
| // TransportRequestUploadRFCCommand Uploads content to a transport request | ||||
| type transportRequestUploadRFCCommonPipelineEnvironment struct { | ||||
| 	custom struct { | ||||
| 		transportRequestID string | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (p *transportRequestUploadRFCCommonPipelineEnvironment) persist(path, resourceName string) { | ||||
| 	content := []struct { | ||||
| 		category string | ||||
| 		name     string | ||||
| 		value    interface{} | ||||
| 	}{ | ||||
| 		{category: "custom", name: "transportRequestId", value: p.custom.transportRequestID}, | ||||
| 	} | ||||
|  | ||||
| 	errCount := 0 | ||||
| 	for _, param := range content { | ||||
| 		err := piperenv.SetResourceParameter(path, resourceName, filepath.Join(param.category, param.name), param.value) | ||||
| 		if err != nil { | ||||
| 			log.Entry().WithError(err).Error("Error persisting piper environment.") | ||||
| 			errCount++ | ||||
| 		} | ||||
| 	} | ||||
| 	if errCount > 0 { | ||||
| 		log.Entry().Fatal("failed to persist Piper environment") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // TransportRequestUploadRFCCommand Uploads a UI5 application as ZIP file to the ABAP system via RFC connections. | ||||
| func TransportRequestUploadRFCCommand() *cobra.Command { | ||||
| 	const STEP_NAME = "transportRequestUploadRFC" | ||||
|  | ||||
| 	metadata := transportRequestUploadRFCMetadata() | ||||
| 	var stepConfig transportRequestUploadRFCOptions | ||||
| 	var startTime time.Time | ||||
| 	var commonPipelineEnvironment transportRequestUploadRFCCommonPipelineEnvironment | ||||
| 	var logCollector *log.CollectorHook | ||||
|  | ||||
| 	var createTransportRequestUploadRFCCmd = &cobra.Command{ | ||||
| 		Use:   STEP_NAME, | ||||
| 		Short: "Uploads content to a transport request", | ||||
| 		Long:  `Uploads content to a transport request.`, | ||||
| 		Short: "Uploads a UI5 application as ZIP file to the ABAP system via RFC connections.", | ||||
| 		Long:  `This step uploads a UI5 application as ZIP file to the ABAP system via RFC connections.`, | ||||
| 		PreRunE: func(cmd *cobra.Command, _ []string) error { | ||||
| 			startTime = time.Now() | ||||
| 			log.SetStepName(STEP_NAME) | ||||
| @@ -77,6 +108,7 @@ func TransportRequestUploadRFCCommand() *cobra.Command { | ||||
| 			telemetryData.ErrorCode = "1" | ||||
| 			handler := func() { | ||||
| 				config.RemoveVaultSecretFiles() | ||||
| 				commonPipelineEnvironment.persist(GeneralConfig.EnvRootPath, "commonPipelineEnvironment") | ||||
| 				telemetryData.Duration = fmt.Sprintf("%v", time.Since(startTime).Milliseconds()) | ||||
| 				telemetryData.ErrorCategory = log.GetErrorCategory().String() | ||||
| 				telemetry.Send(&telemetryData) | ||||
| @@ -94,7 +126,7 @@ func TransportRequestUploadRFCCommand() *cobra.Command { | ||||
| 					GeneralConfig.HookConfig.SplunkConfig.Index, | ||||
| 					GeneralConfig.HookConfig.SplunkConfig.SendLogs) | ||||
| 			} | ||||
| 			transportRequestUploadRFC(stepConfig, &telemetryData) | ||||
| 			transportRequestUploadRFC(stepConfig, &telemetryData, &commonPipelineEnvironment) | ||||
| 			telemetryData.ErrorCode = "0" | ||||
| 			log.Entry().Info("SUCCESS") | ||||
| 		}, | ||||
| @@ -105,19 +137,19 @@ func TransportRequestUploadRFCCommand() *cobra.Command { | ||||
| } | ||||
|  | ||||
| func addTransportRequestUploadRFCFlags(cmd *cobra.Command, stepConfig *transportRequestUploadRFCOptions) { | ||||
| 	cmd.Flags().StringVar(&stepConfig.Endpoint, "endpoint", os.Getenv("PIPER_endpoint"), "Service endpoint") | ||||
| 	cmd.Flags().StringVar(&stepConfig.Client, "client", os.Getenv("PIPER_client"), "AS ABAP client number") | ||||
| 	cmd.Flags().StringVar(&stepConfig.Endpoint, "endpoint", os.Getenv("PIPER_endpoint"), "Service endpoint, Application server URL") | ||||
| 	cmd.Flags().StringVar(&stepConfig.Instance, "instance", os.Getenv("PIPER_instance"), "AS ABAP instance number") | ||||
| 	cmd.Flags().StringVar(&stepConfig.Username, "username", os.Getenv("PIPER_username"), "Deploy user") | ||||
| 	cmd.Flags().StringVar(&stepConfig.Password, "password", os.Getenv("PIPER_password"), "Password for the deploy user") | ||||
| 	cmd.Flags().StringVar(&stepConfig.ApplicationName, "applicationName", os.Getenv("PIPER_applicationName"), "Name of the application.") | ||||
| 	cmd.Flags().StringVar(&stepConfig.ApplicationDescription, "applicationDescription", os.Getenv("PIPER_applicationDescription"), "Description of the application.") | ||||
| 	cmd.Flags().StringVar(&stepConfig.AbapPackage, "abapPackage", os.Getenv("PIPER_abapPackage"), "ABAP package name of your application") | ||||
| 	cmd.Flags().StringVar(&stepConfig.ApplicationURL, "applicationUrl", os.Getenv("PIPER_applicationUrl"), "URL where to find the UI5 package to upload to the transport request") | ||||
| 	cmd.Flags().StringVar(&stepConfig.Username, "username", os.Getenv("PIPER_username"), "Service user for uploading to the ABAP backend via RFC") | ||||
| 	cmd.Flags().StringVar(&stepConfig.Password, "password", os.Getenv("PIPER_password"), "Service user password for uploading to the ABAP backend via RFC") | ||||
| 	cmd.Flags().StringVar(&stepConfig.Client, "client", os.Getenv("PIPER_client"), "AS ABAP client number") | ||||
| 	cmd.Flags().StringVar(&stepConfig.ApplicationName, "applicationName", os.Getenv("PIPER_applicationName"), "Name of the UI5 application") | ||||
| 	cmd.Flags().StringVar(&stepConfig.ApplicationDescription, "applicationDescription", os.Getenv("PIPER_applicationDescription"), "Description of the UI5 application") | ||||
| 	cmd.Flags().StringVar(&stepConfig.AbapPackage, "abapPackage", os.Getenv("PIPER_abapPackage"), "ABAP package name of the UI5 application") | ||||
| 	cmd.Flags().StringVar(&stepConfig.ApplicationURL, "applicationUrl", os.Getenv("PIPER_applicationUrl"), "URL of the UI5 application package to upload to the ABAP backend via RFC") | ||||
| 	cmd.Flags().StringVar(&stepConfig.CodePage, "codePage", `UTF-8`, "Code page") | ||||
| 	cmd.Flags().BoolVar(&stepConfig.AcceptUnixStyleLineEndings, "acceptUnixStyleLineEndings", true, "If unix style line endings should be accepted") | ||||
| 	cmd.Flags().BoolVar(&stepConfig.FailUploadOnWarning, "failUploadOnWarning", true, "If the upload should fail in case the log contains warnings") | ||||
| 	cmd.Flags().StringVar(&stepConfig.TransportRequestID, "transportRequestId", os.Getenv("PIPER_transportRequestId"), "Transport request id") | ||||
| 	cmd.Flags().StringVar(&stepConfig.TransportRequestID, "transportRequestId", os.Getenv("PIPER_transportRequestId"), "ID of the transport request to which the UI5 application is uploaded") | ||||
|  | ||||
| 	cmd.MarkFlagRequired("endpoint") | ||||
| 	cmd.MarkFlagRequired("username") | ||||
| @@ -125,7 +157,6 @@ func addTransportRequestUploadRFCFlags(cmd *cobra.Command, stepConfig *transport | ||||
| 	cmd.MarkFlagRequired("applicationName") | ||||
| 	cmd.MarkFlagRequired("abapPackage") | ||||
| 	cmd.MarkFlagRequired("applicationUrl") | ||||
| 	cmd.MarkFlagRequired("abapPackage") | ||||
| 	cmd.MarkFlagRequired("transportRequestId") | ||||
| } | ||||
|  | ||||
| @@ -135,12 +166,12 @@ func transportRequestUploadRFCMetadata() config.StepData { | ||||
| 		Metadata: config.StepMetadata{ | ||||
| 			Name:        "transportRequestUploadRFC", | ||||
| 			Aliases:     []config.Alias{{Name: "transportRequestUploadFile", Deprecated: false}}, | ||||
| 			Description: "Uploads content to a transport request", | ||||
| 			Description: "Uploads a UI5 application as ZIP file to the ABAP system via RFC connections.", | ||||
| 		}, | ||||
| 		Spec: config.StepSpec{ | ||||
| 			Inputs: config.StepInputs{ | ||||
| 				Secrets: []config.StepSecrets{ | ||||
| 					{Name: "uploadCredentialsId", Description: "Jenkins 'Username with password' credentials ID containing user and password to authenticate against the ABAP backend.", Type: "jenkins", Aliases: []config.Alias{{Name: "changeManagement/credentialsId", Deprecated: false}}}, | ||||
| 					{Name: "uploadCredentialsId", Description: "Jenkins 'Username with password' credentials ID containing user and password to authenticate against the ABAP backend", Type: "jenkins", Aliases: []config.Alias{{Name: "changeManagement/credentialsId", Deprecated: false}}}, | ||||
| 				}, | ||||
| 				Parameters: []config.StepParameters{ | ||||
| 					{ | ||||
| @@ -152,41 +183,53 @@ func transportRequestUploadRFCMetadata() config.StepData { | ||||
| 						Aliases:     []config.Alias{{Name: "changeManagement/endpoint"}}, | ||||
| 						Default:     os.Getenv("PIPER_endpoint"), | ||||
| 					}, | ||||
| 					{ | ||||
| 						Name:        "client", | ||||
| 						ResourceRef: []config.ResourceReference{}, | ||||
| 						Scope:       []string{"PARAMETERS", "STAGES", "STEPS", "GENERAL"}, | ||||
| 						Type:        "string", | ||||
| 						Mandatory:   false, | ||||
| 						Aliases:     []config.Alias{{Name: "changeManagement/rfc/developmentClient"}}, | ||||
| 						Default:     os.Getenv("PIPER_client"), | ||||
| 					}, | ||||
| 					{ | ||||
| 						Name:        "instance", | ||||
| 						ResourceRef: []config.ResourceReference{}, | ||||
| 						Scope:       []string{"PARAMETERS", "STAGES", "STEPS", "GENERAL"}, | ||||
| 						Type:        "string", | ||||
| 						Mandatory:   false, | ||||
| 						Aliases:     []config.Alias{{Name: "changeManagement/rfc/developmentInstance"}}, | ||||
| 						Aliases:     []config.Alias{{Name: "changeManagement/instance"}, {Name: "changeManagement/rfc/developmentInstance"}}, | ||||
| 						Default:     os.Getenv("PIPER_instance"), | ||||
| 					}, | ||||
| 					{ | ||||
| 						Name:        "username", | ||||
| 						Name: "username", | ||||
| 						ResourceRef: []config.ResourceReference{ | ||||
| 							{ | ||||
| 								Name:  "uploadCredentialsId", | ||||
| 								Param: "username", | ||||
| 								Type:  "secret", | ||||
| 							}, | ||||
| 						}, | ||||
| 						Scope:     []string{"PARAMETERS", "STAGES", "STEPS", "GENERAL"}, | ||||
| 						Type:      "string", | ||||
| 						Mandatory: true, | ||||
| 						Aliases:   []config.Alias{}, | ||||
| 						Default:   os.Getenv("PIPER_username"), | ||||
| 					}, | ||||
| 					{ | ||||
| 						Name: "password", | ||||
| 						ResourceRef: []config.ResourceReference{ | ||||
| 							{ | ||||
| 								Name:  "uploadCredentialsId", | ||||
| 								Param: "password", | ||||
| 								Type:  "secret", | ||||
| 							}, | ||||
| 						}, | ||||
| 						Scope:     []string{"PARAMETERS"}, | ||||
| 						Type:      "string", | ||||
| 						Mandatory: true, | ||||
| 						Aliases:   []config.Alias{}, | ||||
| 						Default:   os.Getenv("PIPER_password"), | ||||
| 					}, | ||||
| 					{ | ||||
| 						Name:        "client", | ||||
| 						ResourceRef: []config.ResourceReference{}, | ||||
| 						Scope:       []string{"PARAMETERS", "STAGES", "STEPS", "GENERAL"}, | ||||
| 						Type:        "string", | ||||
| 						Mandatory:   true, | ||||
| 						Aliases:     []config.Alias{}, | ||||
| 						Default:     os.Getenv("PIPER_username"), | ||||
| 					}, | ||||
| 					{ | ||||
| 						Name:        "password", | ||||
| 						ResourceRef: []config.ResourceReference{}, | ||||
| 						Scope:       []string{"PARAMETERS"}, | ||||
| 						Type:        "string", | ||||
| 						Mandatory:   true, | ||||
| 						Aliases:     []config.Alias{}, | ||||
| 						Default:     os.Getenv("PIPER_password"), | ||||
| 						Mandatory:   false, | ||||
| 						Aliases:     []config.Alias{{Name: "changeManagement/client"}, {Name: "changeManagement/rfc/developmentClient"}}, | ||||
| 						Default:     os.Getenv("PIPER_client"), | ||||
| 					}, | ||||
| 					{ | ||||
| 						Name:        "applicationName", | ||||
| @@ -224,15 +267,6 @@ func transportRequestUploadRFCMetadata() config.StepData { | ||||
| 						Aliases:     []config.Alias{}, | ||||
| 						Default:     os.Getenv("PIPER_applicationUrl"), | ||||
| 					}, | ||||
| 					{ | ||||
| 						Name:        "abapPackage", | ||||
| 						ResourceRef: []config.ResourceReference{}, | ||||
| 						Scope:       []string{"PARAMETERS", "STAGES", "STEPS", "GENERAL"}, | ||||
| 						Type:        "string", | ||||
| 						Mandatory:   true, | ||||
| 						Aliases:     []config.Alias{}, | ||||
| 						Default:     os.Getenv("PIPER_abapPackage"), | ||||
| 					}, | ||||
| 					{ | ||||
| 						Name:        "codePage", | ||||
| 						ResourceRef: []config.ResourceReference{}, | ||||
| @@ -261,13 +295,32 @@ func transportRequestUploadRFCMetadata() config.StepData { | ||||
| 						Default:     true, | ||||
| 					}, | ||||
| 					{ | ||||
| 						Name:        "transportRequestId", | ||||
| 						ResourceRef: []config.ResourceReference{}, | ||||
| 						Scope:       []string{"PARAMETERS"}, | ||||
| 						Type:        "string", | ||||
| 						Mandatory:   true, | ||||
| 						Aliases:     []config.Alias{}, | ||||
| 						Default:     os.Getenv("PIPER_transportRequestId"), | ||||
| 						Name: "transportRequestId", | ||||
| 						ResourceRef: []config.ResourceReference{ | ||||
| 							{ | ||||
| 								Name:  "commonPipelineEnvironment", | ||||
| 								Param: "custom/transportRequestId", | ||||
| 							}, | ||||
| 						}, | ||||
| 						Scope:     []string{"PARAMETERS"}, | ||||
| 						Type:      "string", | ||||
| 						Mandatory: true, | ||||
| 						Aliases:   []config.Alias{}, | ||||
| 						Default:   os.Getenv("PIPER_transportRequestId"), | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 			Containers: []config.Container{ | ||||
| 				{Name: "rfcclient", Image: "rfc-client"}, | ||||
| 			}, | ||||
| 			Outputs: config.StepOutputs{ | ||||
| 				Resources: []config.StepResources{ | ||||
| 					{ | ||||
| 						Name: "commonPipelineEnvironment", | ||||
| 						Type: "piperEnvironment", | ||||
| 						Parameters: []map[string]interface{}{ | ||||
| 							{"Name": "custom/transportRequestId"}, | ||||
| 						}, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| package cmd | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"github.com/SAP/jenkins-library/pkg/mock" | ||||
| 	"github.com/SAP/jenkins-library/pkg/transportrequest/rfc" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| @@ -21,6 +22,7 @@ func newTransportRequestUploadRFCTestsUtils() transportRequestUploadRFCMockUtils | ||||
| type uploadMock struct { | ||||
| 	received     rfc.UploadAction | ||||
| 	uploadCalled bool | ||||
| 	failWith     error | ||||
| } | ||||
|  | ||||
| // WithApplicationURL The location of the deployable | ||||
| @@ -50,61 +52,90 @@ func (m *uploadMock) WithConnection(c rfc.Connection) { | ||||
|  | ||||
| func (m *uploadMock) Perform(exec rfc.Exec) error { | ||||
| 	m.uploadCalled = true | ||||
| 	return nil | ||||
| 	return m.failWith | ||||
| } | ||||
|  | ||||
| func TestRunTransportRequestUploadRFC(t *testing.T) { | ||||
| type configMock struct { | ||||
| 	config *transportRequestUploadRFCOptions | ||||
| } | ||||
|  | ||||
| func TestTrRfcRunTransportRequestUpload(t *testing.T) { | ||||
| 	t.Parallel() | ||||
|  | ||||
| 	config := transportRequestUploadRFCOptions{ | ||||
| 		Endpoint:                   "https://my.abap.server", | ||||
| 		Client:                     "001", | ||||
| 		Instance:                   "00", | ||||
| 		Username:                   "me", | ||||
| 		Password:                   "******", | ||||
| 		ApplicationName:            "MyApp", | ||||
| 		ApplicationDescription:     "Lorem impsum", | ||||
| 		AbapPackage:                "XX", | ||||
| 		ApplicationURL:             "http://example.org/myDeployable.zip", | ||||
| 		CodePage:                   "UTF-8", | ||||
| 		AcceptUnixStyleLineEndings: true, | ||||
| 		FailUploadOnWarning:        true, | ||||
| 		TransportRequestID:         "XXXK12345678", | ||||
| 	} | ||||
| 	t.Run("good", func(t *testing.T) { | ||||
| 		t.Parallel() | ||||
|  | ||||
| 	utils := newTransportRequestUploadRFCTestsUtils() | ||||
| 		utils := newTransportRequestUploadRFCTestsUtils() | ||||
| 		configMock := newRfcConfigMock() | ||||
| 		actionMock := uploadMock{} | ||||
| 		cpe := &transportRequestUploadRFCCommonPipelineEnvironment{} | ||||
|  | ||||
| 	mock := uploadMock{} | ||||
| 		err := runTransportRequestUploadRFC(configMock.config, &actionMock, nil, utils, cpe) | ||||
|  | ||||
| 	err := runTransportRequestUploadRFC(&config, &mock, nil, utils) | ||||
| 		if assert.NoError(t, err) { | ||||
| 			t.Run("upload triggered", func(t *testing.T) { | ||||
| 				assert.True(t, actionMock.uploadCalled) | ||||
| 			}) | ||||
| 			t.Run("parameters has been marshalled", func(t *testing.T) { | ||||
| 				assert.Equal(t, rfc.UploadAction{ | ||||
| 					Connection: rfc.Connection{ | ||||
| 						Endpoint: "https://my.abap.server", | ||||
| 						Client:   "001", | ||||
| 						Instance: "00", | ||||
| 						User:     "me", | ||||
| 						Password: "******", | ||||
| 					}, | ||||
| 					Application: rfc.Application{ | ||||
| 						Name:        "MyApp", | ||||
| 						Description: "Lorem impsum", | ||||
| 						AbapPackage: "ABC", | ||||
| 					}, | ||||
| 					Configuration: rfc.UploadConfig{ | ||||
| 						AcceptUnixStyleEndOfLine: true, | ||||
| 						CodePage:                 "UTF-8", | ||||
| 						FailUploadOnWarning:      true, | ||||
| 						Verbose:                  false, // comes from general config | ||||
| 					}, | ||||
| 					TransportRequestID: "K12345678", | ||||
| 					ApplicationURL:     "http://example.org/myDeployable.zip", | ||||
| 				}, actionMock.received) | ||||
|  | ||||
| 	if assert.NoError(t, err) { | ||||
| 		t.Run("upload triggered", func(t *testing.T) { | ||||
| 			assert.True(t, mock.uploadCalled) | ||||
| 		}) | ||||
| 		t.Run("parameters has been marshalled", func(t *testing.T) { | ||||
| 			assert.Equal(t, rfc.UploadAction{ | ||||
| 				Connection: rfc.Connection{ | ||||
| 					Endpoint: "https://my.abap.server", | ||||
| 					Client:   "001", | ||||
| 					Instance: "00", | ||||
| 					User:     "me", | ||||
| 					Password: "******", | ||||
| 				}, | ||||
| 				Application: rfc.Application{ | ||||
| 					Name:        "MyApp", | ||||
| 					Description: "Lorem impsum", | ||||
| 					AbapPackage: "XX", | ||||
| 				}, | ||||
| 				Configuration: rfc.UploadConfig{ | ||||
| 					AcceptUnixStyleEndOfLine: true, | ||||
| 					CodePage:                 "UTF-8", | ||||
| 					FailUploadOnWarning:      true, | ||||
| 					Verbose:                  false, // comes from general config | ||||
| 				}, | ||||
| 				TransportRequestID: "XXXK12345678", | ||||
| 				ApplicationURL:     "http://example.org/myDeployable.zip", | ||||
| 			}, mock.received) | ||||
| 				assert.Equal(t, cpe.custom.transportRequestID, "K12345678") | ||||
| 			}) | ||||
| 		} | ||||
| 	}) | ||||
| 	t.Run("bad", func(t *testing.T) { | ||||
| 		t.Parallel() | ||||
|  | ||||
| 		t.Run("Error during deployment", func(t *testing.T) { | ||||
| 			utilsMock := newTransportRequestUploadSOLMANTestsUtils(0) | ||||
| 			configMock := newRfcConfigMock() | ||||
| 			actionMock := uploadMock{failWith: fmt.Errorf("upload failed")} | ||||
| 			cpe := &transportRequestUploadRFCCommonPipelineEnvironment{} | ||||
|  | ||||
| 			err := runTransportRequestUploadRFC(configMock.config, &actionMock, nil, utilsMock, cpe) | ||||
|  | ||||
| 			assert.Error(t, err, "upload failed") | ||||
| 		}) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func newRfcConfigMock() *configMock { | ||||
| 	return &configMock{ | ||||
| 		config: &transportRequestUploadRFCOptions{ | ||||
| 			Endpoint:                   "https://my.abap.server", | ||||
| 			Client:                     "001", | ||||
| 			Instance:                   "00", | ||||
| 			Username:                   "me", | ||||
| 			Password:                   "******", | ||||
| 			ApplicationName:            "MyApp", | ||||
| 			ApplicationDescription:     "Lorem impsum", | ||||
| 			AbapPackage:                "ABC", | ||||
| 			ApplicationURL:             "http://example.org/myDeployable.zip", | ||||
| 			CodePage:                   "UTF-8", | ||||
| 			AcceptUnixStyleLineEndings: true, | ||||
| 			FailUploadOnWarning:        true, | ||||
| 			TransportRequestID:         "K12345678", | ||||
| 		}, | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -102,7 +102,7 @@ func (action *UploadAction) Perform(command Exec) error { | ||||
| 		return fmt.Errorf("invalid configuration parameters detected. SOLMAN upload parameter may be missing : %w", err) | ||||
| 	} | ||||
| 	if len(parametersWithMissingValues) != 0 { | ||||
| 		return fmt.Errorf("Cannot perform artifact upload. The following parameters are not available %s", parametersWithMissingValues) | ||||
| 		return fmt.Errorf("cannot perform artifact upload. The following parameters are not available %s", parametersWithMissingValues) | ||||
| 	} | ||||
|  | ||||
| 	command.SetEnv([]string{ | ||||
|   | ||||
| @@ -41,7 +41,7 @@ func TestUploadRFC(t *testing.T) { | ||||
| 		err := upload.Perform(&exec) | ||||
|  | ||||
| 		if assert.NoError(t, err) { | ||||
| 			assert.Equal(t, exec.Calls, []mock.ExecCall{mock.ExecCall{Exec: "cts", Params: []string{"uploadToABAP:123456"}}}) | ||||
| 			assert.Equal(t, exec.Calls, []mock.ExecCall{{Exec: "cts", Params: []string{"uploadToABAP:123456"}}}) | ||||
| 			assert.Subset(t, []string{ | ||||
| 				"ABAP_DEVELOPMENT_SERVER=https://example.org/rfc", | ||||
| 				"ABAP_DEVELOPMENT_USER=me", | ||||
| @@ -73,7 +73,7 @@ func TestUploadRFC(t *testing.T) { | ||||
|  | ||||
| 		if assert.Error(t, err) { | ||||
| 			// Don't want to rely on the order, hence not checking for the full string ... | ||||
| 			assert.Contains(t, err.Error(), "Cannot perform artifact upload. The following parameters are not available") | ||||
| 			assert.Contains(t, err.Error(), "cannot perform artifact upload. The following parameters are not available") | ||||
| 			assert.Contains(t, err.Error(), "Connection.Endpoint") | ||||
| 			assert.Contains(t, err.Error(), "Application.AbapPackage") | ||||
| 		} | ||||
|   | ||||
| @@ -514,6 +514,8 @@ steps: | ||||
|       verbose: false | ||||
|   transportRequestRelease: | ||||
|       verbose: false | ||||
|   transportRequestUploadRFC: | ||||
|     credentialsId: 'RFC_CREDENTIALS_ID' | ||||
|   writeTemporaryCredentials: | ||||
|     credentialsDirectories: | ||||
|       - './' | ||||
|   | ||||
| @@ -2,14 +2,14 @@ metadata: | ||||
|   name: transportRequestUploadRFC | ||||
|   aliases: | ||||
|     - name: transportRequestUploadFile | ||||
|   description: "Uploads content to a transport request" | ||||
|   description: Uploads a UI5 application as ZIP file to the ABAP system via RFC connections. | ||||
|   longDescription: | | ||||
|     Uploads content to a transport request. | ||||
|     This step uploads a UI5 application as ZIP file to the ABAP system via RFC connections. | ||||
| spec: | ||||
|   inputs: | ||||
|     secrets: | ||||
|       - name: uploadCredentialsId | ||||
|         description: Jenkins 'Username with password' credentials ID containing user and password to authenticate against the ABAP backend. | ||||
|         description: Jenkins 'Username with password' credentials ID containing user and password to authenticate against the ABAP backend | ||||
|         type: jenkins | ||||
|         aliases: | ||||
|           - name: changeManagement/credentialsId | ||||
| @@ -17,7 +17,7 @@ spec: | ||||
|       - name: endpoint | ||||
|         type: string | ||||
|         mandatory: true | ||||
|         description: "Service endpoint" | ||||
|         description: "Service endpoint, Application server URL" | ||||
|         aliases: | ||||
|           - name: changeManagement/endpoint | ||||
|         scope: | ||||
| @@ -25,19 +25,10 @@ spec: | ||||
|           - STAGES | ||||
|           - STEPS | ||||
|           - GENERAL | ||||
|       - name: client | ||||
|         type: string | ||||
|         aliases: | ||||
|           - name: changeManagement/rfc/developmentClient | ||||
|         description: "AS ABAP client number" | ||||
|         scope: | ||||
|           - PARAMETERS | ||||
|           - STAGES | ||||
|           - STEPS | ||||
|           - GENERAL | ||||
|       - name: instance | ||||
|         type: string | ||||
|         aliases: | ||||
|           - name: changeManagement/instance | ||||
|           - name: changeManagement/rfc/developmentInstance | ||||
|         description: "AS ABAP instance number" | ||||
|         scope: | ||||
| @@ -48,24 +39,43 @@ spec: | ||||
|       - name: username | ||||
|         type: string | ||||
|         mandatory: true | ||||
|         description: "Deploy user" | ||||
|         description: "Service user for uploading to the ABAP backend via RFC" | ||||
|         secret: true | ||||
|         scope: | ||||
|           - PARAMETERS | ||||
|           - STAGES | ||||
|           - STEPS | ||||
|           - GENERAL | ||||
|         resourceRef: | ||||
|           - name: uploadCredentialsId | ||||
|             type: secret | ||||
|             param: username | ||||
|       - name: password | ||||
|         type: string | ||||
|         mandatory: true | ||||
|         description: "Password for the deploy user" | ||||
|         description: "Service user password for uploading to the ABAP backend via RFC" | ||||
|         secret: true | ||||
|         scope: | ||||
|           - PARAMETERS | ||||
|         resourceRef: | ||||
|           - name: uploadCredentialsId | ||||
|             type: secret | ||||
|             param: password | ||||
|       - name: client | ||||
|         type: string | ||||
|         aliases: | ||||
|           - name: changeManagement/client | ||||
|           - name: changeManagement/rfc/developmentClient | ||||
|         description: "AS ABAP client number" | ||||
|         scope: | ||||
|           - PARAMETERS | ||||
|           - STAGES | ||||
|           - STEPS | ||||
|           - GENERAL | ||||
|       - name: applicationName | ||||
|         type: string | ||||
|         mandatory: true | ||||
|         description: "Name of the application." | ||||
|         description: "Name of the UI5 application" | ||||
|         scope: | ||||
|           - PARAMETERS | ||||
|           - STAGES | ||||
| @@ -74,7 +84,7 @@ spec: | ||||
|       - name: applicationDescription | ||||
|         type: string | ||||
|         mandatory: false | ||||
|         description: "Description of the application." | ||||
|         description: "Description of the UI5 application" | ||||
|         scope: | ||||
|           - PARAMETERS | ||||
|           - STAGES | ||||
| @@ -83,7 +93,7 @@ spec: | ||||
|       - name: abapPackage | ||||
|         type: string | ||||
|         mandatory: true | ||||
|         description: "ABAP package name of your application" | ||||
|         description: "ABAP package name of the UI5 application" | ||||
|         scope: | ||||
|           - PARAMETERS | ||||
|           - STAGES | ||||
| @@ -92,16 +102,7 @@ spec: | ||||
|       - name: applicationUrl | ||||
|         type: string | ||||
|         mandatory: true | ||||
|         description: "URL where to find the UI5 package to upload to the transport request" | ||||
|         scope: | ||||
|           - PARAMETERS | ||||
|           - STAGES | ||||
|           - STEPS | ||||
|           - GENERAL | ||||
|       - name: abapPackage | ||||
|         type: string | ||||
|         mandatory: true | ||||
|         description: "ABAP package name of your application" | ||||
|         description: "URL of the UI5 application package to upload to the ABAP backend via RFC" | ||||
|         scope: | ||||
|           - PARAMETERS | ||||
|           - STAGES | ||||
| @@ -137,8 +138,20 @@ spec: | ||||
|           - STEPS | ||||
|           - GENERAL | ||||
|       - name: transportRequestId | ||||
|         resourceRef: | ||||
|           - name: commonPipelineEnvironment | ||||
|             param: custom/transportRequestId | ||||
|         type: string | ||||
|         mandatory: true | ||||
|         description: "Transport request id" | ||||
|         description: "ID of the transport request to which the UI5 application is uploaded" | ||||
|         scope: | ||||
|           - PARAMETERS | ||||
|   outputs: | ||||
|     resources: | ||||
|       - name: commonPipelineEnvironment | ||||
|         type: piperEnvironment | ||||
|         params: | ||||
|           - name: custom/transportRequestId | ||||
|   containers: | ||||
|     - name: rfcclient | ||||
|       image: rfc-client | ||||
|   | ||||
		Reference in New Issue
	
	Block a user