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 
			
		
		
		
	Install maven artifacts after mta build (#1641)
Extend mta build step to install maven artefacts after build to allow re-using them in later stages (additional unit or integration tests which might not be running as part of the "build" life-cycle).
This commit is contained in:
		| @@ -187,6 +187,23 @@ func runMtaBuild(config mtaBuildOptions, | ||||
| 	} | ||||
|  | ||||
| 	commonPipelineEnvironment.mtarFilePath = mtarName | ||||
|  | ||||
| 	err = installMavenArtifacts(e, config) | ||||
|  | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| func installMavenArtifacts(e execRunner, config mtaBuildOptions) error { | ||||
| 	pomXMLExists, err := piperutils.FileExists("pom.xml") | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if pomXMLExists { | ||||
| 		err = maven.InstallMavenArtifacts(e, maven.EvaluateOptions{M2Path: config.M2Path}) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| @@ -319,7 +336,7 @@ func handleSettingsFiles(config mtaBuildOptions, | ||||
|  | ||||
| 	} else { | ||||
|  | ||||
| 		log.Entry().Debugf("Project settings file not provided via configuation.") | ||||
| 		log.Entry().Debugf("Project settings file not provided via configuration.") | ||||
| 	} | ||||
|  | ||||
| 	if len(config.GlobalSettingsFile) > 0 { | ||||
| @@ -329,7 +346,7 @@ func handleSettingsFiles(config mtaBuildOptions, | ||||
| 		} | ||||
| 	} else { | ||||
|  | ||||
| 		log.Entry().Debugf("Global settings file not provided via configuation.") | ||||
| 		log.Entry().Debugf("Global settings file not provided via configuration.") | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
|   | ||||
| @@ -27,6 +27,7 @@ type mtaBuildOptions struct { | ||||
| 	SapNpmRegistry      string `json:"sapNpmRegistry,omitempty"` | ||||
| 	ProjectSettingsFile string `json:"projectSettingsFile,omitempty"` | ||||
| 	GlobalSettingsFile  string `json:"globalSettingsFile,omitempty"` | ||||
| 	M2Path              string `json:"m2Path,omitempty"` | ||||
| } | ||||
|  | ||||
| type mtaBuildCommonPipelineEnvironment struct { | ||||
| @@ -122,6 +123,7 @@ func addMtaBuildFlags(cmd *cobra.Command, stepConfig *mtaBuildOptions) { | ||||
| 	cmd.Flags().StringVar(&stepConfig.SapNpmRegistry, "sapNpmRegistry", `https://npm.sap.com`, "Url to the sap npm registry that should be used for installing npm dependencies prefixed with @sap.") | ||||
| 	cmd.Flags().StringVar(&stepConfig.ProjectSettingsFile, "projectSettingsFile", os.Getenv("PIPER_projectSettingsFile"), "Path or url to the mvn settings file that should be used as project settings file.") | ||||
| 	cmd.Flags().StringVar(&stepConfig.GlobalSettingsFile, "globalSettingsFile", os.Getenv("PIPER_globalSettingsFile"), "Path or url to the mvn settings file that should be used as global settings file") | ||||
| 	cmd.Flags().StringVar(&stepConfig.M2Path, "m2Path", os.Getenv("PIPER_m2Path"), "Path to the location of the local repository that should be used.") | ||||
|  | ||||
| } | ||||
|  | ||||
| @@ -223,6 +225,14 @@ func mtaBuildMetadata() config.StepData { | ||||
| 						Mandatory:   false, | ||||
| 						Aliases:     []config.Alias{}, | ||||
| 					}, | ||||
| 					{ | ||||
| 						Name:        "m2Path", | ||||
| 						ResourceRef: []config.ResourceReference{}, | ||||
| 						Scope:       []string{"GENERAL", "STEPS", "STAGES", "PARAMETERS"}, | ||||
| 						Type:        "string", | ||||
| 						Mandatory:   false, | ||||
| 						Aliases:     []config.Alias{{Name: "maven/m2Path"}}, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
|   | ||||
							
								
								
									
										145
									
								
								integration/integration_mta_build_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								integration/integration_mta_build_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,145 @@ | ||||
| // +build integration | ||||
| // can be execute with go test -tags=integration ./integration/... | ||||
|  | ||||
| package main | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"io/ioutil" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| 	"github.com/testcontainers/testcontainers-go" | ||||
| ) | ||||
|  | ||||
| func TestMavenProject(t *testing.T) { | ||||
| 	t.Parallel() | ||||
| 	ctx := context.Background() | ||||
|  | ||||
| 	pwd, err := os.Getwd() | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("Getting current working directory failed: %v", err) | ||||
| 	} | ||||
| 	pwd = filepath.Dir(pwd) | ||||
|  | ||||
| 	// using custom createTmpDir function to avoid issues with symlinks on Docker for Mac | ||||
| 	tempDir, err := createTmpDir("") | ||||
| 	defer os.RemoveAll(tempDir) // clean up | ||||
|  | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("Error when creating temp dir: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	err = copyDir(filepath.Join(pwd, "integration", "testdata", "TestMtaIntegration", "maven"), tempDir) | ||||
| 	if err != nil { | ||||
| 		t.Fatal("Failed to copy test project.") | ||||
| 	} | ||||
|  | ||||
| 	//workaround to use test script util it is possible to set workdir for Exec call | ||||
| 	testScript := `#!/bin/sh | ||||
| cd /test | ||||
| apt-get -yqq update; apt-get -yqq install make | ||||
| curl -OL https://github.com/SAP/cloud-mta-build-tool/releases/download/v1.0.14/cloud-mta-build-tool_1.0.14_Linux_amd64.tar.gz | ||||
| tar xzf cloud-mta-build-tool_1.0.14_Linux_amd64.tar.gz | ||||
| mv mbt /usr/bin | ||||
| /piperbin/piper mtaBuild >test-log.txt 2>&1 | ||||
| ` | ||||
| 	ioutil.WriteFile(filepath.Join(tempDir, "runPiper.sh"), []byte(testScript), 0700) | ||||
|  | ||||
| 	reqNode := testcontainers.ContainerRequest{ | ||||
| 		Image: "maven:3-openjdk-8-slim", | ||||
| 		Cmd:   []string{"tail", "-f"}, | ||||
|  | ||||
| 		BindMounts: map[string]string{ | ||||
| 			pwd:     "/piperbin", | ||||
| 			tempDir: "/test", | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	mbtContainer, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ | ||||
| 		ContainerRequest: reqNode, | ||||
| 		Started:          true, | ||||
| 	}) | ||||
|  | ||||
| 	code, err := mbtContainer.Exec(ctx, []string{"sh", "/test/runPiper.sh"}) | ||||
|  | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("Script returened error: %v", err) | ||||
| 	} | ||||
| 	assert.Equal(t, 0, code) | ||||
|  | ||||
| 	content, err := ioutil.ReadFile(filepath.Join(tempDir, "/test-log.txt")) | ||||
| 	if err != nil { | ||||
| 		t.Fatal("Could not read test-log.txt.", err) | ||||
| 	} | ||||
| 	output := string(content) | ||||
| 	assert.Contains(t, output, "Installing /test/pom.xml to /root/.m2/repository/mygroup/mymvn/1.0-SNAPSHOT/mymvn-1.0-SNAPSHOT.pom") | ||||
| 	assert.Contains(t, output, "Installing /test/app/target/mymvn-app-1.0-SNAPSHOT.war to /root/.m2/repository/mygroup/mymvn-app/1.0-SNAPSHOT/mymvn-app-1.0-SNAPSHOT.war") | ||||
| 	assert.Contains(t, output, "Installing /test/app/target/mymvn-app-1.0-SNAPSHOT-classes.jar to /root/.m2/repository/mygroup/mymvn-app/1.0-SNAPSHOT/mymvn-app-1.0-SNAPSHOT-classes.jar") | ||||
| } | ||||
|  | ||||
| func TestNPMProject(t *testing.T) { | ||||
| 	t.Parallel() | ||||
| 	ctx := context.Background() | ||||
|  | ||||
| 	pwd, err := os.Getwd() | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("Getting current working directory failed: %v", err) | ||||
| 	} | ||||
| 	pwd = filepath.Dir(pwd) | ||||
|  | ||||
| 	// using custom createTmpDir function to avoid issues with symlinks on Docker for Mac | ||||
| 	tempDir, err := createTmpDir("") | ||||
| 	defer os.RemoveAll(tempDir) // clean up | ||||
|  | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("Error when creating temp dir: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	err = copyDir(filepath.Join(pwd, "integration", "testdata", "TestMtaIntegration", "npm"), tempDir) | ||||
| 	if err != nil { | ||||
| 		t.Fatal("Failed to copy test project.") | ||||
| 	} | ||||
|  | ||||
| 	//workaround to use test script util it is possible to set workdir for Exec call | ||||
| 	testScript := `#!/bin/sh | ||||
| cd /test | ||||
| apt-get -yqq update; apt-get -yqq install make | ||||
| curl -OL https://github.com/SAP/cloud-mta-build-tool/releases/download/v1.0.14/cloud-mta-build-tool_1.0.14_Linux_amd64.tar.gz | ||||
| tar xzf cloud-mta-build-tool_1.0.14_Linux_amd64.tar.gz | ||||
| mv mbt /usr/bin | ||||
| /piperbin/piper mtaBuild >test-log.txt 2>&1 | ||||
| ` | ||||
| 	ioutil.WriteFile(filepath.Join(tempDir, "runPiper.sh"), []byte(testScript), 0700) | ||||
|  | ||||
| 	reqNode := testcontainers.ContainerRequest{ | ||||
| 		Image: "node:12", | ||||
| 		Cmd:   []string{"tail", "-f"}, | ||||
|  | ||||
| 		BindMounts: map[string]string{ | ||||
| 			pwd:     "/piperbin", | ||||
| 			tempDir: "/test", | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	mbtContainer, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ | ||||
| 		ContainerRequest: reqNode, | ||||
| 		Started:          true, | ||||
| 	}) | ||||
|  | ||||
| 	code, err := mbtContainer.Exec(ctx, []string{"sh", "/test/runPiper.sh"}) | ||||
|  | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("Script returened error: %v", err) | ||||
| 	} | ||||
| 	assert.Equal(t, 0, code) | ||||
|  | ||||
| 	content, err := ioutil.ReadFile(filepath.Join(tempDir, "/test-log.txt")) | ||||
| 	if err != nil { | ||||
| 		t.Fatal("Could not read test-log.txt.", err) | ||||
| 	} | ||||
| 	output := string(content) | ||||
| 	assert.Contains(t, output, "INFO the MTA archive generated at: test-mta-js.mtar") | ||||
| } | ||||
| @@ -1,6 +1,18 @@ | ||||
| #!/usr/bin/env bash | ||||
|  | ||||
| # Run all test if no arguments are given, run a single test function if it is passed as $1 | ||||
| # For example: `./run-tests.sh TestRegistrySetInNpmrc` | ||||
|  | ||||
| TEST_NAME=$1 | ||||
|  | ||||
| pushd .. | ||||
| CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -tags release -o piper | ||||
| go test -tags=integration -timeout 20m ./integration/... | ||||
| popd | ||||
|  | ||||
| if [[ "$TEST_NAME" ]] | ||||
| then | ||||
|     go test -tags=integration -timeout 20m -run "$TEST_NAME" ./integration/... | ||||
| else | ||||
|     go test -tags=integration -timeout 20m ./integration/... | ||||
| fi | ||||
|  | ||||
| popd || exit | ||||
|   | ||||
							
								
								
									
										6
									
								
								integration/testdata/TestMtaIntegration/maven/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								integration/testdata/TestMtaIntegration/maven/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| app/target | ||||
| app/.pipeline | ||||
| mtaBuild_errorDetails.json | ||||
| foo.mtar | ||||
| .flattened-pom.xml | ||||
| .pipeline/ | ||||
							
								
								
									
										3
									
								
								integration/testdata/TestMtaIntegration/maven/Dockerfile
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								integration/testdata/TestMtaIntegration/maven/Dockerfile
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| FROM devxci/mbtci:1.0.14 | ||||
|  | ||||
| COPY run-in-container.sh /test.sh | ||||
							
								
								
									
										0
									
								
								integration/testdata/TestMtaIntegration/maven/app/Foo.java
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								integration/testdata/TestMtaIntegration/maven/app/Foo.java
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
								
								
									
										23
									
								
								integration/testdata/TestMtaIntegration/maven/app/pom.xml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								integration/testdata/TestMtaIntegration/maven/app/pom.xml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||
|          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||
|     <modelVersion>4.0.0</modelVersion> | ||||
|     <groupId>mygroup</groupId> | ||||
|     <artifactId>mymvn-app</artifactId> | ||||
|     <version>1.0-SNAPSHOT</version> | ||||
|     <packaging>war</packaging> | ||||
|  | ||||
|     <build> | ||||
|         <plugins> | ||||
|             <plugin> | ||||
|                 <groupId>org.apache.maven.plugins</groupId> | ||||
|                 <artifactId>maven-war-plugin</artifactId> | ||||
|                 <version>2.6</version> | ||||
|                 <configuration> | ||||
|                     <failOnMissingWebXml>false</failOnMissingWebXml> | ||||
|                     <attachClasses>true</attachClasses> | ||||
|                 </configuration> | ||||
|             </plugin> | ||||
|         </plugins> | ||||
|     </build> | ||||
| </project> | ||||
							
								
								
									
										4
									
								
								integration/testdata/TestMtaIntegration/maven/cleanup.sh
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										4
									
								
								integration/testdata/TestMtaIntegration/maven/cleanup.sh
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| #!/usr/bin/env bash | ||||
|  | ||||
| # shellcheck disable=SC2002 | ||||
| cat .gitignore | xargs -L1 rm -r | ||||
							
								
								
									
										8
									
								
								integration/testdata/TestMtaIntegration/maven/mta.yaml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								integration/testdata/TestMtaIntegration/maven/mta.yaml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| _schema-version: "3.1" | ||||
| ID: foo | ||||
| version: 0.0.1 | ||||
|  | ||||
| modules: | ||||
|   - name: foo | ||||
|     type: java | ||||
|     path: app | ||||
							
								
								
									
										9
									
								
								integration/testdata/TestMtaIntegration/maven/pom.xml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								integration/testdata/TestMtaIntegration/maven/pom.xml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||
|          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||
|     <modelVersion>4.0.0</modelVersion> | ||||
|     <groupId>mygroup</groupId> | ||||
|     <artifactId>mymvn</artifactId> | ||||
|     <version>1.0-SNAPSHOT</version> | ||||
|     <packaging>pom</packaging> | ||||
| </project> | ||||
							
								
								
									
										13
									
								
								integration/testdata/TestMtaIntegration/maven/run-in-container.sh
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										13
									
								
								integration/testdata/TestMtaIntegration/maven/run-in-container.sh
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| #!/usr/bin/env bash | ||||
|  | ||||
| set -e | ||||
| set -x | ||||
|  | ||||
| cd /project | ||||
| /piper mtaBuild | ||||
|  | ||||
| find /root/.m2/repository/mygroup | ||||
|  | ||||
| [ -f /root/.m2/repository/mygroup/mymvn/1.0-SNAPSHOT/mymvn-1.0-SNAPSHOT.pom ] || (echo "Assertion failed, file mymvn-1.0-SNAPSHOT.pom must exist"; exit 1) | ||||
| [ -f /root/.m2/repository/mygroup/mymvn-app/1.0-SNAPSHOT/mymvn-app-1.0-SNAPSHOT.war ] || (echo "Assertion failed, file mymvn-app-1.0-SNAPSHOT.war must exist"; exit 1) | ||||
| [ -f /root/.m2/repository/mygroup/mymvn-app/1.0-SNAPSHOT/mymvn-app-1.0-SNAPSHOT-classes.jar ] || (echo "Assertion failed, file mymvn-app-1.0-SNAPSHOT-classes.jar must exist"; exit 1) | ||||
							
								
								
									
										13
									
								
								integration/testdata/TestMtaIntegration/maven/run.sh
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										13
									
								
								integration/testdata/TestMtaIntegration/maven/run.sh
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| #!/usr/bin/env bash | ||||
|  | ||||
| # This test is run in integration_mta_build_test.go | ||||
| # The purpose of this script is to provide a continent way to tinker with the test locally. | ||||
| # It is not run in CI. | ||||
|  | ||||
| pushd ../../../.. | ||||
| CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -tags release -o piper | ||||
| popd || exit 1 | ||||
| docker build -t mta-it . | ||||
| docker run --rm -v "$PWD":/project -u root \ | ||||
|     --mount type=bind,source="$(pwd)"/../../../../piper,target=/piper mta-it \ | ||||
|     /bin/bash -c "/test.sh" | ||||
							
								
								
									
										21
									
								
								integration/testdata/TestMtaIntegration/npm/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								integration/testdata/TestMtaIntegration/npm/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| _out | ||||
| *.db | ||||
| connection.properties | ||||
| default-*.json | ||||
| node_modules/ | ||||
| package-lock.json | ||||
| target/ | ||||
| .che/ | ||||
| .gen/ | ||||
| *_mta_build_tmp | ||||
| *.mtar | ||||
| mta_archives/ | ||||
| Makefile_*.mta | ||||
| .DS_Store | ||||
| *.orig | ||||
| *.log | ||||
| .pipeline | ||||
| mtaBuild_errorDetails.json | ||||
| test-mta-js.mtar | ||||
| .nyc_output/ | ||||
| s4hana_pipeline | ||||
							
								
								
									
										3
									
								
								integration/testdata/TestMtaIntegration/npm/Dockerfile
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								integration/testdata/TestMtaIntegration/npm/Dockerfile
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| FROM devxci/mbtci:1.0.14 | ||||
|  | ||||
| COPY run-in-container.sh /test.sh | ||||
							
								
								
									
										4
									
								
								integration/testdata/TestMtaIntegration/npm/cleanup.sh
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										4
									
								
								integration/testdata/TestMtaIntegration/npm/cleanup.sh
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| #!/usr/bin/env bash | ||||
|  | ||||
| # shellcheck disable=SC2002 | ||||
| cat .gitignore | xargs -L1 rm -r | ||||
							
								
								
									
										0
									
								
								integration/testdata/TestMtaIntegration/npm/gen/srv/.gitkeep
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								integration/testdata/TestMtaIntegration/npm/gen/srv/.gitkeep
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
								
								
									
										16
									
								
								integration/testdata/TestMtaIntegration/npm/mta.yaml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								integration/testdata/TestMtaIntegration/npm/mta.yaml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| _schema-version: '3.1' | ||||
| ID: test-mta-js | ||||
| version: 1.0.0 | ||||
|  | ||||
| build-parameters: | ||||
|   before-all: | ||||
|    - builder: custom | ||||
|      commands: | ||||
|       - npm install | ||||
|       - npm run-script ci-backend-unit-test | ||||
|       - npm run-script ci-it-backend | ||||
|  | ||||
| modules: | ||||
|  - name: test-mta-js-srv | ||||
|    type: nodejs | ||||
|    path: gen/srv | ||||
							
								
								
									
										22
									
								
								integration/testdata/TestMtaIntegration/npm/package.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								integration/testdata/TestMtaIntegration/npm/package.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| { | ||||
|     "name": "test-mta-js", | ||||
|     "version": "1.0.0", | ||||
|     "dependencies": { | ||||
|         "jest": "^26.0.1", | ||||
|         "jest-jenkins-reporter": "^1.0.2" | ||||
|     }, | ||||
|     "devDependencies": { | ||||
|         "chai": "^4.2.0", | ||||
|         "mocha": "^8.0.1", | ||||
|         "mocha-junit-reporter": "^2.0.0", | ||||
|         "nyc": "^15.1.0", | ||||
|         "sinon": "^9.0.2", | ||||
|         "sinon-chai": "^3.5.0", | ||||
|         "ts-node": "^8.10.2", | ||||
|         "typescript": "^3.9.5" | ||||
|     }, | ||||
|     "scripts": { | ||||
|         "ci-backend-unit-test": "nyc --report-dir ./s4hana_pipeline/reports/coverage-reports/backend-unit/ --reporter cobertura mocha -r ts-node/register test/unit-tests/*.spec.js --reporter mocha-junit-reporter --reporter-options mochaFile=./s4hana_pipeline/reports/backend-unit/results.xml", | ||||
|         "ci-it-backend": "nyc --report-dir ./s4hana_pipeline/reports/coverage-reports/backend-integration/ --reporter cobertura mocha -r ts-node/register test/integration-tests/*.spec.js --reporter mocha-junit-reporter --reporter-options mochaFile=./s4hana_pipeline/reports/backend-integration/results.xml" | ||||
|     } | ||||
| } | ||||
							
								
								
									
										9
									
								
								integration/testdata/TestMtaIntegration/npm/run-in-container.sh
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										9
									
								
								integration/testdata/TestMtaIntegration/npm/run-in-container.sh
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| #!/usr/bin/env bash | ||||
|  | ||||
| set -e | ||||
| set -x | ||||
|  | ||||
| cd /project | ||||
| /piper mtaBuild | ||||
|  | ||||
| [ -f /project/test-mta-js.mtar ] || (echo "Assertion failed, file test-mta-js.mtar must exist"; exit 1) | ||||
							
								
								
									
										13
									
								
								integration/testdata/TestMtaIntegration/npm/run.sh
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										13
									
								
								integration/testdata/TestMtaIntegration/npm/run.sh
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| #!/usr/bin/env bash | ||||
|  | ||||
| # This test is run in integration_mta_build_test.go | ||||
| # The purpose of this script is to provide a continent way to tinker with the test locally. | ||||
| # It is not run in CI. | ||||
|  | ||||
| pushd ../../../.. | ||||
| CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -tags release -o piper | ||||
| popd || exit 1 | ||||
| docker run --rm -v "$PWD":/project -u root \ | ||||
|     --mount type=bind,source="$(pwd)"/../../../../piper,target=/piper \ | ||||
|     "$(docker build -q .)" \ | ||||
|     /bin/bash -c "/test.sh" | ||||
							
								
								
									
										8
									
								
								integration/testdata/TestMtaIntegration/npm/srv/hello.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								integration/testdata/TestMtaIntegration/npm/srv/hello.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| module.exports = { | ||||
|     sum: function(a,b) { | ||||
|         return a+b | ||||
|     }, | ||||
|     multiply: function(a,b) { | ||||
|         return a*b | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										6
									
								
								integration/testdata/TestMtaIntegration/npm/test/integration-tests/helloworld.spec.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								integration/testdata/TestMtaIntegration/npm/test/integration-tests/helloworld.spec.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
|  | ||||
| describe("hello IT", () => { | ||||
|   it("responds with \"Hello, World!\"", () => { | ||||
|  | ||||
|   }); | ||||
| }); | ||||
							
								
								
									
										9
									
								
								integration/testdata/TestMtaIntegration/npm/test/unit-tests/helloworld.spec.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								integration/testdata/TestMtaIntegration/npm/test/unit-tests/helloworld.spec.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| const hello = require('../../srv/hello.js') | ||||
|  | ||||
| describe("hello world route", () => { | ||||
|   it("responds with \"Hello, World!\"", () => { | ||||
|  | ||||
|     hello.sum(1,2) | ||||
|     hello.multiply(1,1) | ||||
|   }); | ||||
| }); | ||||
| @@ -5,6 +5,8 @@ import ( | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"net/http" | ||||
| 	"path" | ||||
| 	"path/filepath" | ||||
| 	"strings" | ||||
|  | ||||
| 	piperhttp "github.com/SAP/jenkins-library/pkg/http" | ||||
| @@ -43,6 +45,9 @@ type mavenExecRunner interface { | ||||
| type mavenUtils interface { | ||||
| 	FileExists(path string) (bool, error) | ||||
| 	DownloadFile(url, filename string, header http.Header, cookies []*http.Cookie) error | ||||
| 	Glob(pattern string) (matches []string, err error) | ||||
| 	Getwd() (dir string, err error) | ||||
| 	Chdir(dir string) error | ||||
| } | ||||
|  | ||||
| type utilsBundle struct { | ||||
| @@ -107,6 +112,159 @@ func Evaluate(options *EvaluateOptions, expression string, command mavenExecRunn | ||||
| 	return value, nil | ||||
| } | ||||
|  | ||||
| // InstallFile installs a maven artifact and its pom into the local maven repository. | ||||
| // If "file" is empty, only the pom is installed. "pomFile" must not be empty. | ||||
| func InstallFile(file, pomFile, m2Path string, command mavenExecRunner) error { | ||||
| 	if len(pomFile) == 0 { | ||||
| 		return fmt.Errorf("pomFile can't be empty") | ||||
| 	} | ||||
|  | ||||
| 	var defines []string | ||||
| 	if len(file) > 0 { | ||||
| 		defines = append(defines, "-Dfile="+file) | ||||
| 		if strings.Contains(file, ".jar") { | ||||
| 			defines = append(defines, "-Dpackaging=jar") | ||||
| 		} | ||||
| 		if strings.Contains(file, "-classes") { | ||||
| 			defines = append(defines, "-Dclassifier=classes") | ||||
| 		} | ||||
|  | ||||
| 	} else { | ||||
| 		defines = append(defines, "-Dfile="+pomFile) | ||||
| 	} | ||||
| 	defines = append(defines, "-DpomFile="+pomFile) | ||||
| 	mavenOptionsInstall := ExecuteOptions{ | ||||
| 		Goals:   []string{"install:install-file"}, | ||||
| 		Defines: defines, | ||||
| 		PomPath: pomFile, | ||||
| 		M2Path:  m2Path, | ||||
| 	} | ||||
| 	_, err := Execute(&mavenOptionsInstall, command) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("failed to install maven artifacts: %w", err) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // InstallMavenArtifacts finds maven modules (identified by pom.xml files) and installs the artifacts into the local maven repository. | ||||
| func InstallMavenArtifacts(command mavenExecRunner, options EvaluateOptions) error { | ||||
| 	return doInstallMavenArtifacts(command, options, newUtils()) | ||||
| } | ||||
|  | ||||
| func doInstallMavenArtifacts(command mavenExecRunner, options EvaluateOptions, utils mavenUtils) error { | ||||
| 	err := flattenPom(command, options) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	pomFiles, err := utils.Glob(filepath.Join("**", "pom.xml")) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	oldWorkingDirectory, err := utils.Getwd() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	// Set pom path fix here because we will change into the respective pom's directory | ||||
| 	options.PomPath = "pom.xml" | ||||
| 	for _, pomFile := range pomFiles { | ||||
| 		log.Entry().Info("Installing maven artifacts from module: " + pomFile) | ||||
| 		dir := path.Dir(pomFile) | ||||
| 		err = utils.Chdir(dir) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
|  | ||||
| 		packaging, err := Evaluate(&options, "project.packaging", command) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
|  | ||||
| 		if packaging == "pom" { | ||||
| 			err = InstallFile("", "pom.xml", options.M2Path, command) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 		} else { | ||||
| 			err = installJarWarArtifacts(command, utils, options) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		err = utils.Chdir(oldWorkingDirectory) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| func installJarWarArtifacts(command mavenExecRunner, utils mavenUtils, options EvaluateOptions) error { | ||||
| 	finalName, err := Evaluate(&options, "project.build.finalName", command) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if finalName == "" { | ||||
| 		log.Entry().Warn("project.build.finalName is empty, skipping install of artifact. Installing only the pom file.") | ||||
| 		err = InstallFile("", "pom.xml", options.M2Path, command) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		return nil | ||||
| 	} | ||||
| 	jarExists, _ := utils.FileExists(jarFile(finalName)) | ||||
| 	warExists, _ := utils.FileExists(warFile(finalName)) | ||||
| 	classesJarExists, _ := utils.FileExists(classesJarFile(finalName)) | ||||
|  | ||||
| 	if jarExists { | ||||
| 		err = InstallFile(jarFile(finalName), "pom.xml", options.M2Path, command) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if warExists { | ||||
| 		err = InstallFile(warFile(finalName), "pom.xml", options.M2Path, command) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if classesJarExists { | ||||
| 		err = InstallFile(classesJarFile(finalName), "pom.xml", options.M2Path, command) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func jarFile(finalName string) string { | ||||
| 	return "target/" + finalName + ".jar" | ||||
| } | ||||
|  | ||||
| func classesJarFile(finalName string) string { | ||||
| 	return "target/" + finalName + "-classes.jar" | ||||
| } | ||||
|  | ||||
| func warFile(finalName string) string { | ||||
| 	return "target/" + finalName + ".war" | ||||
| } | ||||
|  | ||||
| func flattenPom(command mavenExecRunner, o EvaluateOptions) error { | ||||
| 	mavenOptionsFlatten := ExecuteOptions{ | ||||
| 		Goals:   []string{"flatten:flatten"}, | ||||
| 		Defines: []string{"-Dflatten.mode=resolveCiFriendliesOnly"}, | ||||
| 		PomPath: "pom.xml", | ||||
| 		M2Path:  o.M2Path, | ||||
| 	} | ||||
| 	_, err := Execute(&mavenOptionsFlatten, command) | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| func evaluateStdOut(options *ExecuteOptions) (*bytes.Buffer, io.Writer) { | ||||
| 	var stdOutBuf *bytes.Buffer | ||||
| 	stdOut := log.Writer() | ||||
|   | ||||
| @@ -2,9 +2,6 @@ package maven | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"os" | ||||
|  | ||||
| 	"github.com/SAP/jenkins-library/pkg/mock" | ||||
|  | ||||
| 	"net/http" | ||||
| @@ -17,7 +14,7 @@ type mockUtils struct { | ||||
| 	shouldFail     bool | ||||
| 	requestedUrls  []string | ||||
| 	requestedFiles []string | ||||
| 	files          map[string][]byte | ||||
| 	*mock.FilesMock | ||||
| } | ||||
|  | ||||
| func (m *mockUtils) DownloadFile(url, filename string, header http.Header, cookies []*http.Cookie) error { | ||||
| @@ -29,17 +26,8 @@ func (m *mockUtils) DownloadFile(url, filename string, header http.Header, cooki | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (m *mockUtils) FileExists(path string) (bool, error) { | ||||
| 	content := m.files[path] | ||||
| 	if content == nil { | ||||
| 		return false, fmt.Errorf("'%s': %w", path, os.ErrNotExist) | ||||
| 	} | ||||
| 	return true, nil | ||||
| } | ||||
|  | ||||
| func newMockUtils(downloadShouldFail bool) mockUtils { | ||||
| 	utils := mockUtils{shouldFail: downloadShouldFail} | ||||
| 	utils.files = map[string][]byte{} | ||||
| 	utils := mockUtils{shouldFail: downloadShouldFail, FilesMock: &mock.FilesMock{}} | ||||
| 	return utils | ||||
| } | ||||
|  | ||||
| @@ -138,8 +126,8 @@ func TestGetParameters(t *testing.T) { | ||||
| 	}) | ||||
| 	t.Run("should resolve configured parameters and not download existing settings files", func(t *testing.T) { | ||||
| 		utils := newMockUtils(false) | ||||
| 		utils.files[".pipeline/mavenGlobalSettings.xml"] = []byte("dummyContent") | ||||
| 		utils.files[".pipeline/mavenProjectSettings.xml"] = []byte("dummyContent") | ||||
| 		utils.AddFile(".pipeline/mavenGlobalSettings.xml", []byte("dummyContent")) | ||||
| 		utils.AddFile(".pipeline/mavenProjectSettings.xml", []byte("dummyContent")) | ||||
| 		opts := ExecuteOptions{PomPath: "pom.xml", GlobalSettingsFile: "https://mysettings.com", ProjectSettingsFile: "http://myprojectsettings.com", ReturnStdout: false} | ||||
| 		expectedParameters := []string{ | ||||
| 			"--global-settings", ".pipeline/mavenGlobalSettings.xml", | ||||
| @@ -173,9 +161,8 @@ func TestDownloadSettingsFromURL(t *testing.T) { | ||||
| func TestGetTestModulesExcludes(t *testing.T) { | ||||
| 	t.Run("Should return excludes for unit- and integration-tests", func(t *testing.T) { | ||||
| 		utils := newMockUtils(false) | ||||
| 		utils.files["unit-tests/pom.xml"] = []byte("dummyPomContent") | ||||
| 		utils.files["integration-tests/pom.xml"] = []byte("dummyPomContent") | ||||
|  | ||||
| 		utils.AddFile("unit-tests/pom.xml", []byte("dummyContent")) | ||||
| 		utils.AddFile("integration-tests/pom.xml", []byte("dummyContent")) | ||||
| 		expected := []string{"-pl", "!unit-tests", "-pl", "!integration-tests"} | ||||
|  | ||||
| 		modulesExcludes := getTestModulesExcludes(&utils) | ||||
| @@ -190,3 +177,49 @@ func TestGetTestModulesExcludes(t *testing.T) { | ||||
| 		assert.Equal(t, expected, modulesExcludes) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func TestMavenInstall(t *testing.T) { | ||||
| 	t.Parallel() | ||||
| 	t.Run("Should return path to jar file", func(t *testing.T) { | ||||
| 		actual := jarFile("my-app") | ||||
| 		assert.Equal(t, "target/my-app.jar", actual) | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("Should return path to war file", func(t *testing.T) { | ||||
| 		actual := warFile("my-app") | ||||
| 		assert.Equal(t, "target/my-app.war", actual) | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("Install a file", func(t *testing.T) { | ||||
| 		execMockRunner := mock.ExecMockRunner{} | ||||
| 		expectedParameters := []string{"--file", "pom.xml", "-Dfile=app.jar", "-Dpackaging=jar", "-DpomFile=pom.xml", "-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn", "--batch-mode", "install:install-file"} | ||||
|  | ||||
| 		err := InstallFile("app.jar", "pom.xml", "", &execMockRunner) | ||||
|  | ||||
| 		assert.NoError(t, err) | ||||
| 		if assert.Equal(t, len(expectedParameters), len(execMockRunner.Calls[0].Params)) { | ||||
| 			assert.Equal(t, mock.ExecCall{Exec: "mvn", Params: expectedParameters}, execMockRunner.Calls[0]) | ||||
| 		} | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("Install files in a project", func(t *testing.T) { | ||||
| 		utils := newMockUtils(false) | ||||
| 		utils.AddFile("target/foo.jar", []byte("dummyContent")) | ||||
| 		utils.AddFile("target/foo.war", []byte("dummyContent")) | ||||
| 		utils.AddFile("pom.xml", []byte("dummycontent")) | ||||
|  | ||||
| 		options := EvaluateOptions{} | ||||
| 		execMockRunner := mock.ExecMockRunner{} | ||||
| 		execMockRunner.StdoutReturn = map[string]string{"mvn --file pom.xml -Dexpression=project.build.finalName -DforceStdout -q -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn --batch-mode org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate": "foo"} | ||||
| 		err := doInstallMavenArtifacts(&execMockRunner, options, &utils) | ||||
|  | ||||
| 		assert.NoError(t, err) | ||||
| 		if assert.Equal(t, 5, len(execMockRunner.Calls)) { | ||||
| 			assert.Equal(t, mock.ExecCall{Exec: "mvn", Params: []string{"--file", "pom.xml", "-Dflatten.mode=resolveCiFriendliesOnly", "-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn", "--batch-mode", "flatten:flatten"}}, execMockRunner.Calls[0]) | ||||
| 			assert.Equal(t, mock.ExecCall{Exec: "mvn", Params: []string{"--file", "pom.xml", "-Dexpression=project.packaging", "-DforceStdout", "-q", "-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn", "--batch-mode", "org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate"}}, execMockRunner.Calls[1]) | ||||
| 			assert.Equal(t, mock.ExecCall{Exec: "mvn", Params: []string{"--file", "pom.xml", "-Dexpression=project.build.finalName", "-DforceStdout", "-q", "-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn", "--batch-mode", "org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate"}}, execMockRunner.Calls[2]) | ||||
| 			assert.Equal(t, mock.ExecCall{Exec: "mvn", Params: []string{"--file", "pom.xml", "-Dfile=target/foo.jar", "-Dpackaging=jar", "-DpomFile=pom.xml", "-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn", "--batch-mode", "install:install-file"}}, execMockRunner.Calls[3]) | ||||
| 			assert.Equal(t, mock.ExecCall{Exec: "mvn", Params: []string{"--file", "pom.xml", "-Dfile=target/foo.war", "-DpomFile=pom.xml", "-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn", "--batch-mode", "install:install-file"}}, execMockRunner.Calls[4]) | ||||
| 		} | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -118,6 +118,17 @@ spec: | ||||
|         - STEPS | ||||
|         mandatory: false | ||||
|         default: | ||||
|       - name: m2Path | ||||
|         type: string | ||||
|         description: Path to the location of the local repository that should be used. | ||||
|         scope: | ||||
|           - GENERAL | ||||
|           - STEPS | ||||
|           - STAGES | ||||
|           - PARAMETERS | ||||
|         mandatory: false | ||||
|         aliases: | ||||
|           - name: maven/m2Path | ||||
|   outputs: | ||||
|     resources: | ||||
|       - name: commonPipelineEnvironment | ||||
|   | ||||
		Reference in New Issue
	
	Block a user