You've already forked sap-jenkins-library
mirror of
https://github.com/SAP/jenkins-library.git
synced 2025-07-17 01:42:43 +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
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,7 +336,7 @@ func handleSettingsFiles(config mtaBuildOptions,
|
|||||||
|
|
||||||
} else {
|
} 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 {
|
if len(config.GlobalSettingsFile) > 0 {
|
||||||
@ -329,7 +346,7 @@ func handleSettingsFiles(config mtaBuildOptions,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
log.Entry().Debugf("Global settings file not provided via configuation.")
|
log.Entry().Debugf("Global settings file not provided via configuration.")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -27,6 +27,7 @@ type mtaBuildOptions struct {
|
|||||||
SapNpmRegistry string `json:"sapNpmRegistry,omitempty"`
|
SapNpmRegistry string `json:"sapNpmRegistry,omitempty"`
|
||||||
ProjectSettingsFile string `json:"projectSettingsFile,omitempty"`
|
ProjectSettingsFile string `json:"projectSettingsFile,omitempty"`
|
||||||
GlobalSettingsFile string `json:"globalSettingsFile,omitempty"`
|
GlobalSettingsFile string `json:"globalSettingsFile,omitempty"`
|
||||||
|
M2Path string `json:"m2Path,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type mtaBuildCommonPipelineEnvironment struct {
|
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.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.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.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,
|
Mandatory: false,
|
||||||
Aliases: []config.Alias{},
|
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
|
#!/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 ..
|
pushd ..
|
||||||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -tags release -o piper
|
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"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"path"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
piperhttp "github.com/SAP/jenkins-library/pkg/http"
|
piperhttp "github.com/SAP/jenkins-library/pkg/http"
|
||||||
@ -43,6 +45,9 @@ type mavenExecRunner interface {
|
|||||||
type mavenUtils interface {
|
type mavenUtils interface {
|
||||||
FileExists(path string) (bool, error)
|
FileExists(path string) (bool, error)
|
||||||
DownloadFile(url, filename string, header http.Header, cookies []*http.Cookie) 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 {
|
type utilsBundle struct {
|
||||||
@ -107,6 +112,159 @@ func Evaluate(options *EvaluateOptions, expression string, command mavenExecRunn
|
|||||||
return value, nil
|
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) {
|
func evaluateStdOut(options *ExecuteOptions) (*bytes.Buffer, io.Writer) {
|
||||||
var stdOutBuf *bytes.Buffer
|
var stdOutBuf *bytes.Buffer
|
||||||
stdOut := log.Writer()
|
stdOut := log.Writer()
|
||||||
|
@ -2,9 +2,6 @@ package maven
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/SAP/jenkins-library/pkg/mock"
|
"github.com/SAP/jenkins-library/pkg/mock"
|
||||||
|
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -17,7 +14,7 @@ type mockUtils struct {
|
|||||||
shouldFail bool
|
shouldFail bool
|
||||||
requestedUrls []string
|
requestedUrls []string
|
||||||
requestedFiles []string
|
requestedFiles []string
|
||||||
files map[string][]byte
|
*mock.FilesMock
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockUtils) DownloadFile(url, filename string, header http.Header, cookies []*http.Cookie) error {
|
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
|
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 {
|
func newMockUtils(downloadShouldFail bool) mockUtils {
|
||||||
utils := mockUtils{shouldFail: downloadShouldFail}
|
utils := mockUtils{shouldFail: downloadShouldFail, FilesMock: &mock.FilesMock{}}
|
||||||
utils.files = map[string][]byte{}
|
|
||||||
return utils
|
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) {
|
t.Run("should resolve configured parameters and not download existing settings files", func(t *testing.T) {
|
||||||
utils := newMockUtils(false)
|
utils := newMockUtils(false)
|
||||||
utils.files[".pipeline/mavenGlobalSettings.xml"] = []byte("dummyContent")
|
utils.AddFile(".pipeline/mavenGlobalSettings.xml", []byte("dummyContent"))
|
||||||
utils.files[".pipeline/mavenProjectSettings.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}
|
opts := ExecuteOptions{PomPath: "pom.xml", GlobalSettingsFile: "https://mysettings.com", ProjectSettingsFile: "http://myprojectsettings.com", ReturnStdout: false}
|
||||||
expectedParameters := []string{
|
expectedParameters := []string{
|
||||||
"--global-settings", ".pipeline/mavenGlobalSettings.xml",
|
"--global-settings", ".pipeline/mavenGlobalSettings.xml",
|
||||||
@ -173,9 +161,8 @@ func TestDownloadSettingsFromURL(t *testing.T) {
|
|||||||
func TestGetTestModulesExcludes(t *testing.T) {
|
func TestGetTestModulesExcludes(t *testing.T) {
|
||||||
t.Run("Should return excludes for unit- and integration-tests", func(t *testing.T) {
|
t.Run("Should return excludes for unit- and integration-tests", func(t *testing.T) {
|
||||||
utils := newMockUtils(false)
|
utils := newMockUtils(false)
|
||||||
utils.files["unit-tests/pom.xml"] = []byte("dummyPomContent")
|
utils.AddFile("unit-tests/pom.xml", []byte("dummyContent"))
|
||||||
utils.files["integration-tests/pom.xml"] = []byte("dummyPomContent")
|
utils.AddFile("integration-tests/pom.xml", []byte("dummyContent"))
|
||||||
|
|
||||||
expected := []string{"-pl", "!unit-tests", "-pl", "!integration-tests"}
|
expected := []string{"-pl", "!unit-tests", "-pl", "!integration-tests"}
|
||||||
|
|
||||||
modulesExcludes := getTestModulesExcludes(&utils)
|
modulesExcludes := getTestModulesExcludes(&utils)
|
||||||
@ -190,3 +177,49 @@ func TestGetTestModulesExcludes(t *testing.T) {
|
|||||||
assert.Equal(t, expected, modulesExcludes)
|
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
|
- STEPS
|
||||||
mandatory: false
|
mandatory: false
|
||||||
default:
|
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:
|
outputs:
|
||||||
resources:
|
resources:
|
||||||
- name: commonPipelineEnvironment
|
- name: commonPipelineEnvironment
|
||||||
|
Reference in New Issue
Block a user