1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2025-01-30 05:59:39 +02:00

Merge branch 'master' into pr/inlineRules

This commit is contained in:
Christopher Fenner 2019-05-16 11:35:22 +02:00 committed by GitHub
commit 3a3b15e9ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 130 additions and 148 deletions

View File

@ -74,8 +74,7 @@ To setup the shared library, you need to perform the following steps:
1. Scroll down to section *Global Pipeline Libraries* and add a new Library by
clicking the *Add* button.
1. set *Library Name* to `piper-lib-os`
1. set *Default Version* to the branch or tag you want to consume (e.g.
`master` or `v0.1`)
1. set *Default Version* to the branch or tag you want to consume (e.g. `master` or `v0.1`)
1. set *Retrieval Method* to `Modern SCM`
1. set *Source Code Management* to `Git`
1. set *Project Repository* to `https://github.com/SAP/jenkins-library`

View File

@ -6,6 +6,8 @@ import com.sap.piper.GenerateDocumentation
import java.util.regex.Matcher
import groovy.text.StreamingTemplateEngine
import com.sap.piper.MapUtils
//
// Collects helper functions for rendering the documentation
//
@ -21,7 +23,8 @@ class TemplateHelper {
def props = parameters.get(it)
def defaultValue = isComplexDefault(props.defaultValue) ? renderComplexDefaultValue(props.defaultValue) : "`${props.defaultValue}`"
def defaultValue = isComplexDefault(props.defaultValue) ? renderComplexDefaultValue(props.defaultValue) :
props.defaultValue != null ? "`${props.defaultValue}`" : ''
t += "| `${it}` | ${props.mandatory ?: props.required ? 'yes' : 'no'} | ${defaultValue} | ${props.value ?: ''} |\n"
}
@ -375,14 +378,6 @@ class Helper {
return mappings
}
static getValue(Map config, List pPath) {
def p = config[pPath.head()]
if(pPath.size() == 1) return p // there is no tail
if(p in Map) getValue(p, pPath.tail())
return null // there is a remaining path which could not be resolved.
// the value we are looking for does not exist.
}
static resolveDocuRelevantSteps(GroovyScriptEngine gse, File stepsDir) {
def docuRelevantSteps = []
@ -641,7 +636,7 @@ def handleStep(stepName, prepareDefaultValuesStep, gse, customDefaults) {
it ->
def defaultValue = Helper.getValue(defaultConfig, it.tokenize('/'))
def defaultValue = MapUtils.getByPath(defaultConfig, it)
def parameterProperties = [
defaultValue: defaultValue,
@ -676,7 +671,7 @@ def handleStep(stepName, prepareDefaultValuesStep, gse, customDefaults) {
[
dependentParameterKey: dependentParameterKey,
key: possibleValue,
value: Helper.getValue(defaultConfig.get(possibleValue), k.tokenize('/'))
value: MapUtils.getByPath(defaultConfig.get(possibleValue), k)
]
}
}

View File

@ -11,12 +11,10 @@ Build an application based on SAPUI5 or SAP Fiori with Jenkins and deploy the bu
* You have installed Node.js including node and npm. See [Node.js](https://nodejs.org/en/download/).
* You have installed the SAP Cloud Platform Neo Environment SDK. See [SAP Development Tools](https://tools.hana.ondemand.com/#cloud).
### Project Prerequisites
This scenario requires additional files in your project and in the execution environment on your Jenkins instance.
On the project level, provide and adjust the following template:
| File Name | Description | Position |
@ -26,12 +24,10 @@ On the project level, provide and adjust the following template:
| [`package.json`](https://github.com/SAP/jenkins-library/blob/master/documentation/docs/scenarios/ui5-sap-cp/files/package.json) | This file lists the required development dependencies for the build. | Add the content of the `package.json` file to your existing `package.json` file. |
| [`Gruntfile.js`](https://github.com/SAP/jenkins-library/blob/master/documentation/docs/scenarios/ui5-sap-cp/files/Gruntfile.js) | This file controls the grunt build. By default the tasks `clean`, `build`, and `lint` are executed. | Place the `Gruntfile.js` in the root directory of your project. |
## Context
This scenario combines various different steps to create a complete pipeline.
In this scenario, we want to show how to build an application based on SAPUI5 or SAP Fiori by using the multi-target application (MTA) concept and how to deploy the build result into an SAP Cloud Platform account in the Neo environment. This document comprises the [mtaBuild](https://sap.github.io/jenkins-library/steps/mtaBuild/) and the [neoDeploy](https://sap.github.io/jenkins-library/steps/neoDeploy/) steps.
![This pipeline in Jenkins Blue Ocean](images/pipeline.jpg)
@ -73,7 +69,6 @@ steps:
| `buildTarget` | The target platform to which the mtar can be deployed. Possible values are: `CF`, `NEO`, `XSA` |
| `mtaJarLocation` | The location of the multi-target application archive builder jar file, including file name and extension. |
#### Configuration for the Deployment to SAP Cloud Platform
| Parameter | Description |
@ -83,7 +78,6 @@ steps:
| `host` | The SAP Cloud Platform host to deploy to. |
| `neoHome` | The path to the `neo-java-web-sdk` tool that is used for the deployment. |
### Parameters
For the detailed description of the relevant parameters, see:

View File

@ -15,8 +15,8 @@ Very basic setup can be done like that (with user "admin" and password "adminPwd
For more advanced setup please reach out to the respective documentation:
- https://hub.docker.com/_/influxdb/ (and https://github.com/docker-library/docs/tree/master/influxdb)
- https://hub.docker.com/r/grafana/grafana/ (and https://github.com/grafana/grafana-docker)
- InfluxDB ([Docker Hub](https://hub.docker.com/_/influxdb/) [GitHub](https://github.com/docker-library/docs/tree/master/influxdb))
- Grafana ([Docker Hub](https://hub.docker.com/r/grafana/grafana/) [GitHub](https://github.com/grafana/grafana-docker))
After you have started your InfluxDB docker you need to create a database:

View File

@ -1,7 +1,6 @@
# ${docGenStepName}
## ${docGenDescription}
## ${docGenParameters}

View File

@ -18,7 +18,7 @@ seleniumExecuteTests (script: this) {
### Example test using WebdriverIO
Example based on http://webdriver.io/guide/getstarted/modes.html and http://webdriver.io/guide.html
Example based on <http://webdriver.io/guide/getstarted/modes.html> and <http://webdriver.io/guide.html>
#### Configuration for Local Docker Environment

View File

@ -8,11 +8,8 @@
## ${docGenParameters}
## ${docGenConfiguration}
The step is configured using a customer configuration file provided as
resource in an custom shared library.

View File

@ -33,10 +33,12 @@ String getGitCommitId() {
return sh(returnStdout: true, script: 'git rev-parse HEAD').trim()
}
String[] extractLogLines(String filter = '',
String[] extractLogLines(
String filter = '',
String from = 'origin/master',
String to = 'HEAD',
String format = '%b') {
String format = '%b'
) {
// Checks below: there was an value provided from outside, but the value was null.
// Throwing an exception is more transparent than making a fallback to the defaults

View File

@ -63,6 +63,17 @@ class MapUtils implements Serializable {
m.putAll(updates)
}
static private def getByPath(Map m, def key) {
List path = key in CharSequence ? key.tokenize('/') : key
def value = m.get(path.head())
if (path.size() == 1) return value
if (value in Map) return getByPath(value, path.tail())
return null
}
/*
* Provides a new map with the same content like the original map.
* Nested Collections and Maps are copied. Values with are not

View File

@ -3,6 +3,9 @@ package com.sap.piper
import org.junit.Assert
import org.junit.Test
import static org.hamcrest.Matchers.is
import static org.junit.Assert.assertThat
class MapUtilsTest {
@Test
@ -51,6 +54,15 @@ class MapUtilsTest {
assert m == [a: 'replaced', m: [b: 'replaced', c: 'otherString']]
}
@Test
void testGetByPath() {
Map m = [trees: [oak: 5, beech :1], flowers:[rose: 23]]
assertThat(MapUtils.getByPath(m, 'flowers'), is([rose: 23]))
assertThat(MapUtils.getByPath(m, 'trees/oak'), is(5))
assertThat(MapUtils.getByPath(m, 'trees/palm'), is(null))
}
@Test
void testDeepCopy() {

View File

@ -451,27 +451,4 @@ steps: {}
assertThat(nullScript.commonPipelineEnvironment.configuration.runStage.Acceptance, is(true))
}
@Test
void testGetConfigValue() {
def config = [
invalidKey: 'invalidValue',
stringKey: 'stringValue',
listKey: [
'listValue1',
'listValue2'
],
nested: [
key: 'nestedValue'
]
]
assertThat(jsr.step.piperInitRunStageConfiguration.getConfigValue(config, 'stringKey'), is('stringValue'))
assertThat(jsr.step.piperInitRunStageConfiguration.getConfigValue(config, 'listKey'), is(['listValue1','listValue2']))
assertThat(jsr.step.piperInitRunStageConfiguration.getConfigValue(config, 'nested/key'), is('nestedValue'))
assertThat(jsr.step.piperInitRunStageConfiguration.getConfigValue(config, 'invalidKey/key'), is(nullValue()))
//assertThat(jsr.step.piperInitRunStageConfiguration.getConfigValue(config, 'nested/key'), is('nestedValue'))
}
}

View File

@ -12,6 +12,7 @@ class commonPipelineEnvironment implements Serializable {
//stores the gitCommitId as well as additional git information for the build during pipeline run
String gitCommitId
String gitCommitMessage
String gitSshUrl
String gitHttpsUrl
String gitBranch
@ -46,6 +47,7 @@ class commonPipelineEnvironment implements Serializable {
configuration = [:]
gitCommitId = null
gitCommitMessage = null
gitSshUrl = null
gitHttpsUrl = null
gitBranch = null

View File

@ -42,4 +42,3 @@ def call(Map parameters = [:], body) {
return duration
}

View File

@ -54,13 +54,17 @@ void call(Map parameters = [:]) {
deleteDir()
checkout([$class: 'GitSCM', branches: [[name: config.branch]],
checkout([
$class: 'GitSCM',
branches: [[name: config.branch]],
doGenerateSubmoduleConfigurations: false,
extensions: [[$class: 'SparseCheckoutPaths',
extensions: [[
$class: 'SparseCheckoutPaths',
sparseCheckoutPaths: [[path: config.path]]
]],
submoduleCfg: [],
userRemoteConfigs: [[credentialsId: config.credentialsId,
userRemoteConfigs: [[
credentialsId: config.credentialsId,
url: config.repoUrl
]]
])

View File

@ -3,6 +3,7 @@ import com.sap.piper.ConfigurationLoader
import static com.sap.piper.Prerequisites.checkScript
import com.sap.piper.ConfigurationHelper
import com.sap.piper.MapUtils
import groovy.transform.Field
@Field String STEP_NAME = getClass().getName()
@ -65,27 +66,27 @@ void call(Map parameters = [:]) {
case 'config':
if (condition.getValue() instanceof Map) {
condition.getValue().each {configCondition ->
if (getConfigValue(stepConfig, configCondition.getKey()) in configCondition.getValue()) {
if (MapUtils.getByPath(stepConfig, configCondition.getKey()) in configCondition.getValue()) {
stepActive = true
}
}
} else if (getConfigValue(stepConfig, condition.getValue())) {
} else if (MapUtils.getByPath(stepConfig, condition.getValue())) {
stepActive = true
}
break
case 'configKeys':
if (condition.getValue() instanceof List) {
condition.getValue().each {configKey ->
if (getConfigValue(stepConfig, configKey)) {
if (MapUtils.getByPath(stepConfig, configKey)) {
stepActive = true
}
}
} else if (getConfigValue(stepConfig, condition.getValue())) {
} else if (MapUtils.getByPath(stepConfig, condition.getValue())) {
stepActive = true
}
break
case 'filePatternFromConfig':
def conditionValue = getConfigValue(stepConfig, condition.getValue())
def conditionValue = MapUtils.getByPath(stepConfig, condition.getValue())
if (conditionValue && findFiles(glob: conditionValue)) {
stepActive = true
}
@ -110,16 +111,3 @@ void call(Map parameters = [:]) {
echo "[${STEP_NAME}] Debug - Run Step Configuration: ${script.commonPipelineEnvironment.configuration.runStep}"
}
}
private def getConfigValue(Map stepConfig, def configKey) {
if (stepConfig == null) return null
List configPath = configKey instanceof String ? configKey.tokenize('/') : configKey
def configValue = stepConfig[configPath.head()]
if (configPath.size() == 1) return configValue
if (configValue in Map) return getConfigValue(configValue, configPath.tail())
return null
}

View File

@ -189,7 +189,8 @@ void call(parameters = [:]) {
configuration.developmentSystemId,
configuration.changeManagement.endpoint,
configuration.changeManagement.credentialsId,
configuration.changeManagement.clientOpts)
configuration.changeManagement.clientOpts
)
} else if(backendType == BackendType.CTS) {
transportRequestId = cm.createTransportRequestCTS(
configuration.changeManagement.cts.docker,
@ -198,7 +199,8 @@ void call(parameters = [:]) {
configuration.description,
configuration.changeManagement.endpoint,
configuration.changeManagement.credentialsId,
configuration.changeManagement.clientOpts)
configuration.changeManagement.clientOpts
)
} else if (backendType == BackendType.RFC) {
transportRequestId = cm.createTransportRequestRFC(
configuration.changeManagement.rfc.docker,
@ -207,7 +209,8 @@ void call(parameters = [:]) {
configuration.changeManagement.rfc.developmentClient,
configuration.changeManagement.credentialsId,
configuration.description,
configuration.verbose)
configuration.verbose
)
} else {
throw new IllegalArgumentException("Invalid backend type: '${backendType}'.")
}

View File

@ -70,7 +70,7 @@ import static com.sap.piper.cm.StepHelpers.getBackendTypeAndLogInfoIfCMIntegrati
'transportRequestId',
/** @see transportRequestCreate */
'verbose',
])
])
/** Releases a Transport Request. */
@GenerateDocumentation