mirror of
https://github.com/SAP/jenkins-library.git
synced 2025-03-05 15:15:44 +02:00
Merge remote-tracking branch 'github/master' into HEAD
This commit is contained in:
commit
11812f5c09
@ -72,7 +72,7 @@ class TemplateHelper {
|
||||
|
||||
parameters.keySet().toSorted().each {
|
||||
def props = parameters.get(it)
|
||||
t += "| `${it}` | ${props.GENERAL_CONFIG ? 'X' : ''} | ${props.STEP_CONFIG ? 'X' : ''} | ${props.STAGE_CONFIG ? 'X' : ''} |\n"
|
||||
t += "| `${it}` | ${props.GENERAL_CONFIG ? 'X' : ''} | ${props.STEP_CONFIG ? 'X' : ''} | ${props.STAGE_CONFIG ? 'X' : ''} |\n"
|
||||
}
|
||||
|
||||
t.trim()
|
||||
@ -235,7 +235,7 @@ class Helper {
|
||||
mandatoryLines.clear()
|
||||
}
|
||||
|
||||
if( line.trim() ==~ /^\/\*\*/ ) {
|
||||
if( line.trim() ==~ /^\/\*\*.*/ ) {
|
||||
docu = true
|
||||
}
|
||||
|
||||
@ -243,7 +243,7 @@ class Helper {
|
||||
def _line = line
|
||||
_line = _line.replaceAll('^\\s*', '') // leading white spaces
|
||||
if(_line.startsWith('/**')) _line = _line.replaceAll('^\\/\\*\\*', '') // start comment
|
||||
if(_line.startsWith('*/')) _line = _line.replaceAll('^\\*/', '') // end comment
|
||||
if(_line.startsWith('*/') || _line.trim().endsWith('*/')) _line = _line.replaceAll('^\\*/', '').replaceAll('\\*/\\s*$', '') // end comment
|
||||
if(_line.startsWith('*')) _line = _line.replaceAll('^\\*', '') // continue comment
|
||||
if(_line.startsWith(' ')) _line = _line.replaceAll('^\\s', '')
|
||||
if(_line ==~ /.*@possibleValues.*/) {
|
||||
@ -275,7 +275,7 @@ class Helper {
|
||||
}
|
||||
}
|
||||
|
||||
if(docu && line.trim() ==~ /^\*\//) {
|
||||
if(docu && line.trim() ==~ /^.*\*\//) {
|
||||
docu = false
|
||||
value = false
|
||||
mandatory = false
|
||||
@ -418,6 +418,19 @@ for (step in steps) {
|
||||
}
|
||||
}
|
||||
|
||||
// replace @see tag in docu by docu from referenced step.
|
||||
for(step in stepDescriptors) {
|
||||
if(step.value.parameters) {
|
||||
for(param in step.value.parameters) {
|
||||
if( param?.value?.docu?.contains('@see')) {
|
||||
def otherStep = param.value.docu.replaceAll('@see', '').trim()
|
||||
param.value.docu = fetchTextFrom(otherStep, param.key, stepDescriptors)
|
||||
param.value.mandatory = fetchMandatoryFrom(otherStep, param.key, stepDescriptors)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(step in stepDescriptors) {
|
||||
try {
|
||||
renderStep(step.key, step.value)
|
||||
@ -461,6 +474,26 @@ void renderStep(stepName, stepProperties) {
|
||||
theStepDocu.withWriter { w -> w.write text }
|
||||
}
|
||||
|
||||
def fetchTextFrom(def step, def parameterName, def steps) {
|
||||
try {
|
||||
def docuFromOtherStep = steps[step]?.parameters[parameterName]?.docu
|
||||
if(! docuFromOtherStep) throw new IllegalStateException("No docu found for parameter '${parameterName}' in step ${step}.")
|
||||
return docuFromOtherStep
|
||||
} catch(e) {
|
||||
System.err << "[ERROR] Cannot retrieve docu for parameter ${parameterName} from step ${step}.\n"
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
def fetchMandatoryFrom(def step, def parameterName, def steps) {
|
||||
try {
|
||||
return steps[step]?.parameters[parameterName]?.mandatory
|
||||
} catch(e) {
|
||||
System.err << "[ERROR] Cannot retrieve docu for parameter ${parameterName} from step ${step}.\n"
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
def handleStep(stepName, prepareDefaultValuesStep, gse) {
|
||||
|
||||
File theStep = new File(stepsDir, "${stepName}.groovy")
|
||||
|
65
documentation/docs/scenarios/CAP_Scenario.md
Normal file
65
documentation/docs/scenarios/CAP_Scenario.md
Normal file
@ -0,0 +1,65 @@
|
||||
# Build and Deploy Applications with Jenkins and the SAP Cloud Application Programming Model
|
||||
|
||||
Set up a basic continuous delivery process for developing applications according to the SAP Cloud Application Programming Model.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
* You have an account on SAP Cloud Platform in the Cloud Foundry environment. See [Accounts](https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/8ed4a705efa0431b910056c0acdbf377.html).
|
||||
* You have downloaded and installed the Cloud Foundry command line interface (CLI). See [Download and Install the Cloud Foundry Command Line Interface](https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/afc3f643ec6942a283daad6cdf1b4936.html).
|
||||
* You have installed the multi-target application plug-in for the Cloud Foundry command line interface. See [Install the Multi-Target Application Plug-in in the Cloud Foundry Environment](https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/27f3af39c2584d4ea8c15ba8c282fd75.html).
|
||||
* You have installed the Java Runtime Environment 8.
|
||||
* You have installed Jenkins 2.60.3 or higher.
|
||||
* You have set up Project “Piper”. See [README](https://github.com/SAP/jenkins-library/blob/master/README.md).
|
||||
* You have installed the Multi-Target Application (MTA) Archive Builder 1.0.6 or newer. See [SAP Development Tools](https://tools.hana.ondemand.com/#cloud).
|
||||
* You have installed Node.js including node and npm. See [Node.js](https://nodejs.org/en/download/).
|
||||
|
||||
## Context
|
||||
|
||||
The Application Programming Model for SAP Cloud Platform is an end-to-end best practice guide for developing applications on SAP Cloud Platform and provides a supportive set of APIs, languages, and libraries. For more information about the SAP Cloud Application Programming Model, see [Working with the SAP Cloud Application Programming Model](https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/00823f91779d4d42aa29a498e0535cdf.html).
|
||||
|
||||
In this scenario, we want to show how to implement a basic continuous delivery process for developing applications according to this programming model with the help of project "Piper" on Jenkins. This basic scenario can be adapted and enriched according to your specific needs.
|
||||
|
||||
## Example
|
||||
|
||||
### Jenkinsfile
|
||||
|
||||
```groovy
|
||||
@Library('piper-library-os') _
|
||||
|
||||
node(){
|
||||
stage('Prepare') {
|
||||
deleteDir()
|
||||
checkout scm
|
||||
setupCommonPipelineEnvironment script:this
|
||||
}
|
||||
|
||||
stage('Build') {
|
||||
mtaBuild script:this
|
||||
}
|
||||
|
||||
stage('Deploy') {
|
||||
cloudFoundryDeploy script:this, deployTool:'mtaDeployPlugin'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Configuration (`.pipeline/config.yml`)
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
mtaBuild
|
||||
buildTarget: 'CF'
|
||||
cloudFoundryDeploy:
|
||||
cloudFoundry:
|
||||
credentialsId: 'CF'
|
||||
apiEndpoint: '<CF Endpoint>'
|
||||
org: '<CF Organization>'
|
||||
space: '<CF Space>'
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
For the detailed description of the relevant parameters, see:
|
||||
|
||||
* [mtaBuild](https://sap.github.io/jenkins-library/steps/mtaBuild/)
|
||||
* [cloudFoundryDeploy](https://sap.github.io/jenkins-library/steps/cloudFoundryDeploy/)
|
@ -1,4 +1,4 @@
|
||||
# Develop Hybrid Applications with Jenkins and SAP Solution Manager
|
||||
# Build and Deploy Hybrid Applications with Jenkins and SAP Solution Manager
|
||||
|
||||
Set up an agile development process with Jenkins CI, which automatically feeds changes into SAP Solution Manager.
|
||||
|
||||
@ -38,7 +38,7 @@ The basic workflow is as follows:
|
||||
5. As soon as the development process is completed, the change document in SAP Solution Manager can be set to status `to be tested` and all components can be transported to the test system.
|
||||
|
||||

|
||||
##### Hybrid Application Development Worflow
|
||||
###### Hybrid Application Development Workflow
|
||||
|
||||
## Example
|
||||
|
||||
@ -92,4 +92,6 @@ For the detailed description of the relevant parameters, see:
|
||||
|
||||
* [checkChangeInDevelopment](https://sap.github.io/jenkins-library/steps/checkChangeInDevelopment/)
|
||||
* [mtaBuild](https://sap.github.io/jenkins-library/steps/mtaBuild/)
|
||||
* [transportRequestCreate](https://sap.github.io/jenkins-library/steps/transportRequestCreate/)
|
||||
* [transportRequestUploadFile](https://sap.github.io/jenkins-library/steps/transportRequestUploadFile/)
|
||||
* [transportRequestRelease](https://sap.github.io/jenkins-library/steps/transportRequestRelease/)
|
||||
|
@ -1,9 +1,6 @@
|
||||
# Create a Pipeline for SAP UI5 or SAP Fiori on SAP Cloud Platform
|
||||
|
||||
Create an application based on SAP UI5 or SAP Fiori and deploy the build result into an SAP Cloud Platform account in the Neo environment.
|
||||
|
||||
This document describes a scenario step, which means that it combines various different steps to create a complete pipeline.
|
||||
# Build and Deploy SAP UI5 or SAP Fiori Applications on SAP Cloud Platform with Jenkins
|
||||
|
||||
Build an application based on SAP UI5 or SAP Fiori with Jenkins and deploy the build result into an SAP Cloud Platform account in the Neo environment.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
@ -17,21 +14,28 @@ This document describes a scenario step, which means that it combines various di
|
||||
|
||||
### Project Prerequisites
|
||||
|
||||
This scenario step requires additional files in your project and the execution environment on your Jenkins instance. On the project level, provide and adjust the following template:
|
||||
This scenario requires additional files in your project and in the execution environment on your Jenkins instance.
|
||||
|
||||
| File Name | Description |
|
||||
|-----|-----|
|
||||
| [`.npmrc`](https://github.com/marcusholl/jenkins-library/tree/pr/scenarioUI5SAPCP/documentation/docs/scenarios/ui5-sap-cp/files/.npmrc) | This file contains a reference to the SAP NPM registry (`@sap:registry https://npm.sap.com`), which is required to fetch dependencies to build the application. Place it in the root directory of your project. |
|
||||
| [`mta.yaml`](https://github.com/marcusholl/jenkins-library/tree/pr/scenarioUI5SAPCP/documentation/docs/scenarios/ui5-sap-cp/files/mta.yaml) | This file controls the behavior of the MTA toolset. Place it in your application root folder and adjust the values in brackets with your data. |
|
||||
| [`package.json`](https://github.com/marcusholl/jenkins-library/tree/pr/scenarioUI5SAPCP/documentation/docs/scenarios/ui5-sap-cp/files/package.json) | This file lists the required development dependencies for the build. Add the content to your existing `package.json` file. |
|
||||
| [`Gruntfile.js`](https://github.com/marcusholl/jenkins-library/tree/pr/scenarioUI5SAPCP/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 it in the root directory of your project. |
|
||||
|
||||
On the project level, provide and adjust the following template:
|
||||
|
||||
| File Name | Description | Position |
|
||||
|-----|-----|-----|
|
||||
| [`.npmrc`](https://github.com/SAP/jenkins-library/blob/master/documentation/docs/scenarios/ui5-sap-cp/files/.npmrc) | This file contains a reference to the SAP NPM registry (`@sap:registry https://npm.sap.com`), which is required to fetch the dependencies required to build the application. | Place the `.npmrc` file in the root directory of your project. |
|
||||
| [`mta.yaml`](https://github.com/SAP/jenkins-library/blob/master/documentation/docs/scenarios/ui5-sap-cp/files/mta.yaml) | This file controls the behavior of the MTA toolset. | Place the `mta.yaml` file in your application root folder and adjust the values in brackets with your data. |
|
||||
| [`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
|
||||
|
||||
In this scenario step, we want to show how to build an application based on SAP UI5 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 scenario combines various different steps to create a complete pipeline.
|
||||
|
||||
|
||||
In this scenario, we want to show how to build an application based on SAP UI5 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.
|
||||
|
||||

|
||||
###### Screenshot: Build and Deploy Process in Jenkins
|
||||
|
||||
## Example
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
## Description
|
||||
|
||||
Executes a closure inside a container in a kubernetes pod. Proxy environment variables defined on the Jenkins machine are also available in the container.
|
||||
Content here is generated from corresponnding step, see `vars`.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
@ -13,59 +13,11 @@ Executes a closure inside a container in a kubernetes pod. Proxy environment var
|
||||
|
||||
## Parameters
|
||||
|
||||
| parameter | mandatory | default | possible values |
|
||||
| ----------|-----------|---------|-----------------|
|
||||
|script|yes|||
|
||||
|containerCommand|no|||
|
||||
|containerCommands|no|||
|
||||
|containerEnvVars|no|||
|
||||
|containerMap|no|`[:]`||
|
||||
|containerName|no|||
|
||||
|containerPortMappings|no|||
|
||||
|containerShell|no|||
|
||||
|containerWorkspaces|no|||
|
||||
|dockerEnvVars|no|`[:]`||
|
||||
|dockerImage|yes|||
|
||||
|dockerWorkspace|no|`''`||
|
||||
|jenkinsKubernetes|no|`[jnlpAgent:s4sdk/jenkins-agent-k8s:latest]`||
|
||||
|stashExcludes|no|`[workspace:nohup.out]`||
|
||||
|stashIncludes|no|`[workspace:**/*.*]`||
|
||||
|
||||
* `script` defines the global script environment of the Jenkins file run. Typically `this` is passed to this parameter. This allows the function to access the [`commonPipelineEnvironment`](commonPipelineEnvironment.md) for storing the measured duration.
|
||||
* `containerCommand`: allows to specify start command for container created with dockerImage parameter to overwrite Piper default (`/usr/bin/tail -f /dev/null`).
|
||||
* `containerCommands` specifies start command for containers to overwrite Piper default (`/usr/bin/tail -f /dev/null`). If container's defaultstart command should be used provide empty string like: `['selenium/standalone-chrome': '']`.
|
||||
* `containerEnvVars` specifies environment variables per container. If not provided `dockerEnvVars` will be used.
|
||||
* `containerMap` A map of docker image to the name of the container. The pod will be created with all the images from this map and they are labled based on the value field of each map entry.
|
||||
Example: `['maven:3.5-jdk-8-alpine': 'mavenExecute', 'selenium/standalone-chrome': 'selenium', 'famiko/jmeter-base': 'checkJMeter', 's4sdk/docker-cf-cli': 'cloudfoundry']`
|
||||
* `containerName`: optional configuration in combination with containerMap to define the container where the commands should be executed in
|
||||
* `containerPortMappings`: Map which defines per docker image the port mappings, like `containerPortMappings: ['selenium/standalone-chrome': [[name: 'selPort', containerPort: 4444, hostPort: 4444]]]`
|
||||
* `containerShell` allows to specify the shell to be executed for container with containerName
|
||||
* `containerWorkspaces` specifies workspace (=home directory of user) per container. If not provided `dockerWorkspace` will be used. If empty, home directory will not be set.
|
||||
* `dockerImage` Name of the docker image that should be used. If empty, Docker is not used.
|
||||
* `dockerEnvVars` Environment variables to set in the container, e.g. [http_proxy:'proxy:8080']
|
||||
* `dockerWorkspace` Docker options to be set when starting the container. It can be a list or a string.
|
||||
Content here is generated from corresponnding step, see `vars`.
|
||||
|
||||
## Step configuration
|
||||
|
||||
We recommend to define values of step parameters via [config.yml file](../configuration.md).
|
||||
|
||||
In following sections the configuration is possible:
|
||||
|
||||
| parameter | general | step | stage |
|
||||
| ----------|-----------|---------|-----------------|
|
||||
|script||||
|
||||
|containerCommands||X|X|
|
||||
|containerEnvVars||X|X|
|
||||
|containerMap||X|X|
|
||||
|containerName||X|X|
|
||||
|containerPortMappings||X|X|
|
||||
|containerWorkspaces||X|X|
|
||||
|dockerEnvVars||X|X|
|
||||
|dockerImage||X|X|
|
||||
|dockerWorkspace||X|X|
|
||||
|jenkinsKubernetes|X|||
|
||||
|stashExcludes||X|X|
|
||||
|stashIncludes||X|X|
|
||||
Content here is generated from corresponnding step, see `vars`.
|
||||
|
||||
## Side effects
|
||||
|
||||
|
@ -55,7 +55,9 @@ testsPublishResults script: this, junit: [pattern: '**/newman/TEST-*.xml']
|
||||
|
||||
We recommend to define values of step parameters via [config.yml file](../configuration.md).
|
||||
|
||||
In following sections the configuration is possible:| parameter | general | step | stage |
|
||||
In following sections the configuration is possible:
|
||||
|
||||
| parameter | general | step | stage |
|
||||
|-----------|---------|------|-------|
|
||||
| `dockerImage` | | X | X |
|
||||
| `failOnError` | | X | X |
|
||||
|
@ -33,6 +33,7 @@ Available parameters:
|
||||
| parameter | mandatory | default | possible values |
|
||||
| ----------|-----------|---------|-----------------|
|
||||
| script | yes | | |
|
||||
| `failOnError` | no | `false` | `true`, `false` |
|
||||
| junit | no | `false` | true, false |
|
||||
| jacoco | no | `false` | true, false |
|
||||
| cobertura | no | `false` | true, false |
|
||||
@ -43,6 +44,7 @@ Available parameters:
|
||||
with the `this` parameter, as in `script: this`.
|
||||
This allows the function to access the [`commonPipelineEnvironment`](commonPipelineEnvironment.md)
|
||||
for retrieving, for example, configuration parameters.
|
||||
* `failOnError` - If `failOnError` it set to `true` the step will fail the build if JUnit detected any failing tests.
|
||||
* `junit` - Publishes test results files in JUnit format with the [JUnit Plugin](https://plugins.jenkins.io/junit).
|
||||
* `jacoco` - Publishes code coverage with the [JaCoCo plugin](https://plugins.jenkins.io/jacoco) .
|
||||
* `cobertura` - Publishes code coverage with the [Cobertura plugin](https://plugins.jenkins.io/cobertura).
|
||||
|
@ -35,9 +35,11 @@ nav:
|
||||
- transportRequestCreate: steps/transportRequestCreate.md
|
||||
- transportRequestRelease: steps/transportRequestRelease.md
|
||||
- transportRequestUploadFile: steps/transportRequestUploadFile.md
|
||||
- uiVeri5ExecuteTests: steps/uiVeri5ExecuteTests.md
|
||||
- 'Scenarios':
|
||||
- 'Develop Hybrid Applications with Jenkins and SAP Solution Manager': scenarios/changeManagement.md
|
||||
- 'Create a Pipeline for SAP UI5 or SAP Fiori on SAP Cloud Platform': scenarios/ui5-sap-cp/Readme.md
|
||||
- 'Build and Deploy Hybrid Applications with Jenkins and SAP Solution Manager': scenarios/changeManagement.md
|
||||
- 'Build and Deploy SAP UI5 or SAP Fiori Applications on SAP Cloud Platform with Jenkins': scenarios/ui5-sap-cp/Readme.md
|
||||
- 'Build and Deploy Applications with Jenkins and the SAP Cloud Application Programming Model': scenarios/CAP_Scenario.md
|
||||
- 'Required Plugins': jenkins/requiredPlugins.md
|
||||
|
||||
theme:
|
||||
|
20
resources/com.sap.piper/pipeline/stageDefaults.yml
Normal file
20
resources/com.sap.piper/pipeline/stageDefaults.yml
Normal file
@ -0,0 +1,20 @@
|
||||
stages:
|
||||
'Pull-Request Voting': {}
|
||||
Build: {}
|
||||
'Additional Unit Tests': {}
|
||||
Integration: {}
|
||||
Acceptance:
|
||||
stepConditions:
|
||||
cloudFoundryDeploy:
|
||||
config: 'cfSpace'
|
||||
newmanExecute:
|
||||
filePatternFromConfig: 'newmanCollection'
|
||||
config: 'testRepository'
|
||||
uiVeri5ExecuteTests:
|
||||
filePattern: '**/conf.js'
|
||||
config: 'testRepository'
|
||||
Security: {}
|
||||
Performance: {}
|
||||
Compliance: {}
|
||||
Promote: {}
|
||||
Release: {}
|
14
resources/com.sap.piper/pipeline/stashSettings.yml
Normal file
14
resources/com.sap.piper/pipeline/stashSettings.yml
Normal file
@ -0,0 +1,14 @@
|
||||
Init:
|
||||
unstash: []
|
||||
stashes:
|
||||
- name: "source"
|
||||
includes: "**/*"
|
||||
excludes: ".pipeline/**"
|
||||
|
||||
'Central Build':
|
||||
unstash: ['source']
|
||||
stashes: []
|
||||
|
||||
'Pull-Request Voting':
|
||||
unstash: ['source']
|
||||
stashes: []
|
@ -5,7 +5,6 @@
|
||||
|
||||
#Project Setup
|
||||
general:
|
||||
productiveBranch: 'master'
|
||||
collectTelemetryData: true
|
||||
changeManagement:
|
||||
type: 'NONE' # SOLMAN, CTS, NONE
|
||||
@ -22,6 +21,8 @@ general:
|
||||
gitSshKeyCredentialsId: '' #needed to allow sshagent to run with local ssh key
|
||||
jenkinsKubernetes:
|
||||
jnlpAgent: 's4sdk/jenkins-agent-k8s:latest'
|
||||
manualConfirmation: true
|
||||
productiveBranch: 'master'
|
||||
|
||||
#Steps Specific Configuration
|
||||
steps:
|
||||
@ -153,8 +154,11 @@ steps:
|
||||
- 'tests'
|
||||
testReportFilePath: 'cst-report.json'
|
||||
dockerExecute:
|
||||
dockerPullImage: true
|
||||
sidecarPullImage: true
|
||||
stashContent: []
|
||||
dockerExecuteOnKubernetes:
|
||||
dockerPullImage: true
|
||||
stashContent: []
|
||||
stashIncludes:
|
||||
workspace: '**/*'
|
||||
@ -313,6 +317,7 @@ steps:
|
||||
toJson: false
|
||||
toHtml: false
|
||||
testsPublishResults:
|
||||
failOnError: false
|
||||
junit:
|
||||
pattern: '**/TEST-*.xml'
|
||||
updateResults: false
|
||||
|
@ -3,6 +3,7 @@ package com.sap.piper
|
||||
import com.cloudbees.groovy.cps.NonCPS
|
||||
import jenkins.model.Jenkins
|
||||
import org.jenkinsci.plugins.workflow.steps.MissingContextVariableException
|
||||
import hudson.tasks.junit.TestResultAction
|
||||
|
||||
@API
|
||||
@NonCPS
|
||||
@ -10,6 +11,14 @@ static def isPluginActive(pluginId) {
|
||||
return Jenkins.instance.pluginManager.plugins.find { p -> p.isActive() && p.getShortName() == pluginId }
|
||||
}
|
||||
|
||||
static boolean hasTestFailures(build){
|
||||
//build: https://javadoc.jenkins.io/plugin/workflow-support/org/jenkinsci/plugins/workflow/support/steps/build/RunWrapper.html
|
||||
//getRawBuild: https://javadoc.jenkins.io/plugin/workflow-job/org/jenkinsci/plugins/workflow/job/WorkflowRun.html
|
||||
//getAction: http://www.hudson-ci.org/javadoc/hudson/tasks/junit/TestResultAction.html
|
||||
def action = build?.getRawBuild()?.getAction(TestResultAction.class)
|
||||
return action && action.getFailCount() != 0
|
||||
}
|
||||
|
||||
def nodeAvailable() {
|
||||
try {
|
||||
sh "echo 'Node is available!'"
|
||||
|
@ -47,6 +47,7 @@ public class CommonStepsTest extends BasePiperTest{
|
||||
'commonPipelineEnvironment',
|
||||
'handlePipelineStepErrors',
|
||||
'pipelineExecute',
|
||||
'piperPipeline',
|
||||
'prepareDefaultValues',
|
||||
'setupCommonPipelineEnvironment',
|
||||
'toolValidate',
|
||||
@ -103,6 +104,7 @@ public class CommonStepsTest extends BasePiperTest{
|
||||
'toolValidate', // step is intended to be configured by other steps
|
||||
'durationMeasure', // only expects parameters via signature
|
||||
'prepareDefaultValues', // special step (infrastructure)
|
||||
'piperPipeline', // special step (infrastructure)
|
||||
'pipelineStashFilesAfterBuild', // intended to be called from pipelineStashFiles
|
||||
'pipelineStashFilesBeforeBuild', // intended to be called from pipelineStashFiles
|
||||
'pipelineStashFiles', // only forwards to before/after step
|
||||
@ -166,7 +168,10 @@ public class CommonStepsTest extends BasePiperTest{
|
||||
@Test
|
||||
public void stepsWithWrongFieldNameTest() {
|
||||
|
||||
def whitelist = ['commonPipelineEnvironment']
|
||||
def whitelist = [
|
||||
'commonPipelineEnvironment',
|
||||
'piperPipeline'
|
||||
]
|
||||
|
||||
def stepsWithWrongStepName = []
|
||||
|
||||
|
@ -53,6 +53,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest {
|
||||
def envList = []
|
||||
def portList = []
|
||||
def containerCommands = []
|
||||
def pullImageMap = [:]
|
||||
|
||||
|
||||
@Before
|
||||
@ -78,6 +79,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest {
|
||||
if (option.command) {
|
||||
containerCommands.add(option.command)
|
||||
}
|
||||
pullImageMap.put(option.image.toString(), option.alwaysPullImage)
|
||||
}
|
||||
body()
|
||||
})
|
||||
@ -287,6 +289,50 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest {
|
||||
assertThat(containerCommands, hasItem('/busybox/tail -f /dev/null'))
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSkipDockerImagePull() throws Exception {
|
||||
stepRule.step.dockerExecuteOnKubernetes(
|
||||
script: nullScript,
|
||||
dockerPullImage: false,
|
||||
containerMap: ['maven:3.5-jdk-8-alpine': 'mavenexecute']
|
||||
) {
|
||||
container(name: 'mavenexecute') {
|
||||
bodyExecuted = true
|
||||
}
|
||||
}
|
||||
assertEquals(false, pullImageMap.get('maven:3.5-jdk-8-alpine'))
|
||||
assertTrue(bodyExecuted)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSkipSidecarImagePull() throws Exception {
|
||||
stepRule.step.dockerExecuteOnKubernetes(
|
||||
script: nullScript,
|
||||
juStabUtils: utils,
|
||||
containerCommands: ['selenium/standalone-chrome': ''],
|
||||
containerEnvVars: [
|
||||
'selenium/standalone-chrome': ['customEnvKey': 'customEnvValue']
|
||||
],
|
||||
containerMap: [
|
||||
'maven:3.5-jdk-8-alpine': 'mavenexecute',
|
||||
'selenium/standalone-chrome': 'selenium'
|
||||
],
|
||||
containerName: 'mavenexecute',
|
||||
containerWorkspaces: [
|
||||
'selenium/standalone-chrome': ''
|
||||
],
|
||||
containerPullImageFlags: [
|
||||
'maven:3.5-jdk-8-alpine': true,
|
||||
'selenium/standalone-chrome': false
|
||||
],
|
||||
dockerWorkspace: '/home/piper'
|
||||
) {
|
||||
bodyExecuted = true
|
||||
}
|
||||
assertEquals(true, pullImageMap.get('maven:3.5-jdk-8-alpine'))
|
||||
assertEquals(false, pullImageMap.get('selenium/standalone-chrome'))
|
||||
assertTrue(bodyExecuted)
|
||||
}
|
||||
|
||||
private container(options, body) {
|
||||
containerName = options.name
|
||||
|
@ -137,6 +137,38 @@ class DockerExecuteTest extends BasePiperTest {
|
||||
assertTrue(bodyExecuted)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSkipDockerImagePull() throws Exception {
|
||||
nullScript.commonPipelineEnvironment.configuration = [steps:[dockerExecute:[dockerPullImage: false]]]
|
||||
stepRule.step.dockerExecute(
|
||||
script: nullScript,
|
||||
dockerImage: 'maven:3.5-jdk-8-alpine'
|
||||
) {
|
||||
bodyExecuted = true
|
||||
}
|
||||
assertThat(docker.imagePullCount, is(0))
|
||||
assertThat(bodyExecuted, is(true))
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSkipSidecarImagePull() throws Exception {
|
||||
stepRule.step.dockerExecute(
|
||||
script: nullScript,
|
||||
dockerName: 'maven',
|
||||
dockerImage: 'maven:3.5-jdk-8-alpine',
|
||||
sidecarEnvVars: ['testEnv':'testVal'],
|
||||
sidecarImage: 'selenium/standalone-chrome',
|
||||
sidecarVolumeBind: ['/dev/shm':'/dev/shm'],
|
||||
sidecarName: 'testAlias',
|
||||
sidecarPorts: ['4444':'4444', '1111':'1111'],
|
||||
sidecarPullImage: false
|
||||
) {
|
||||
bodyExecuted = true
|
||||
}
|
||||
assertThat(docker.imagePullCount, is(1))
|
||||
assertThat(bodyExecuted, is(true))
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExecuteInsideDockerContainerWithParameters() throws Exception {
|
||||
stepRule.step.dockerExecute(script: nullScript,
|
||||
|
@ -72,8 +72,6 @@ user3@domain.com noreply+github@domain.com'''
|
||||
],
|
||||
'master',
|
||||
2)
|
||||
println("LOGS: ${loggingRule.log}")
|
||||
println("RESULT: ${result}")
|
||||
// asserts
|
||||
assertThat(result, containsString('user2@domain.com'))
|
||||
assertThat(result, containsString('user3@domain.com'))
|
||||
|
@ -113,7 +113,7 @@ class PiperStageWrapperTest extends BasePiperTest {
|
||||
assertThat(executed, is(true))
|
||||
assertThat(loggingRule.log, containsString('[piperStageWrapper] Running project interceptor \'.pipeline/extensions/test.groovy\' for test.'))
|
||||
assertThat(loggingRule.log, containsString('Stage Name: test'))
|
||||
assertThat(loggingRule.log, containsString('Config: [productiveBranch:master,'))
|
||||
assertThat(loggingRule.log, containsString('Config: ['))
|
||||
assertThat(loggingRule.log, containsString('testBranch'))
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ import org.junit.Ignore
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.RuleChain
|
||||
import org.junit.rules.ExpectedException
|
||||
|
||||
import util.BasePiperTest
|
||||
import util.JenkinsReadYamlRule
|
||||
@ -16,12 +17,14 @@ class TestsPublishResultsTest extends BasePiperTest {
|
||||
Map publisherStepOptions
|
||||
List archiveStepPatterns
|
||||
|
||||
private ExpectedException thrown = ExpectedException.none()
|
||||
private JenkinsStepRule stepRule = new JenkinsStepRule(this)
|
||||
|
||||
@Rule
|
||||
public RuleChain ruleChain = Rules
|
||||
.getCommonRules(this)
|
||||
.around(new JenkinsReadYamlRule(this))
|
||||
.around(thrown)
|
||||
.around(stepRule)
|
||||
|
||||
@Before
|
||||
@ -126,4 +129,40 @@ class TestsPublishResultsTest extends BasePiperTest {
|
||||
assertTrue('Cobertura options are not empty', publisherStepOptions.cobertura == null)
|
||||
assertTrue('JMeter options are not empty', publisherStepOptions.jmeter == null)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testBuildResultStatus() throws Exception {
|
||||
stepRule.step.testsPublishResults(script: nullScript)
|
||||
assertJobStatusSuccess()
|
||||
}
|
||||
|
||||
@Test
|
||||
void testBuildWithTestFailuresAndWithoutFailOnError() throws Exception {
|
||||
nullScript.currentBuild.getRawBuild = {
|
||||
return [getAction: { type ->
|
||||
return [getFailCount: {
|
||||
return 6
|
||||
}]
|
||||
}]
|
||||
}
|
||||
|
||||
stepRule.step.testsPublishResults(script: nullScript)
|
||||
assertJobStatusSuccess()
|
||||
}
|
||||
|
||||
@Test
|
||||
void testBuildWithTestFailuresAndWithFailOnError() throws Exception {
|
||||
nullScript.currentBuild.getRawBuild = {
|
||||
return [getAction: { type ->
|
||||
return [getFailCount: {
|
||||
return 6
|
||||
}]
|
||||
}]
|
||||
}
|
||||
|
||||
thrown.expect(hudson.AbortException)
|
||||
thrown.expectMessage('[testsPublishResults] Some tests failed!')
|
||||
|
||||
stepRule.step.testsPublishResults(script: nullScript, failOnError: true)
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
#!groovy
|
||||
package steps
|
||||
|
||||
import static org.hamcrest.Matchers.*
|
||||
|
||||
|
394
test/groovy/templates/PiperInitRunStageConfigurationTest.groovy
Normal file
394
test/groovy/templates/PiperInitRunStageConfigurationTest.groovy
Normal file
@ -0,0 +1,394 @@
|
||||
#!groovy
|
||||
package templates
|
||||
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.ExpectedException
|
||||
import org.junit.rules.RuleChain
|
||||
import util.BasePiperTest
|
||||
import util.JenkinsLoggingRule
|
||||
import util.JenkinsReadYamlRule
|
||||
import util.JenkinsStepRule
|
||||
import util.Rules
|
||||
|
||||
import static org.hamcrest.Matchers.*
|
||||
import static org.junit.Assert.assertThat
|
||||
|
||||
class PiperInitRunStageConfigurationTest extends BasePiperTest {
|
||||
private JenkinsStepRule jsr = new JenkinsStepRule(this)
|
||||
private JenkinsLoggingRule jlr = new JenkinsLoggingRule(this)
|
||||
private JenkinsReadYamlRule jryr = new JenkinsReadYamlRule(this)
|
||||
private ExpectedException thrown = new ExpectedException()
|
||||
|
||||
@Rule
|
||||
public RuleChain rules = Rules
|
||||
.getCommonRules(this)
|
||||
.around(jryr)
|
||||
.around(thrown)
|
||||
.around(jlr)
|
||||
.around(jsr)
|
||||
|
||||
@Before
|
||||
void init() {
|
||||
|
||||
binding.variables.env.STAGE_NAME = 'Test'
|
||||
|
||||
helper.registerAllowedMethod("findFiles", [Map.class], { map ->
|
||||
switch (map.glob) {
|
||||
case '**/conf.js':
|
||||
return [new File('conf.js')].toArray()
|
||||
case 'myCollection.json':
|
||||
return [new File('myCollection.json')].toArray()
|
||||
default:
|
||||
return [].toArray()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@Test
|
||||
void testStageConfig() {
|
||||
helper.registerAllowedMethod('libraryResource', [String.class], {s ->
|
||||
if(s == 'testDefault.yml') {
|
||||
return '''
|
||||
stages:
|
||||
testStage1: {}
|
||||
testStage2: {}
|
||||
testStage3: {}
|
||||
'''
|
||||
} else {
|
||||
return '''
|
||||
general: {}
|
||||
steps: {}
|
||||
'''
|
||||
}
|
||||
})
|
||||
|
||||
nullScript.commonPipelineEnvironment.configuration = [
|
||||
stages: [
|
||||
testStage2: [testStage: 'myVal2'],
|
||||
testStage3: [testStage: 'myVal3']
|
||||
]
|
||||
]
|
||||
|
||||
jsr.step.piperInitRunStageConfiguration(
|
||||
script: nullScript,
|
||||
juStabUtils: utils,
|
||||
stageConfigResource: 'testDefault.yml'
|
||||
)
|
||||
|
||||
assertThat(nullScript.commonPipelineEnvironment.configuration.runStage.keySet(),
|
||||
allOf(
|
||||
containsInAnyOrder(
|
||||
'testStage2',
|
||||
'testStage3'
|
||||
),
|
||||
hasSize(2)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testConditionConfig() {
|
||||
helper.registerAllowedMethod('libraryResource', [String.class], {s ->
|
||||
if(s == 'testDefault.yml') {
|
||||
return '''
|
||||
stages:
|
||||
testStage1:
|
||||
stepConditions:
|
||||
firstStep:
|
||||
config: testGeneral
|
||||
testStage2:
|
||||
stepConditions:
|
||||
secondStep:
|
||||
config: testStage
|
||||
testStage3:
|
||||
stepConditions:
|
||||
thirdStep:
|
||||
config: testStep
|
||||
|
||||
'''
|
||||
} else {
|
||||
return '''
|
||||
general: {}
|
||||
steps: {}
|
||||
'''
|
||||
}
|
||||
})
|
||||
|
||||
nullScript.commonPipelineEnvironment.configuration = [
|
||||
general: [testGeneral: 'myVal1'],
|
||||
stages: [testStage2: [testStage: 'myVal2']],
|
||||
steps: [thirdStep: [testStep: 'myVal3']]
|
||||
]
|
||||
|
||||
jsr.step.piperInitRunStageConfiguration(
|
||||
script: nullScript,
|
||||
juStabUtils: utils,
|
||||
stageConfigResource: 'testDefault.yml'
|
||||
)
|
||||
|
||||
assertThat(nullScript.commonPipelineEnvironment.configuration.runStage.keySet(),
|
||||
allOf(
|
||||
containsInAnyOrder(
|
||||
'testStage1',
|
||||
'testStage2',
|
||||
'testStage3'
|
||||
),
|
||||
hasSize(3)
|
||||
)
|
||||
)
|
||||
|
||||
assertThat(nullScript.commonPipelineEnvironment.configuration.runStep.testStage1.firstStep, is(true))
|
||||
assertThat(nullScript.commonPipelineEnvironment.configuration.runStep.testStage2.secondStep, is(true))
|
||||
assertThat(nullScript.commonPipelineEnvironment.configuration.runStep.testStage3.thirdStep, is(true))
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testConditionConfigValue() {
|
||||
helper.registerAllowedMethod('libraryResource', [String.class], {s ->
|
||||
if(s == 'testDefault.yml') {
|
||||
return '''
|
||||
stages:
|
||||
testStage1:
|
||||
stepConditions:
|
||||
firstStep:
|
||||
config:
|
||||
testGeneral:
|
||||
- myValx
|
||||
- myVal1
|
||||
testStage2:
|
||||
stepConditions:
|
||||
secondStep:
|
||||
config:
|
||||
testStage:
|
||||
- maValXyz
|
||||
testStage3:
|
||||
stepConditions:
|
||||
thirdStep:
|
||||
config:
|
||||
testStep:
|
||||
- myVal3
|
||||
|
||||
'''
|
||||
} else {
|
||||
return '''
|
||||
general: {}
|
||||
steps: {}
|
||||
'''
|
||||
}
|
||||
})
|
||||
|
||||
nullScript.commonPipelineEnvironment.configuration = [
|
||||
general: [testGeneral: 'myVal1'],
|
||||
stages: [:],
|
||||
steps: [thirdStep: [testStep: 'myVal3']]
|
||||
]
|
||||
|
||||
jsr.step.piperInitRunStageConfiguration(
|
||||
script: nullScript,
|
||||
juStabUtils: utils,
|
||||
stageConfigResource: 'testDefault.yml'
|
||||
)
|
||||
|
||||
assertThat(nullScript.commonPipelineEnvironment.configuration.runStage.keySet(),
|
||||
allOf(
|
||||
containsInAnyOrder(
|
||||
'testStage1',
|
||||
'testStage3'
|
||||
),
|
||||
hasSize(2)
|
||||
)
|
||||
)
|
||||
|
||||
assertThat(nullScript.commonPipelineEnvironment.configuration.runStep.testStage1.firstStep, is(true))
|
||||
assertThat(nullScript.commonPipelineEnvironment.configuration.runStep.testStage2?.secondStep, is(false))
|
||||
assertThat(nullScript.commonPipelineEnvironment.configuration.runStep.testStage3.thirdStep, is(true))
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testConditionFilePattern() {
|
||||
helper.registerAllowedMethod('libraryResource', [String.class], {s ->
|
||||
if(s == 'testDefault.yml') {
|
||||
return '''
|
||||
stages:
|
||||
testStage1:
|
||||
stepConditions:
|
||||
firstStep:
|
||||
filePattern: \'**/conf.js\'
|
||||
secondStep:
|
||||
filePattern: \'**/conf.jsx\'
|
||||
|
||||
'''
|
||||
} else {
|
||||
return '''
|
||||
general: {}
|
||||
steps: {}
|
||||
'''
|
||||
}
|
||||
})
|
||||
|
||||
jsr.step.piperInitRunStageConfiguration(
|
||||
script: nullScript,
|
||||
juStabUtils: utils,
|
||||
stageConfigResource: 'testDefault.yml'
|
||||
)
|
||||
|
||||
assertThat(nullScript.commonPipelineEnvironment.configuration.runStage.keySet(),
|
||||
allOf(
|
||||
contains('testStage1'),
|
||||
hasSize(1)
|
||||
)
|
||||
)
|
||||
|
||||
assertThat(nullScript.commonPipelineEnvironment.configuration.runStep.testStage1.firstStep, is(true))
|
||||
assertThat(nullScript.commonPipelineEnvironment.configuration.runStep.testStage1.secondStep, is(false))
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testConditionFilePatternFromConfig() {
|
||||
helper.registerAllowedMethod('libraryResource', [String.class], {s ->
|
||||
if(s == 'testDefault.yml') {
|
||||
return '''
|
||||
stages:
|
||||
testStage1:
|
||||
stepConditions:
|
||||
firstStep:
|
||||
filePatternFromConfig: myVal1
|
||||
secondStep:
|
||||
filePatternFromConfig: myVal2
|
||||
|
||||
'''
|
||||
} else {
|
||||
return '''
|
||||
general: {}
|
||||
steps: {}
|
||||
'''
|
||||
}
|
||||
})
|
||||
|
||||
nullScript.commonPipelineEnvironment.configuration = [
|
||||
general: [:],
|
||||
stages: [testStage1: [myVal1: '**/conf.js']]
|
||||
]
|
||||
|
||||
jsr.step.piperInitRunStageConfiguration(
|
||||
script: nullScript,
|
||||
juStabUtils: utils,
|
||||
stageConfigResource: 'testDefault.yml'
|
||||
)
|
||||
|
||||
assertThat(nullScript.commonPipelineEnvironment.configuration.runStage.keySet(),
|
||||
allOf(
|
||||
contains('testStage1'),
|
||||
hasSize(1)
|
||||
)
|
||||
)
|
||||
|
||||
assertThat(nullScript.commonPipelineEnvironment.configuration.runStep.testStage1.firstStep, is(true))
|
||||
assertThat(nullScript.commonPipelineEnvironment.configuration.runStep.testStage1.secondStep, is(false))
|
||||
}
|
||||
|
||||
@Test
|
||||
void testVerboseOption() {
|
||||
nullScript.commonPipelineEnvironment.configuration = [
|
||||
general: [verbose: true],
|
||||
steps: [:],
|
||||
stages: [
|
||||
Test: [:],
|
||||
Integration: [test: 'test'],
|
||||
Acceptance: [test: 'test']
|
||||
]
|
||||
]
|
||||
|
||||
jsr.step.piperInitRunStageConfiguration(
|
||||
script: nullScript,
|
||||
juStabUtils: utils,
|
||||
stageConfigResource: 'com.sap.piper/pipeline/stageDefaults.yml'
|
||||
)
|
||||
|
||||
assertThat(jlr.log, allOf(
|
||||
containsString('[piperInitRunStageConfiguration] Debug - Run Stage Configuration:'),
|
||||
containsString('[piperInitRunStageConfiguration] Debug - Run Step Configuration:')
|
||||
))
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPiperInitDefault() {
|
||||
|
||||
helper.registerAllowedMethod("findFiles", [Map.class], { map -> [].toArray() })
|
||||
|
||||
nullScript.commonPipelineEnvironment.configuration = [
|
||||
general: [:],
|
||||
steps: [:],
|
||||
stages: [
|
||||
Test: [:],
|
||||
Integration: [test: 'test'],
|
||||
Acceptance: [test: 'test']
|
||||
]
|
||||
]
|
||||
|
||||
jsr.step.piperInitRunStageConfiguration(
|
||||
script: nullScript,
|
||||
juStabUtils: utils,
|
||||
stageConfigResource: 'com.sap.piper/pipeline/stageDefaults.yml'
|
||||
)
|
||||
|
||||
assertThat(nullScript.commonPipelineEnvironment.configuration.runStage.keySet(),
|
||||
allOf(
|
||||
containsInAnyOrder(
|
||||
'Acceptance',
|
||||
'Integration'
|
||||
),
|
||||
hasSize(2)
|
||||
)
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPiperStepActivation() {
|
||||
|
||||
nullScript.commonPipelineEnvironment.configuration = [
|
||||
general: [:],
|
||||
steps: [
|
||||
cloudFoundryDeploy: [cfSpace: 'myTestSpace'],
|
||||
newmanExecute: [newmanCollection: 'myCollection.json']
|
||||
],
|
||||
stages: [:]
|
||||
]
|
||||
|
||||
jsr.step.piperInitRunStageConfiguration(
|
||||
script: nullScript,
|
||||
juStabUtils: utils,
|
||||
stageConfigResource: 'com.sap.piper/pipeline/stageDefaults.yml'
|
||||
)
|
||||
|
||||
assertThat(nullScript.commonPipelineEnvironment.configuration.runStep.Acceptance.cloudFoundryDeploy, is(true))
|
||||
assertThat(nullScript.commonPipelineEnvironment.configuration.runStep.Acceptance.newmanExecute, is(true))
|
||||
assertThat(nullScript.commonPipelineEnvironment.configuration.runStep.Acceptance.newmanExecute, is(true))
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPiperStepActivationWithStage() {
|
||||
|
||||
nullScript.commonPipelineEnvironment.configuration = [
|
||||
general: [:],
|
||||
steps: [:],
|
||||
stages: [Acceptance: [cfSpace: 'test']]
|
||||
]
|
||||
|
||||
jsr.step.piperInitRunStageConfiguration(
|
||||
script: nullScript,
|
||||
juStabUtils: utils,
|
||||
stageConfigResource: 'com.sap.piper/pipeline/stageDefaults.yml'
|
||||
)
|
||||
assertThat(nullScript.commonPipelineEnvironment.configuration.runStep.Acceptance.cloudFoundryDeploy, is(true))
|
||||
assertThat(nullScript.commonPipelineEnvironment.configuration.runStage.Acceptance, is(true))
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
#!groovy
|
||||
package templates
|
||||
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.RuleChain
|
||||
import util.*
|
||||
|
||||
import static org.hamcrest.Matchers.containsString
|
||||
import static org.junit.Assert.assertThat
|
||||
|
||||
class PiperPipelineStageAcceptanceTest extends BasePiperTest {
|
||||
private JenkinsStepRule jsr = new JenkinsStepRule(this)
|
||||
private JenkinsLoggingRule jlr = new JenkinsLoggingRule(this)
|
||||
|
||||
@Rule
|
||||
public RuleChain rules = Rules
|
||||
.getCommonRules(this)
|
||||
.around(new JenkinsReadYamlRule(this))
|
||||
.around(jlr)
|
||||
.around(jsr)
|
||||
|
||||
@Before
|
||||
void init() {
|
||||
binding.variables.env.STAGE_NAME = 'Acceptance'
|
||||
helper.registerAllowedMethod('piperStageWrapper', [Map.class, Closure.class], {m, body ->
|
||||
return body()
|
||||
})
|
||||
}
|
||||
|
||||
@Test
|
||||
void testStageDefault() {
|
||||
|
||||
jsr.step.piperPipelineStageIntegration(
|
||||
script: nullScript,
|
||||
juStabUtils: utils,
|
||||
)
|
||||
assertThat(jlr.log, containsString('Stage implementation is not provided yet.'))
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
#!groovy
|
||||
package templates
|
||||
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.RuleChain
|
||||
import util.*
|
||||
|
||||
import static org.hamcrest.Matchers.containsString
|
||||
import static org.junit.Assert.assertThat
|
||||
|
||||
class PiperPipelineStageAdditionalUnitTestsTest extends BasePiperTest {
|
||||
private JenkinsStepRule jsr = new JenkinsStepRule(this)
|
||||
private JenkinsLoggingRule jlr = new JenkinsLoggingRule(this)
|
||||
|
||||
@Rule
|
||||
public RuleChain rules = Rules
|
||||
.getCommonRules(this)
|
||||
.around(new JenkinsReadYamlRule(this))
|
||||
.around(jlr)
|
||||
.around(jsr)
|
||||
|
||||
@Before
|
||||
void init() {
|
||||
binding.variables.env.STAGE_NAME = 'Additional Unit Tests'
|
||||
helper.registerAllowedMethod('piperStageWrapper', [Map.class, Closure.class], {m, body ->
|
||||
return body()
|
||||
})
|
||||
}
|
||||
|
||||
@Test
|
||||
void testStageDefault() {
|
||||
|
||||
jsr.step.piperPipelineStageIntegration(
|
||||
script: nullScript,
|
||||
juStabUtils: utils,
|
||||
)
|
||||
assertThat(jlr.log, containsString('Stage implementation is not provided yet.'))
|
||||
|
||||
}
|
||||
}
|
42
test/groovy/templates/PiperPipelineStageBuildTest.groovy
Normal file
42
test/groovy/templates/PiperPipelineStageBuildTest.groovy
Normal file
@ -0,0 +1,42 @@
|
||||
#!groovy
|
||||
package templates
|
||||
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.RuleChain
|
||||
import util.*
|
||||
|
||||
import static org.hamcrest.Matchers.containsString
|
||||
import static org.junit.Assert.assertThat
|
||||
|
||||
class PiperPipelineStageBuildTest extends BasePiperTest {
|
||||
private JenkinsStepRule jsr = new JenkinsStepRule(this)
|
||||
private JenkinsLoggingRule jlr = new JenkinsLoggingRule(this)
|
||||
|
||||
@Rule
|
||||
public RuleChain rules = Rules
|
||||
.getCommonRules(this)
|
||||
.around(new JenkinsReadYamlRule(this))
|
||||
.around(jlr)
|
||||
.around(jsr)
|
||||
|
||||
@Before
|
||||
void init() {
|
||||
binding.variables.env.STAGE_NAME = 'Build'
|
||||
helper.registerAllowedMethod('piperStageWrapper', [Map.class, Closure.class], {m, body ->
|
||||
return body()
|
||||
})
|
||||
}
|
||||
|
||||
@Test
|
||||
void testStageDefault() {
|
||||
|
||||
jsr.step.piperPipelineStageIntegration(
|
||||
script: nullScript,
|
||||
juStabUtils: utils,
|
||||
)
|
||||
assertThat(jlr.log, containsString('Stage implementation is not provided yet.'))
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
#!groovy
|
||||
package templates
|
||||
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.RuleChain
|
||||
import util.*
|
||||
|
||||
import static org.hamcrest.Matchers.containsString
|
||||
import static org.junit.Assert.assertThat
|
||||
|
||||
class PiperPipelineStageComplianceTest extends BasePiperTest {
|
||||
private JenkinsStepRule jsr = new JenkinsStepRule(this)
|
||||
private JenkinsLoggingRule jlr = new JenkinsLoggingRule(this)
|
||||
|
||||
@Rule
|
||||
public RuleChain rules = Rules
|
||||
.getCommonRules(this)
|
||||
.around(new JenkinsReadYamlRule(this))
|
||||
.around(jlr)
|
||||
.around(jsr)
|
||||
|
||||
@Before
|
||||
void init() {
|
||||
binding.variables.env.STAGE_NAME = 'Compliance'
|
||||
helper.registerAllowedMethod('piperStageWrapper', [Map.class, Closure.class], {m, body ->
|
||||
return body()
|
||||
})
|
||||
}
|
||||
|
||||
@Test
|
||||
void testStageDefault() {
|
||||
|
||||
jsr.step.piperPipelineStageIntegration(
|
||||
script: nullScript,
|
||||
juStabUtils: utils,
|
||||
)
|
||||
assertThat(jlr.log, containsString('Stage implementation is not provided yet.'))
|
||||
|
||||
}
|
||||
}
|
151
test/groovy/templates/PiperPipelineStageInitTest.groovy
Normal file
151
test/groovy/templates/PiperPipelineStageInitTest.groovy
Normal file
@ -0,0 +1,151 @@
|
||||
#!groovy
|
||||
package templates
|
||||
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.ExpectedException
|
||||
import org.junit.rules.RuleChain
|
||||
import util.*
|
||||
|
||||
import static org.hamcrest.Matchers.hasItems
|
||||
import static org.hamcrest.Matchers.is
|
||||
import static org.hamcrest.Matchers.isEmptyOrNullString
|
||||
import static org.hamcrest.Matchers.not
|
||||
import static org.junit.Assert.assertThat
|
||||
|
||||
class PiperPipelineStageInitTest extends BasePiperTest {
|
||||
private JenkinsStepRule jsr = new JenkinsStepRule(this)
|
||||
private JenkinsLoggingRule jlr = new JenkinsLoggingRule(this)
|
||||
private ExpectedException thrown = new ExpectedException()
|
||||
|
||||
@Rule
|
||||
public RuleChain rules = Rules
|
||||
.getCommonRules(this)
|
||||
.around(new JenkinsReadYamlRule(this))
|
||||
.around(thrown)
|
||||
.around(jlr)
|
||||
.around(jsr)
|
||||
|
||||
private List stepsCalled = []
|
||||
|
||||
@Before
|
||||
void init() {
|
||||
|
||||
binding.variables.env.STAGE_NAME = 'Init'
|
||||
|
||||
nullScript.commonPipelineEnvironment.configuration = [:]
|
||||
|
||||
helper.registerAllowedMethod("findFiles", [Map.class], { map ->
|
||||
switch (map.glob) {
|
||||
case 'pom.xml':
|
||||
return [new File('pom.xml')].toArray()
|
||||
default:
|
||||
return [].toArray()
|
||||
}
|
||||
})
|
||||
|
||||
helper.registerAllowedMethod('piperStageWrapper', [Map.class, Closure.class], { m, body ->
|
||||
assertThat(m.stageName, is('Init'))
|
||||
return body()
|
||||
})
|
||||
|
||||
helper.registerAllowedMethod('checkout', [Closure.class], { c ->
|
||||
stepsCalled.add('checkout')
|
||||
return [GIT_BRANCH: 'master', GIT_COMMIT: 'testGitCommitId', GIT_URL: 'https://github.com/testOrg/testRepo']
|
||||
})
|
||||
binding.setVariable('scm', {})
|
||||
|
||||
helper.registerAllowedMethod('setupCommonPipelineEnvironment', [Map.class], { m ->
|
||||
stepsCalled.add('setupCommonPipelineEnvironment')
|
||||
})
|
||||
|
||||
helper.registerAllowedMethod('piperInitRunStageConfiguration', [Map.class], { m ->
|
||||
assertThat(m.stageConfigResource, not(isEmptyOrNullString()))
|
||||
stepsCalled.add('piperInitRunStageConfiguration')
|
||||
})
|
||||
|
||||
helper.registerAllowedMethod('artifactSetVersion', [Map.class], { m ->
|
||||
stepsCalled.add('artifactSetVersion')
|
||||
})
|
||||
|
||||
helper.registerAllowedMethod('pipelineStashFilesBeforeBuild', [Map.class], { m ->
|
||||
stepsCalled.add('pipelineStashFilesBeforeBuild')
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInitNoBuildTool() {
|
||||
|
||||
thrown.expectMessage('ERROR - NO VALUE AVAILABLE FOR buildTool')
|
||||
jsr.step.piperPipelineStageInit(
|
||||
script: nullScript,
|
||||
juStabUtils: utils,
|
||||
stashSettings: 'com.sap.piper/pipeline/stashSettings.yml'
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInitBuildToolDoesNotMatchProject() {
|
||||
|
||||
thrown.expectMessage('[piperPipelineStageInit] buildTool configuration \'npm\' does not fit to your project, please set buildTool as genereal setting in your .pipeline/config.yml correctly, see also https://github.wdf.sap.corp/pages/ContinuousDelivery/piper-doc/configuration/')
|
||||
jsr.step.piperPipelineStageInit(
|
||||
script: nullScript,
|
||||
juStabUtils: utils,
|
||||
buildTool: 'npm',
|
||||
stashSettings: 'com.sap.piper/pipeline/stashSettings.yml'
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInitDefault() {
|
||||
|
||||
jsr.step.piperPipelineStageInit(
|
||||
script: nullScript,
|
||||
juStabUtils: utils,
|
||||
buildTool: 'maven',
|
||||
stashSettings: 'com.sap.piper/pipeline/stashSettings.yml'
|
||||
)
|
||||
|
||||
assertThat(stepsCalled, hasItems('checkout', 'setupCommonPipelineEnvironment', 'piperInitRunStageConfiguration', 'artifactSetVersion', 'pipelineStashFilesBeforeBuild'))
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInitOverwriteDefault() {
|
||||
|
||||
binding.variables.env.BRANCH_NAME = 'testBranch'
|
||||
|
||||
jsr.step.piperPipelineStageInit(
|
||||
script: nullScript,
|
||||
juStabUtils: utils,
|
||||
buildTool: 'maven',
|
||||
stashSettings: 'com.sap.piper/pipeline/stashSettings.yml'
|
||||
)
|
||||
|
||||
assertThat(stepsCalled, hasItems('checkout', 'setupCommonPipelineEnvironment', 'piperInitRunStageConfiguration', 'pipelineStashFilesBeforeBuild'))
|
||||
assertThat(stepsCalled, not(hasItems('artifactSetVersion')))
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetScmInfoOnCommonPipelineEnvironment() {
|
||||
//currently supported formats
|
||||
def scmInfoTestList = [
|
||||
[GIT_URL: 'https://github.com/testOrg/testRepo.git', expectedSsh: 'git@github.com:testOrg/testRepo.git', expectedHttp: 'https://github.com/testOrg/testRepo.git'],
|
||||
[GIT_URL: 'https://github.com:7777/testOrg/testRepo.git', expectedSsh: 'git@github.com:testOrg/testRepo.git', expectedHttp: 'https://github.com:7777/testOrg/testRepo.git'],
|
||||
[GIT_URL: 'git@github.com:testOrg/testRepo.git', expectedSsh: 'git@github.com:testOrg/testRepo.git', expectedHttp: 'https://github.com/testOrg/testRepo.git'],
|
||||
[GIT_URL: 'ssh://git@github.com/testOrg/testRepo.git', expectedSsh: 'ssh://git@github.com/testOrg/testRepo.git', expectedHttp: 'https://github.com/testOrg/testRepo.git'],
|
||||
[GIT_URL: 'ssh://git@github.com:7777/testOrg/testRepo.git', expectedSsh: 'ssh://git@github.com:7777/testOrg/testRepo.git', expectedHttp: 'https://github.com/testOrg/testRepo.git'],
|
||||
]
|
||||
|
||||
scmInfoTestList.each {scmInfoTest ->
|
||||
jsr.step.piperPipelineStageInit.setScmInfoOnCommonPipelineEnvironment(nullScript, scmInfoTest)
|
||||
assertThat(nullScript.commonPipelineEnvironment.getGitSshUrl(), is(scmInfoTest.expectedSsh))
|
||||
assertThat(nullScript.commonPipelineEnvironment.getGitHttpsUrl(), is(scmInfoTest.expectedHttp))
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
#!groovy
|
||||
package templates
|
||||
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.RuleChain
|
||||
import util.*
|
||||
|
||||
import static org.hamcrest.Matchers.*
|
||||
import static org.junit.Assert.assertThat
|
||||
|
||||
class PiperPipelineStageIntegrationTest extends BasePiperTest {
|
||||
private JenkinsStepRule jsr = new JenkinsStepRule(this)
|
||||
private JenkinsLoggingRule jlr = new JenkinsLoggingRule(this)
|
||||
|
||||
@Rule
|
||||
public RuleChain rules = Rules
|
||||
.getCommonRules(this)
|
||||
.around(new JenkinsReadYamlRule(this))
|
||||
.around(jlr)
|
||||
.around(jsr)
|
||||
|
||||
@Before
|
||||
void init() {
|
||||
binding.variables.env.STAGE_NAME = 'Integration'
|
||||
helper.registerAllowedMethod('piperStageWrapper', [Map.class, Closure.class], {m, body ->
|
||||
return body()
|
||||
})
|
||||
}
|
||||
|
||||
@Test
|
||||
void testStageDefault() {
|
||||
|
||||
jsr.step.piperPipelineStageIntegration(
|
||||
script: nullScript,
|
||||
juStabUtils: utils,
|
||||
)
|
||||
assertThat(jlr.log, containsString('Stage implementation is not provided yet.'))
|
||||
|
||||
}
|
||||
}
|
42
test/groovy/templates/PiperPipelineStagePRVotingTest.groovy
Normal file
42
test/groovy/templates/PiperPipelineStagePRVotingTest.groovy
Normal file
@ -0,0 +1,42 @@
|
||||
#!groovy
|
||||
package templates
|
||||
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.RuleChain
|
||||
import util.*
|
||||
|
||||
import static org.hamcrest.Matchers.containsString
|
||||
import static org.junit.Assert.assertThat
|
||||
|
||||
class PiperPipelineStagePRVotingTest extends BasePiperTest {
|
||||
private JenkinsStepRule jsr = new JenkinsStepRule(this)
|
||||
private JenkinsLoggingRule jlr = new JenkinsLoggingRule(this)
|
||||
|
||||
@Rule
|
||||
public RuleChain rules = Rules
|
||||
.getCommonRules(this)
|
||||
.around(new JenkinsReadYamlRule(this))
|
||||
.around(jlr)
|
||||
.around(jsr)
|
||||
|
||||
@Before
|
||||
void init() {
|
||||
binding.variables.env.STAGE_NAME = 'Pull-Request Voting'
|
||||
helper.registerAllowedMethod('piperStageWrapper', [Map.class, Closure.class], {m, body ->
|
||||
return body()
|
||||
})
|
||||
}
|
||||
|
||||
@Test
|
||||
void testStageDefault() {
|
||||
|
||||
jsr.step.piperPipelineStageIntegration(
|
||||
script: nullScript,
|
||||
juStabUtils: utils,
|
||||
)
|
||||
assertThat(jlr.log, containsString('Stage implementation is not provided yet.'))
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
#!groovy
|
||||
package templates
|
||||
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.RuleChain
|
||||
import util.*
|
||||
|
||||
import static org.hamcrest.Matchers.containsString
|
||||
import static org.junit.Assert.assertThat
|
||||
|
||||
class PiperPipelineStagePerformanceTest extends BasePiperTest {
|
||||
private JenkinsStepRule jsr = new JenkinsStepRule(this)
|
||||
private JenkinsLoggingRule jlr = new JenkinsLoggingRule(this)
|
||||
|
||||
@Rule
|
||||
public RuleChain rules = Rules
|
||||
.getCommonRules(this)
|
||||
.around(new JenkinsReadYamlRule(this))
|
||||
.around(jlr)
|
||||
.around(jsr)
|
||||
|
||||
@Before
|
||||
void init() {
|
||||
binding.variables.env.STAGE_NAME = 'Performance'
|
||||
helper.registerAllowedMethod('piperStageWrapper', [Map.class, Closure.class], {m, body ->
|
||||
return body()
|
||||
})
|
||||
}
|
||||
|
||||
@Test
|
||||
void testStageDefault() {
|
||||
|
||||
jsr.step.piperPipelineStageIntegration(
|
||||
script: nullScript,
|
||||
juStabUtils: utils,
|
||||
)
|
||||
assertThat(jlr.log, containsString('Stage implementation is not provided yet.'))
|
||||
|
||||
}
|
||||
}
|
42
test/groovy/templates/PiperPipelineStagePromoteTest.groovy
Normal file
42
test/groovy/templates/PiperPipelineStagePromoteTest.groovy
Normal file
@ -0,0 +1,42 @@
|
||||
#!groovy
|
||||
package templates
|
||||
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.RuleChain
|
||||
import util.*
|
||||
|
||||
import static org.hamcrest.Matchers.containsString
|
||||
import static org.junit.Assert.assertThat
|
||||
|
||||
class PiperPipelineStagePromoteTest extends BasePiperTest {
|
||||
private JenkinsStepRule jsr = new JenkinsStepRule(this)
|
||||
private JenkinsLoggingRule jlr = new JenkinsLoggingRule(this)
|
||||
|
||||
@Rule
|
||||
public RuleChain rules = Rules
|
||||
.getCommonRules(this)
|
||||
.around(new JenkinsReadYamlRule(this))
|
||||
.around(jlr)
|
||||
.around(jsr)
|
||||
|
||||
@Before
|
||||
void init() {
|
||||
binding.variables.env.STAGE_NAME = 'Promote'
|
||||
helper.registerAllowedMethod('piperStageWrapper', [Map.class, Closure.class], {m, body ->
|
||||
return body()
|
||||
})
|
||||
}
|
||||
|
||||
@Test
|
||||
void testStageDefault() {
|
||||
|
||||
jsr.step.piperPipelineStageIntegration(
|
||||
script: nullScript,
|
||||
juStabUtils: utils,
|
||||
)
|
||||
assertThat(jlr.log, containsString('Stage implementation is not provided yet.'))
|
||||
|
||||
}
|
||||
}
|
42
test/groovy/templates/PiperPipelineStageReleaseTest.groovy
Normal file
42
test/groovy/templates/PiperPipelineStageReleaseTest.groovy
Normal file
@ -0,0 +1,42 @@
|
||||
#!groovy
|
||||
package templates
|
||||
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.RuleChain
|
||||
import util.*
|
||||
|
||||
import static org.hamcrest.Matchers.containsString
|
||||
import static org.junit.Assert.assertThat
|
||||
|
||||
class PiperPipelineStageReleaseTest extends BasePiperTest {
|
||||
private JenkinsStepRule jsr = new JenkinsStepRule(this)
|
||||
private JenkinsLoggingRule jlr = new JenkinsLoggingRule(this)
|
||||
|
||||
@Rule
|
||||
public RuleChain rules = Rules
|
||||
.getCommonRules(this)
|
||||
.around(new JenkinsReadYamlRule(this))
|
||||
.around(jlr)
|
||||
.around(jsr)
|
||||
|
||||
@Before
|
||||
void init() {
|
||||
binding.variables.env.STAGE_NAME = 'Release'
|
||||
helper.registerAllowedMethod('piperStageWrapper', [Map.class, Closure.class], {m, body ->
|
||||
return body()
|
||||
})
|
||||
}
|
||||
|
||||
@Test
|
||||
void testStageDefault() {
|
||||
|
||||
jsr.step.piperPipelineStageIntegration(
|
||||
script: nullScript,
|
||||
juStabUtils: utils,
|
||||
)
|
||||
assertThat(jlr.log, containsString('Stage implementation is not provided yet.'))
|
||||
|
||||
}
|
||||
}
|
42
test/groovy/templates/PiperPipelineStageSecurityTest.groovy
Normal file
42
test/groovy/templates/PiperPipelineStageSecurityTest.groovy
Normal file
@ -0,0 +1,42 @@
|
||||
#!groovy
|
||||
package templates
|
||||
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.RuleChain
|
||||
import util.*
|
||||
|
||||
import static org.hamcrest.Matchers.containsString
|
||||
import static org.junit.Assert.assertThat
|
||||
|
||||
class PiperPipelineStageSecurityTest extends BasePiperTest {
|
||||
private JenkinsStepRule jsr = new JenkinsStepRule(this)
|
||||
private JenkinsLoggingRule jlr = new JenkinsLoggingRule(this)
|
||||
|
||||
@Rule
|
||||
public RuleChain rules = Rules
|
||||
.getCommonRules(this)
|
||||
.around(new JenkinsReadYamlRule(this))
|
||||
.around(jlr)
|
||||
.around(jsr)
|
||||
|
||||
@Before
|
||||
void init() {
|
||||
binding.variables.env.STAGE_NAME = 'Security'
|
||||
helper.registerAllowedMethod('piperStageWrapper', [Map.class, Closure.class], {m, body ->
|
||||
return body()
|
||||
})
|
||||
}
|
||||
|
||||
@Test
|
||||
void testStageDefault() {
|
||||
|
||||
jsr.step.piperPipelineStageIntegration(
|
||||
script: nullScript,
|
||||
juStabUtils: utils,
|
||||
)
|
||||
assertThat(jlr.log, containsString('Stage implementation is not provided yet.'))
|
||||
|
||||
}
|
||||
}
|
233
test/groovy/templates/PiperPipelineTest.groovy
Normal file
233
test/groovy/templates/PiperPipelineTest.groovy
Normal file
@ -0,0 +1,233 @@
|
||||
#!groovy
|
||||
package templates
|
||||
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.RuleChain
|
||||
import util.BasePiperTest
|
||||
import util.JenkinsReadYamlRule
|
||||
import util.JenkinsStepRule
|
||||
import util.PipelineWhenException
|
||||
import util.Rules
|
||||
|
||||
import static org.hamcrest.Matchers.*
|
||||
import static org.junit.Assert.assertThat
|
||||
|
||||
class PiperPipelineTest extends BasePiperTest {
|
||||
private JenkinsStepRule jsr = new JenkinsStepRule(this)
|
||||
|
||||
@Rule
|
||||
public RuleChain rules = Rules
|
||||
.getCommonRules(this)
|
||||
.around(new JenkinsReadYamlRule(this))
|
||||
.around(jsr)
|
||||
|
||||
private skipDefaultCheckout = false
|
||||
private timestamps = false
|
||||
private stagesExecuted = []
|
||||
private stepsCalled = []
|
||||
|
||||
@Before
|
||||
void init() {
|
||||
|
||||
helper.registerAllowedMethod('library', [String.class], null)
|
||||
|
||||
helper.registerAllowedMethod('pipeline', [Closure.class], null)
|
||||
|
||||
helper.registerAllowedMethod('agent', [Closure.class], null)
|
||||
binding.setVariable('any', {})
|
||||
binding.setVariable('none', {})
|
||||
|
||||
helper.registerAllowedMethod('options', [Closure.class], null)
|
||||
|
||||
helper.registerAllowedMethod('skipDefaultCheckout', [], {skipDefaultCheckout = true})
|
||||
helper.registerAllowedMethod('timestamps', [], {timestamps = true})
|
||||
|
||||
helper.registerAllowedMethod('stages', [Closure.class], null)
|
||||
|
||||
helper.registerAllowedMethod('stage', [String.class, Closure.class], {stageName, body ->
|
||||
|
||||
def stageResult
|
||||
|
||||
binding.variables.env.STAGE_NAME = stageName
|
||||
|
||||
helper.registerAllowedMethod('when', [Closure.class], {cWhen ->
|
||||
|
||||
helper.registerAllowedMethod('allOf', [Closure.class], null)
|
||||
|
||||
helper.registerAllowedMethod('anyOf', [Closure.class], {cAnyOf ->
|
||||
def result = false
|
||||
helper.registerAllowedMethod('branch', [String.class], {branchName ->
|
||||
if (!result)
|
||||
result = (branchName == env.BRANCH_NAME)
|
||||
if( !result) {
|
||||
throw new PipelineWhenException("Stage '${stageName}' skipped - expression: '${result}'")
|
||||
}
|
||||
})
|
||||
return cAnyOf()
|
||||
})
|
||||
|
||||
helper.registerAllowedMethod('branch', [String.class], {branchName ->
|
||||
def result = (branchName == env.BRANCH_NAME)
|
||||
if(result == false) {
|
||||
throw new PipelineWhenException("Stage '${stageName}' skipped - expected branch: '${branchName}' while current branch: '${env.BRANCH_NAME}'")
|
||||
}
|
||||
return result
|
||||
})
|
||||
|
||||
helper.registerAllowedMethod('expression', [Closure.class], { Closure cExp ->
|
||||
def result = cExp()
|
||||
if(!result) {
|
||||
throw new PipelineWhenException("Stage '${stageName}' skipped - expression: '${result}'")
|
||||
}
|
||||
return result
|
||||
})
|
||||
return cWhen()
|
||||
})
|
||||
|
||||
// Stage is not executed if build fails or aborts
|
||||
def status = currentBuild.result
|
||||
switch (status) {
|
||||
case 'FAILURE':
|
||||
case 'ABORTED':
|
||||
break
|
||||
default:
|
||||
try {
|
||||
stageResult = body()
|
||||
stagesExecuted.add(stageName)
|
||||
}
|
||||
catch (PipelineWhenException pwe) {
|
||||
//skip stage due to not met when expression
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
return stageResult
|
||||
})
|
||||
|
||||
helper.registerAllowedMethod('steps', [Closure], null)
|
||||
helper.registerAllowedMethod('post', [Closure], null)
|
||||
helper.registerAllowedMethod('always', [Closure], null)
|
||||
|
||||
helper.registerAllowedMethod('input', [Map], {m -> return null})
|
||||
|
||||
helper.registerAllowedMethod('influxWriteData', [Map], {m ->
|
||||
assertThat(m.wrapInNode, is(true))
|
||||
})
|
||||
helper.registerAllowedMethod('mailSendNotification', [Map], {m ->
|
||||
assertThat(m.wrapInNode, is(true))
|
||||
})
|
||||
|
||||
helper.registerAllowedMethod('piperPipelineStageInit', [Map.class], {m ->
|
||||
stepsCalled.add('piperPipelineStageInit')
|
||||
})
|
||||
helper.registerAllowedMethod('piperPipelineStagePRVoting', [Map.class], {m ->
|
||||
stepsCalled.add('piperPipelineStagePRVoting')
|
||||
})
|
||||
helper.registerAllowedMethod('piperPipelineStageBuild', [Map.class], {m ->
|
||||
stepsCalled.add('piperPipelineStageBuild')
|
||||
})
|
||||
helper.registerAllowedMethod('piperPipelineStageAdditionalUnitTests', [Map.class], {m ->
|
||||
stepsCalled.add('piperPipelineStageAdditionalUnitTests')
|
||||
})
|
||||
helper.registerAllowedMethod('piperPipelineStageIntegration', [Map.class], {m ->
|
||||
stepsCalled.add('piperPipelineStageIntegration')
|
||||
})
|
||||
helper.registerAllowedMethod('piperPipelineStageAcceptance', [Map.class], {m ->
|
||||
stepsCalled.add('piperPipelineStageAcceptance')
|
||||
})
|
||||
helper.registerAllowedMethod('piperPipelineStageSecurity', [Map.class], {m ->
|
||||
stepsCalled.add('piperPipelineStageSecurity')
|
||||
})
|
||||
helper.registerAllowedMethod('piperPipelineStagePerformance', [Map.class], {m ->
|
||||
stepsCalled.add('piperPipelineStagePerformance')
|
||||
})
|
||||
helper.registerAllowedMethod('piperPipelineStageCompliance', [Map.class], {m ->
|
||||
stepsCalled.add('piperPipelineStageCompliance')
|
||||
})
|
||||
helper.registerAllowedMethod('input', [Map.class], {m ->
|
||||
stepsCalled.add('input')
|
||||
})
|
||||
helper.registerAllowedMethod('piperPipelineStagePromote', [Map.class], {m ->
|
||||
stepsCalled.add('piperPipelineStagePromote')
|
||||
})
|
||||
helper.registerAllowedMethod('piperPipelineStageRelease', [Map.class], {m ->
|
||||
stepsCalled.add('piperPipelineStageRelease')
|
||||
})
|
||||
|
||||
nullScript.prepareDefaultValues(script: nullScript)
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPRVoting() {
|
||||
|
||||
helper.registerAllowedMethod('piperPipelineStageInit', [Map], null)
|
||||
|
||||
binding.variables.env.BRANCH_NAME = 'PR-*'
|
||||
|
||||
nullScript.commonPipelineEnvironment.configuration = [runStage:[Integration:[test: 'test']]]
|
||||
jsr.step.piperPipeline(script: nullScript)
|
||||
|
||||
assertThat(skipDefaultCheckout, is(true))
|
||||
assertThat(timestamps, is(true))
|
||||
|
||||
assertThat(stagesExecuted.size(), is(2))
|
||||
assertThat(stagesExecuted, allOf(hasItem('Init'), hasItem('Pull-Request Voting')))
|
||||
|
||||
assertThat(stepsCalled, hasItem('piperPipelineStagePRVoting'))
|
||||
}
|
||||
|
||||
@Test
|
||||
void testConfirm() {
|
||||
jsr.step.piperPipeline(script: nullScript)
|
||||
|
||||
assertThat(stepsCalled, hasItem('input'))
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNoConfirm() {
|
||||
nullScript.commonPipelineEnvironment.configuration = [
|
||||
general: [
|
||||
manualConfirmation: false
|
||||
]
|
||||
]
|
||||
jsr.step.piperPipeline(script: nullScript)
|
||||
|
||||
assertThat(stepsCalled, not(hasItem('input')))
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMasterPipelineAllOn() {
|
||||
|
||||
nullScript.commonPipelineEnvironment.configuration.runStage = [
|
||||
Build: true,
|
||||
'Additional Unit Tests': true,
|
||||
Integration: true,
|
||||
Acceptance: true,
|
||||
Security: true,
|
||||
Performance: true,
|
||||
Compliance: true,
|
||||
Promote: true,
|
||||
Release: true
|
||||
]
|
||||
jsr.step.piperPipeline(script: nullScript)
|
||||
|
||||
assertThat(stepsCalled, hasItems(
|
||||
'piperPipelineStageInit',
|
||||
'piperPipelineStageBuild',
|
||||
'piperPipelineStageAdditionalUnitTests',
|
||||
'piperPipelineStageIntegration',
|
||||
'piperPipelineStageAcceptance',
|
||||
'piperPipelineStageSecurity',
|
||||
'piperPipelineStagePerformance',
|
||||
'piperPipelineStageCompliance',
|
||||
'input',
|
||||
'piperPipelineStagePromote',
|
||||
'piperPipelineStageRelease'
|
||||
))
|
||||
}
|
||||
}
|
@ -41,6 +41,7 @@ class JenkinsSetupRule implements TestRule {
|
||||
JOB_NAME : 'p',
|
||||
BUILD_NUMBER: '1',
|
||||
BUILD_URL : 'http://build.url',
|
||||
BRANCH_NAME: 'master'
|
||||
])
|
||||
|
||||
base.evaluate()
|
||||
|
@ -152,11 +152,9 @@ class LibraryLoadingTestExecutionListener extends AbstractTestExecutionListener
|
||||
helper.registerAllowedMethod("node", [String.class, Closure.class], null)
|
||||
helper.registerAllowedMethod("node", [Closure.class], null)
|
||||
helper.registerAllowedMethod( method('sh', Map.class), {m ->
|
||||
println "sh-command: $m.script"
|
||||
return ""
|
||||
} )
|
||||
helper.registerAllowedMethod( method('sh', String.class), {s ->
|
||||
println "sh-command: $s"
|
||||
return ""
|
||||
} )
|
||||
helper.registerAllowedMethod("checkout", [Map.class], null)
|
||||
|
10
test/groovy/util/PipelineWhenException.groovy
Normal file
10
test/groovy/util/PipelineWhenException.groovy
Normal file
@ -0,0 +1,10 @@
|
||||
package util
|
||||
|
||||
import hudson.AbortException
|
||||
|
||||
class PipelineWhenException extends AbortException{
|
||||
public PipelineWhenException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
}
|
@ -37,9 +37,7 @@ void call(Map parameters = [:]) {
|
||||
def utils = parameters.juStabUtils ?: new Utils()
|
||||
def jenkinsUtils = parameters.jenkinsUtilsStub ?: new JenkinsUtils()
|
||||
|
||||
def script = checkScript(this, parameters)
|
||||
if (script == null)
|
||||
script = this
|
||||
final script = checkScript(this, parameters) ?: this
|
||||
|
||||
Map config = ConfigurationHelper.newInstance(this)
|
||||
.loadStepDefaults()
|
||||
@ -123,11 +121,10 @@ void call(Map parameters = [:]) {
|
||||
}
|
||||
|
||||
def findMtar(){
|
||||
def mtarPath = ''
|
||||
def mtarFiles = findFiles(glob: '**/target/*.mtar')
|
||||
def mtarFiles = findFiles(glob: '**/*.mtar')
|
||||
|
||||
if(mtarFiles.length > 1){
|
||||
error 'Found multiple *.mtar files, please specify file via mtaPath parameter! ${mtarFiles}'
|
||||
error "Found multiple *.mtar files, please specify file via mtaPath parameter! ${mtarFiles}"
|
||||
}
|
||||
if(mtarFiles.length == 1){
|
||||
return mtarFiles[0].path
|
||||
|
@ -1,3 +1,6 @@
|
||||
import com.sap.piper.ConfigurationLoader
|
||||
import com.sap.piper.ConfigurationMerger
|
||||
|
||||
class commonPipelineEnvironment implements Serializable {
|
||||
Map configProperties = [:]
|
||||
|
||||
@ -134,4 +137,18 @@ class commonPipelineEnvironment implements Serializable {
|
||||
def getPipelineMeasurement(key) {
|
||||
return influxCustomDataMap.pipeline_data[key]
|
||||
}
|
||||
|
||||
Map getStepConfiguration(stepName, stageName = env.STAGE_NAME, includeDefaults = true) {
|
||||
Map defaults = [:]
|
||||
if (includeDefaults) {
|
||||
defaults = ConfigurationLoader.defaultGeneralConfiguration()
|
||||
defaults = ConfigurationMerger.merge(ConfigurationLoader.defaultStepConfiguration(null, stepName), null, defaults)
|
||||
defaults = ConfigurationMerger.merge(ConfigurationLoader.defaultStageConfiguration(null, stageName), null, defaults)
|
||||
}
|
||||
Map config = ConfigurationMerger.merge(configuration.get('general') ?: [:], null, defaults)
|
||||
config = ConfigurationMerger.merge(configuration.get('steps')?.get(stepName) ?: [:], null, config)
|
||||
config = ConfigurationMerger.merge(configuration.get('stages')?.get(stageName) ?: [:], null, config)
|
||||
return config
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,13 +1,11 @@
|
||||
import static com.sap.piper.Prerequisites.checkScript
|
||||
|
||||
import com.cloudbees.groovy.cps.NonCPS
|
||||
|
||||
import com.sap.piper.ConfigurationHelper
|
||||
import com.sap.piper.GenerateDocumentation
|
||||
import com.sap.piper.JenkinsUtils
|
||||
import com.sap.piper.Utils
|
||||
import com.sap.piper.k8s.ContainerMap
|
||||
|
||||
import groovy.transform.Field
|
||||
|
||||
@Field def STEP_NAME = getClass().getName()
|
||||
@ -57,6 +55,10 @@ import groovy.transform.Field
|
||||
* Volumes that should be mounted into the container.
|
||||
*/
|
||||
'dockerVolumeBind',
|
||||
/**
|
||||
* Set this to 'false' to bypass a docker image pull. Usefull during development process. Allows testing of images which are available in the local registry only.
|
||||
*/
|
||||
'dockerPullImage',
|
||||
/**
|
||||
* Kubernetes only:
|
||||
* Specifies a dedicated user home directory for the container which will be passed as value for environment variable `HOME`.
|
||||
@ -82,6 +84,10 @@ import groovy.transform.Field
|
||||
* as `dockerVolumeBind` for the sidecar container
|
||||
*/
|
||||
'sidecarVolumeBind',
|
||||
/**
|
||||
* Set this to 'false' to bypass a docker image pull. Usefull during development process. Allows testing of images which are available in the local registry only.
|
||||
*/
|
||||
'sidecarPullImage',
|
||||
/**
|
||||
* as `dockerWorkspace` for the sidecar container
|
||||
*/
|
||||
@ -127,6 +133,7 @@ void call(Map parameters = [:], body) {
|
||||
containerCommand: config.containerCommand,
|
||||
containerShell: config.containerShell,
|
||||
dockerImage: config.dockerImage,
|
||||
dockerPullImage: config.dockerPullImage,
|
||||
dockerEnvVars: config.dockerEnvVars,
|
||||
dockerWorkspace: config.dockerWorkspace,
|
||||
stashContent: config.stashContent
|
||||
@ -139,6 +146,7 @@ void call(Map parameters = [:], body) {
|
||||
script: script,
|
||||
containerCommands: [:],
|
||||
containerEnvVars: [:],
|
||||
containerPullImageFlags: [:],
|
||||
containerMap: [:],
|
||||
containerName: config.dockerName,
|
||||
containerPortMappings: [:],
|
||||
@ -150,6 +158,9 @@ void call(Map parameters = [:], body) {
|
||||
paramMap.containerEnvVars[config.dockerImage] = config.dockerEnvVars
|
||||
paramMap.containerEnvVars[config.sidecarImage] = config.sidecarEnvVars
|
||||
|
||||
paramMap.containerPullImageFlags[config.dockerImage] = config.dockerPullImage
|
||||
paramMap.containerPullImageFlags[config.sidecarImage] = config.sidecarPullImage
|
||||
|
||||
paramMap.containerMap[config.dockerImage] = config.dockerName
|
||||
paramMap.containerMap[config.sidecarImage] = config.sidecarName
|
||||
|
||||
@ -179,7 +190,8 @@ void call(Map parameters = [:], body) {
|
||||
if (executeInsideDocker && config.dockerImage) {
|
||||
utils.unstashAll(config.stashContent)
|
||||
def image = docker.image(config.dockerImage)
|
||||
image.pull()
|
||||
if (config.dockerPullImage) image.pull()
|
||||
else echo"[INFO][$STEP_NAME] Skipped pull of image '${config.dockerImage}'."
|
||||
if (!config.sidecarImage) {
|
||||
image.inside(getDockerOptions(config.dockerEnvVars, config.dockerVolumeBind, config.dockerOptions)) {
|
||||
body()
|
||||
@ -189,14 +201,15 @@ void call(Map parameters = [:], body) {
|
||||
sh "docker network create ${networkName}"
|
||||
try{
|
||||
def sidecarImage = docker.image(config.sidecarImage)
|
||||
sidecarImage.pull()
|
||||
if (config.sidecarPullImage) sidecarImage.pull()
|
||||
else echo"[INFO][$STEP_NAME] Skipped pull of image '${config.sidecarImage}'."
|
||||
config.sidecarOptions = config.sidecarOptions?:[]
|
||||
if(config.sidecarName)
|
||||
if (config.sidecarName)
|
||||
config.sidecarOptions.add("--network-alias ${config.sidecarName}")
|
||||
config.sidecarOptions.add("--network ${networkName}")
|
||||
sidecarImage.withRun(getDockerOptions(config.sidecarEnvVars, config.sidecarVolumeBind, config.sidecarOptions)) { c ->
|
||||
config.dockerOptions = config.dockerOptions?:[]
|
||||
if(config.dockerName)
|
||||
if (config.dockerName)
|
||||
config.dockerOptions.add("--network-alias ${config.dockerName}")
|
||||
config.dockerOptions.add("--network ${networkName}")
|
||||
image.inside(getDockerOptions(config.dockerEnvVars, config.dockerVolumeBind, config.dockerOptions)) {
|
||||
|
@ -1,6 +1,7 @@
|
||||
import static com.sap.piper.Prerequisites.checkScript
|
||||
|
||||
import com.sap.piper.ConfigurationHelper
|
||||
import com.sap.piper.GenerateDocumentation
|
||||
import com.sap.piper.JenkinsUtils
|
||||
import com.sap.piper.Utils
|
||||
import com.sap.piper.k8s.SystemEnv
|
||||
@ -9,23 +10,77 @@ import hudson.AbortException
|
||||
|
||||
@Field def STEP_NAME = getClass().getName()
|
||||
@Field def PLUGIN_ID_KUBERNETES = 'kubernetes'
|
||||
|
||||
@Field Set GENERAL_CONFIG_KEYS = [
|
||||
'jenkinsKubernetes'
|
||||
]
|
||||
@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus([
|
||||
'containerCommand', // specify start command for container created with dockerImage parameter to overwrite Piper default (`/usr/bin/tail -f /dev/null`).
|
||||
'containerCommands', //specify start command for containers to overwrite Piper default (`/usr/bin/tail -f /dev/null`). If container's default start command should be used provide empty string like: `['selenium/standalone-chrome': '']`
|
||||
'containerEnvVars', //specify environment variables per container. If not provided dockerEnvVars will be used
|
||||
'containerMap', //specify multiple images which then form a kubernetes pod, example: containerMap: ['maven:3.5-jdk-8-alpine': 'mavenexecute','selenium/standalone-chrome': 'selenium']
|
||||
'containerName', //optional configuration in combination with containerMap to define the container where the commands should be executed in
|
||||
'containerPortMappings', //map which defines per docker image the port mappings, like containerPortMappings: ['selenium/standalone-chrome': [[name: 'selPort', containerPort: 4444, hostPort: 4444]]]
|
||||
'containerShell', // allows to specify the shell to be executed for container with containerName
|
||||
'containerWorkspaces', //specify workspace (=home directory of user) per container. If not provided dockerWorkspace will be used. If empty, home directory will not be set.
|
||||
'dockerImage',
|
||||
'dockerWorkspace',
|
||||
/**
|
||||
* Allows to specify start command for container created with dockerImage parameter to overwrite Piper default (`/usr/bin/tail -f /dev/null`).
|
||||
*/
|
||||
'containerCommand',
|
||||
/**
|
||||
* Specifies start command for containers to overwrite Piper default (`/usr/bin/tail -f /dev/null`).
|
||||
* If container's defaultstart command should be used provide empty string like: `['selenium/standalone-chrome': '']`.
|
||||
*/
|
||||
'containerCommands',
|
||||
/**
|
||||
* Specifies environment variables per container. If not provided `dockerEnvVars` will be used.
|
||||
*/
|
||||
'containerEnvVars',
|
||||
/**
|
||||
* A map of docker image to the name of the container. The pod will be created with all the images from this map and they are labled based on the value field of each map entry.
|
||||
* Example: `['maven:3.5-jdk-8-alpine': 'mavenExecute', 'selenium/standalone-chrome': 'selenium', 'famiko/jmeter-base': 'checkJMeter', 's4sdk/docker-cf-cli': 'cloudfoundry']`
|
||||
*/
|
||||
'containerMap',
|
||||
/**
|
||||
* Optional configuration in combination with containerMap to define the container where the commands should be executed in.
|
||||
*/
|
||||
'containerName',
|
||||
/**
|
||||
* Map which defines per docker image the port mappings, e.g. `containerPortMappings: ['selenium/standalone-chrome': [[name: 'selPort', containerPort: 4444, hostPort: 4444]]]`.
|
||||
*/
|
||||
'containerPortMappings',
|
||||
/**
|
||||
* Specifies the pullImage flag per container.
|
||||
*/
|
||||
'containerPullImageFlags',
|
||||
/**
|
||||
* Allows to specify the shell to be executed for container with containerName.
|
||||
*/
|
||||
'containerShell',
|
||||
/**
|
||||
* Specifies a dedicated user home directory per container which will be passed as value for environment variable `HOME`. If not provided `dockerWorkspace` will be used.
|
||||
*/
|
||||
'containerWorkspaces',
|
||||
/**
|
||||
* Environment variables to set in the container, e.g. [http_proxy:'proxy:8080'].
|
||||
*/
|
||||
'dockerEnvVars',
|
||||
/**
|
||||
* Name of the docker image that should be used. If empty, Docker is not used.
|
||||
*/
|
||||
'dockerImage',
|
||||
/**
|
||||
* Set this to 'false' to bypass a docker image pull.
|
||||
* Usefull during development process. Allows testing of images which are available in the local registry only.
|
||||
*/
|
||||
'dockerPullImage',
|
||||
/**
|
||||
* Specifies a dedicated user home directory for the container which will be passed as value for environment variable `HOME`.
|
||||
*/
|
||||
'dockerWorkspace',
|
||||
/**
|
||||
* Specific stashes that should be considered for the step execution.
|
||||
*/
|
||||
'stashContent',
|
||||
/**
|
||||
*
|
||||
*/
|
||||
'stashExcludes',
|
||||
/**
|
||||
*
|
||||
*/
|
||||
'stashIncludes'
|
||||
])
|
||||
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS.minus([
|
||||
@ -33,6 +88,11 @@ import hudson.AbortException
|
||||
'stashExcludes'
|
||||
])
|
||||
|
||||
/**
|
||||
* Executes a closure inside a container in a kubernetes pod.
|
||||
* Proxy environment variables defined on the Jenkins machine are also available in the container.
|
||||
*/
|
||||
@GenerateDocumentation
|
||||
void call(Map parameters = [:], body) {
|
||||
handlePipelineStepErrors(stepName: STEP_NAME, stepParameters: parameters) {
|
||||
|
||||
@ -140,17 +200,17 @@ private void unstashWorkspace(config, prefix) {
|
||||
}
|
||||
|
||||
private List getContainerList(config) {
|
||||
|
||||
result = []
|
||||
result.push(containerTemplate(
|
||||
name: 'jnlp',
|
||||
image: config.jenkinsKubernetes.jnlpAgent
|
||||
))
|
||||
config.containerMap.each { imageName, containerName ->
|
||||
def containerPullImage = config.containerPullImageFlags?.get(imageName)
|
||||
def templateParameters = [
|
||||
name: containerName.toLowerCase(),
|
||||
image: imageName,
|
||||
alwaysPullImage: true,
|
||||
alwaysPullImage: containerPullImage != null ? containerPullImage : config.dockerPullImage,
|
||||
envVars: getContainerEnvs(config, imageName)
|
||||
]
|
||||
|
||||
@ -173,7 +233,7 @@ private List getContainerList(config) {
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* Returns a list of envVar object consisting of set
|
||||
* environment variables, params (Parametrized Build) and working directory.
|
||||
* (Kubernetes-Plugin only!)
|
||||
|
@ -44,10 +44,7 @@ void call(Map parameters = [:]) {
|
||||
|
||||
dockerExecute(script: script, dockerImage: configuration.dockerImage, dockerOptions: configuration.dockerOptions) {
|
||||
def java = new ToolDescriptor('Java', 'JAVA_HOME', '', '/bin/', 'java', '1.8.0', '-version 2>&1')
|
||||
java.verify(this, configuration)
|
||||
|
||||
def mta = new JavaArchiveDescriptor('SAP Multitarget Application Archive Builder', 'MTA_JAR_LOCATION', 'mtaJarLocation', '1.0.6', '-v', java)
|
||||
mta.verify(this, configuration)
|
||||
|
||||
def mtaYamlName = "mta.yaml"
|
||||
def applicationName = configuration.applicationName
|
||||
|
100
vars/piperInitRunStageConfiguration.groovy
Normal file
100
vars/piperInitRunStageConfiguration.groovy
Normal file
@ -0,0 +1,100 @@
|
||||
import com.sap.piper.ConfigurationLoader
|
||||
|
||||
import static com.sap.piper.Prerequisites.checkScript
|
||||
|
||||
import com.sap.piper.ConfigurationHelper
|
||||
import groovy.transform.Field
|
||||
|
||||
@Field String STEP_NAME = getClass().getName()
|
||||
|
||||
@Field Set GENERAL_CONFIG_KEYS = [
|
||||
/**
|
||||
* Print more detailed information into the log.
|
||||
* @possibleValues `true`, `false`
|
||||
*/
|
||||
'verbose'
|
||||
]
|
||||
|
||||
@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus([
|
||||
/**
|
||||
* Defines the library resource that contains the stage configuration settings
|
||||
*/
|
||||
'stageConfigResource'
|
||||
|
||||
])
|
||||
|
||||
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS
|
||||
|
||||
void call(Map parameters = [:]) {
|
||||
|
||||
def script = checkScript(this, parameters) ?: this
|
||||
def stageName = parameters.stageName?:env.STAGE_NAME
|
||||
|
||||
script.commonPipelineEnvironment.configuration.runStage = [:]
|
||||
script.commonPipelineEnvironment.configuration.runStep = [:]
|
||||
|
||||
// load default & individual configuration
|
||||
Map config = ConfigurationHelper.newInstance(this)
|
||||
.loadStepDefaults()
|
||||
.mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS)
|
||||
.mixinStepConfig(script.commonPipelineEnvironment, STEP_CONFIG_KEYS)
|
||||
.mixinStageConfig(script.commonPipelineEnvironment, stageName, STEP_CONFIG_KEYS)
|
||||
.mixin(parameters, PARAMETER_KEYS)
|
||||
.withMandatoryProperty('stageConfigResource')
|
||||
.use()
|
||||
|
||||
|
||||
config.stages = (readYaml(text: libraryResource(config.stageConfigResource))).stages
|
||||
|
||||
//handling of stage and step activation
|
||||
config.stages.each {stage ->
|
||||
|
||||
//activate stage if stage configuration is available
|
||||
if (ConfigurationLoader.stageConfiguration(script, stage.getKey())) {
|
||||
script.commonPipelineEnvironment.configuration.runStage[stage.getKey()] = true
|
||||
}
|
||||
//-------------------------------------------------------------------------------
|
||||
//detailed handling of step and stage activation based on conditions
|
||||
script.commonPipelineEnvironment.configuration.runStep[stage.getKey()] = [:]
|
||||
def currentStage = stage.getKey()
|
||||
stage.getValue().stepConditions.each {step ->
|
||||
def stepActive = false
|
||||
step.getValue().each {condition ->
|
||||
switch(condition.getKey()) {
|
||||
case 'config':
|
||||
if (condition.getValue() instanceof Map) {
|
||||
condition.getValue().each {configCondition ->
|
||||
if (script.commonPipelineEnvironment.getStepConfiguration(step.getKey(), currentStage)?.get(configCondition.getKey()) in configCondition.getValue()) {
|
||||
stepActive = true
|
||||
}
|
||||
}
|
||||
} else if (script.commonPipelineEnvironment.getStepConfiguration(step.getKey(), currentStage)?.get(condition.getValue())) {
|
||||
stepActive = true
|
||||
}
|
||||
break
|
||||
case 'filePatternFromConfig':
|
||||
def conditionValue=script.commonPipelineEnvironment.getStepConfiguration(step.getKey(), currentStage)?.get(condition.getValue())
|
||||
if (conditionValue && findFiles(glob: conditionValue)) {
|
||||
stepActive = true
|
||||
}
|
||||
break
|
||||
case 'filePattern':
|
||||
if (findFiles(glob: condition.getValue())) {
|
||||
stepActive = true
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
script.commonPipelineEnvironment.configuration.runStep."${stage.getKey()}"."${step.getKey()}" = stepActive
|
||||
|
||||
//make sure that also related stage is activated if steps are active
|
||||
if (stepActive) script.commonPipelineEnvironment.configuration.runStage[stage.getKey()] = true
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (config.verbose) {
|
||||
echo "[${STEP_NAME}] Debug - Run Stage Configuration: ${script.commonPipelineEnvironment.configuration.runStage}"
|
||||
echo "[${STEP_NAME}] Debug - Run Step Configuration: ${script.commonPipelineEnvironment.configuration.runStep}"
|
||||
}
|
||||
}
|
90
vars/piperPipeline.groovy
Normal file
90
vars/piperPipeline.groovy
Normal file
@ -0,0 +1,90 @@
|
||||
void call(parameters) {
|
||||
pipeline {
|
||||
agent none
|
||||
options {
|
||||
skipDefaultCheckout()
|
||||
timestamps()
|
||||
}
|
||||
stages {
|
||||
stage('Init') {
|
||||
steps {
|
||||
library 'piper-lib-os'
|
||||
piperPipelineStageInit script: parameters.script, customDefaults: parameters.customDefaults
|
||||
}
|
||||
}
|
||||
stage('Pull-Request Voting') {
|
||||
when { anyOf { branch 'PR-*'; branch parameters.script.commonPipelineEnvironment.getStepConfiguration('piperPipelineStagePRVoting', 'Pull-Request Voting').customVotingBranch } }
|
||||
steps {
|
||||
piperPipelineStagePRVoting script: parameters.script
|
||||
}
|
||||
}
|
||||
stage('Build') {
|
||||
when {branch parameters.script.commonPipelineEnvironment.getStepConfiguration('', '').productiveBranch}
|
||||
steps {
|
||||
piperPipelineStageBuild script: parameters.script
|
||||
}
|
||||
}
|
||||
stage('Additional Unit Tests') {
|
||||
when {allOf {branch parameters.script.commonPipelineEnvironment.getStepConfiguration('', '').productiveBranch; expression {return parameters.script.commonPipelineEnvironment.configuration.runStage?.get(env.STAGE_NAME)}}}
|
||||
steps {
|
||||
piperPipelineStageAdditionalUnitTests script: parameters.script
|
||||
}
|
||||
}
|
||||
stage('Integration') {
|
||||
when {allOf {branch parameters.script.commonPipelineEnvironment.getStepConfiguration('', '').productiveBranch; expression {return parameters.script.commonPipelineEnvironment.configuration.runStage?.get(env.STAGE_NAME)}}}
|
||||
steps {
|
||||
piperPipelineStageIntegration script: parameters.script
|
||||
}
|
||||
}
|
||||
stage('Acceptance') {
|
||||
when {allOf {branch parameters.script.commonPipelineEnvironment.getStepConfiguration('', '').productiveBranch; expression {return parameters.script.commonPipelineEnvironment.configuration.runStage?.get(env.STAGE_NAME)}}}
|
||||
steps {
|
||||
piperPipelineStageAcceptance script: parameters.script
|
||||
}
|
||||
}
|
||||
stage('Security') {
|
||||
when {allOf {branch parameters.script.commonPipelineEnvironment.getStepConfiguration('', '').productiveBranch; expression {return parameters.script.commonPipelineEnvironment.configuration.runStage?.get(env.STAGE_NAME)}}}
|
||||
steps {
|
||||
piperPipelineStageSecurity script: parameters.script
|
||||
}
|
||||
}
|
||||
stage('Performance') {
|
||||
when {allOf {branch parameters.script.commonPipelineEnvironment.getStepConfiguration('', '').productiveBranch; expression {return parameters.script.commonPipelineEnvironment.configuration.runStage?.get(env.STAGE_NAME)}}}
|
||||
steps {
|
||||
piperPipelineStagePerformance script: parameters.script
|
||||
}
|
||||
}
|
||||
stage('Compliance') {
|
||||
when {allOf {branch parameters.script.commonPipelineEnvironment.getStepConfiguration('', '').productiveBranch; expression {return parameters.script.commonPipelineEnvironment.configuration.runStage?.get(env.STAGE_NAME)}}}
|
||||
steps {
|
||||
piperPipelineStageCompliance script: parameters.script
|
||||
}
|
||||
}
|
||||
stage('Confirm') {
|
||||
agent none
|
||||
when {allOf {branch parameters.script.commonPipelineEnvironment.getStepConfiguration('', '').productiveBranch; expression {return parameters.script.commonPipelineEnvironment.getStepConfiguration('piperInitRunStageConfiguration', env.STAGE_NAME).manualConfirmation}}}
|
||||
steps {
|
||||
input message: 'Shall we proceed to promotion & release?'
|
||||
}
|
||||
}
|
||||
stage('Promote') {
|
||||
when { branch parameters.script.commonPipelineEnvironment.getStepConfiguration('', '').productiveBranch}
|
||||
steps {
|
||||
piperPipelineStagePromote script: parameters.script
|
||||
}
|
||||
}
|
||||
stage('Release') {
|
||||
when {allOf {branch parameters.script.commonPipelineEnvironment.getStepConfiguration('', '').productiveBranch; expression {return parameters.script.commonPipelineEnvironment.configuration.runStage?.get(env.STAGE_NAME)}}}
|
||||
steps {
|
||||
piperPipelineStageRelease script: parameters.script
|
||||
}
|
||||
}
|
||||
}
|
||||
post {
|
||||
always {
|
||||
influxWriteData script: parameters.script, wrapInNode: true
|
||||
mailSendNotification script: parameters.script, wrapInNode: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
36
vars/piperPipelineStageAcceptance.groovy
Normal file
36
vars/piperPipelineStageAcceptance.groovy
Normal file
@ -0,0 +1,36 @@
|
||||
import com.sap.piper.ConfigurationHelper
|
||||
import com.sap.piper.Utils
|
||||
import groovy.transform.Field
|
||||
|
||||
import static com.sap.piper.Prerequisites.checkScript
|
||||
|
||||
@Field String STEP_NAME = getClass().getName()
|
||||
|
||||
@Field Set GENERAL_CONFIG_KEYS = []
|
||||
@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus([])
|
||||
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS
|
||||
|
||||
void call(Map parameters = [:]) {
|
||||
|
||||
def script = checkScript(this, parameters) ?: this
|
||||
def utils = parameters.juStabUtils ?: new Utils()
|
||||
|
||||
def stageName = parameters.stageName?:env.STAGE_NAME
|
||||
|
||||
Map config = ConfigurationHelper.newInstance(this)
|
||||
.loadStepDefaults()
|
||||
.mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS)
|
||||
.mixinStageConfig(script.commonPipelineEnvironment, stageName, STEP_CONFIG_KEYS)
|
||||
.mixin(parameters, PARAMETER_KEYS)
|
||||
.use()
|
||||
|
||||
piperStageWrapper (script: script, stageName: stageName) {
|
||||
|
||||
// telemetry reporting
|
||||
utils.pushToSWA([step: STEP_NAME], config)
|
||||
|
||||
//ToDO: provide stage implementation
|
||||
echo "${STEP_NAME}: Stage implementation is not provided yet. You can extend the stage using the provided stage extension mechanism."
|
||||
|
||||
}
|
||||
}
|
36
vars/piperPipelineStageAdditionalUnitTests.groovy
Normal file
36
vars/piperPipelineStageAdditionalUnitTests.groovy
Normal file
@ -0,0 +1,36 @@
|
||||
import com.sap.piper.ConfigurationHelper
|
||||
import com.sap.piper.Utils
|
||||
import groovy.transform.Field
|
||||
|
||||
import static com.sap.piper.Prerequisites.checkScript
|
||||
|
||||
@Field String STEP_NAME = getClass().getName()
|
||||
|
||||
@Field Set GENERAL_CONFIG_KEYS = []
|
||||
@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus([])
|
||||
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS
|
||||
|
||||
void call(Map parameters = [:]) {
|
||||
|
||||
def script = checkScript(this, parameters) ?: this
|
||||
def utils = parameters.juStabUtils ?: new Utils()
|
||||
|
||||
def stageName = parameters.stageName?:env.STAGE_NAME
|
||||
|
||||
Map config = ConfigurationHelper.newInstance(this)
|
||||
.loadStepDefaults()
|
||||
.mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS)
|
||||
.mixinStageConfig(script.commonPipelineEnvironment, stageName, STEP_CONFIG_KEYS)
|
||||
.mixin(parameters, PARAMETER_KEYS)
|
||||
.use()
|
||||
|
||||
piperStageWrapper (script: script, stageName: stageName) {
|
||||
|
||||
// telemetry reporting
|
||||
utils.pushToSWA([step: STEP_NAME], config)
|
||||
|
||||
//ToDO: provide stage implementation
|
||||
echo "${STEP_NAME}: Stage implementation is not provided yet. You can extend the stage using the provided stage extension mechanism."
|
||||
|
||||
}
|
||||
}
|
36
vars/piperPipelineStageBuild.groovy
Normal file
36
vars/piperPipelineStageBuild.groovy
Normal file
@ -0,0 +1,36 @@
|
||||
import com.sap.piper.ConfigurationHelper
|
||||
import com.sap.piper.Utils
|
||||
import groovy.transform.Field
|
||||
|
||||
import static com.sap.piper.Prerequisites.checkScript
|
||||
|
||||
@Field String STEP_NAME = getClass().getName()
|
||||
|
||||
@Field Set GENERAL_CONFIG_KEYS = []
|
||||
@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus([])
|
||||
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS
|
||||
|
||||
void call(Map parameters = [:]) {
|
||||
|
||||
def script = checkScript(this, parameters) ?: this
|
||||
def utils = parameters.juStabUtils ?: new Utils()
|
||||
|
||||
def stageName = parameters.stageName?:env.STAGE_NAME
|
||||
|
||||
Map config = ConfigurationHelper.newInstance(this)
|
||||
.loadStepDefaults()
|
||||
.mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS)
|
||||
.mixinStageConfig(script.commonPipelineEnvironment, stageName, STEP_CONFIG_KEYS)
|
||||
.mixin(parameters, PARAMETER_KEYS)
|
||||
.use()
|
||||
|
||||
piperStageWrapper (script: script, stageName: stageName) {
|
||||
|
||||
// telemetry reporting
|
||||
utils.pushToSWA([step: STEP_NAME], config)
|
||||
|
||||
//ToDO: provide stage implementation
|
||||
echo "${STEP_NAME}: Stage implementation is not provided yet. You can extend the stage using the provided stage extension mechanism."
|
||||
|
||||
}
|
||||
}
|
36
vars/piperPipelineStageCompliance.groovy
Normal file
36
vars/piperPipelineStageCompliance.groovy
Normal file
@ -0,0 +1,36 @@
|
||||
import com.sap.piper.ConfigurationHelper
|
||||
import com.sap.piper.Utils
|
||||
import groovy.transform.Field
|
||||
|
||||
import static com.sap.piper.Prerequisites.checkScript
|
||||
|
||||
@Field String STEP_NAME = getClass().getName()
|
||||
|
||||
@Field Set GENERAL_CONFIG_KEYS = []
|
||||
@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus([])
|
||||
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS
|
||||
|
||||
void call(Map parameters = [:]) {
|
||||
|
||||
def script = checkScript(this, parameters) ?: this
|
||||
def utils = parameters.juStabUtils ?: new Utils()
|
||||
|
||||
def stageName = parameters.stageName?:env.STAGE_NAME
|
||||
|
||||
Map config = ConfigurationHelper.newInstance(this)
|
||||
.loadStepDefaults()
|
||||
.mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS)
|
||||
.mixinStageConfig(script.commonPipelineEnvironment, stageName, STEP_CONFIG_KEYS)
|
||||
.mixin(parameters, PARAMETER_KEYS)
|
||||
.use()
|
||||
|
||||
piperStageWrapper (script: script, stageName: stageName) {
|
||||
|
||||
// telemetry reporting
|
||||
utils.pushToSWA([step: STEP_NAME], config)
|
||||
|
||||
//ToDO: provide stage implementation
|
||||
echo "${STEP_NAME}: Stage implementation is not provided yet. You can extend the stage using the provided stage extension mechanism."
|
||||
|
||||
}
|
||||
}
|
112
vars/piperPipelineStageInit.groovy
Normal file
112
vars/piperPipelineStageInit.groovy
Normal file
@ -0,0 +1,112 @@
|
||||
import com.sap.piper.ConfigurationHelper
|
||||
import com.sap.piper.Utils
|
||||
import groovy.transform.Field
|
||||
|
||||
import static com.sap.piper.Prerequisites.checkScript
|
||||
|
||||
@Field String STEP_NAME = getClass().getName()
|
||||
|
||||
@Field Set GENERAL_CONFIG_KEYS = [
|
||||
'buildTool',
|
||||
'productiveBranch',
|
||||
'stashSettings',
|
||||
'verbose'
|
||||
]
|
||||
@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS
|
||||
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS
|
||||
|
||||
void call(Map parameters = [:]) {
|
||||
|
||||
def script = checkScript(this, parameters) ?: this
|
||||
def utils = parameters.juStabUtils ?: new Utils()
|
||||
|
||||
def stageName = parameters.stageName?:env.STAGE_NAME
|
||||
|
||||
piperStageWrapper (script: script, stageName: stageName, stashContent: [], ordinal: 1) {
|
||||
def scmInfo = checkout scm
|
||||
|
||||
setupCommonPipelineEnvironment script: script, customDefaults: parameters.customDefaults
|
||||
|
||||
Map config = ConfigurationHelper.newInstance(this)
|
||||
.loadStepDefaults()
|
||||
.mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS)
|
||||
.mixinStageConfig(script.commonPipelineEnvironment, stageName, STEP_CONFIG_KEYS)
|
||||
.mixin(parameters, PARAMETER_KEYS)
|
||||
.addIfEmpty('stageConfigResource', 'com.sap.piper/pipeline/stageDefaults.yml')
|
||||
.addIfEmpty('stashSettings', 'com.sap.piper/pipeline/stashSettings.yml')
|
||||
.withMandatoryProperty('buildTool')
|
||||
.use()
|
||||
|
||||
//perform stashing based on libray resource piper-stash-settings.yml if not configured otherwise
|
||||
initStashConfiguration(script, config)
|
||||
|
||||
setScmInfoOnCommonPipelineEnvironment(script, scmInfo)
|
||||
script.commonPipelineEnvironment.setGitCommitId(scmInfo.GIT_COMMIT)
|
||||
|
||||
if (config.verbose) {
|
||||
echo "piper-lib-os configuration: ${script.commonPipelineEnvironment.configuration}"
|
||||
}
|
||||
|
||||
// telemetry reporting
|
||||
utils.pushToSWA([step: STEP_NAME], config)
|
||||
|
||||
checkBuildTool(config)
|
||||
|
||||
piperInitRunStageConfiguration script: script, stageConfigResource: config.stageConfigResource
|
||||
|
||||
if (env.BRANCH_NAME == config.productiveBranch) {
|
||||
artifactSetVersion script: script
|
||||
}
|
||||
|
||||
pipelineStashFilesBeforeBuild script: script
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void checkBuildTool(config) {
|
||||
def buildDescriptorPattern = ''
|
||||
switch (config.buildTool) {
|
||||
case 'maven':
|
||||
buildDescriptorPattern = 'pom.xml'
|
||||
break
|
||||
case 'npm':
|
||||
buildDescriptorPattern = 'package.json'
|
||||
break
|
||||
case 'mta':
|
||||
buildDescriptorPattern = 'mta.yaml'
|
||||
break
|
||||
}
|
||||
if (buildDescriptorPattern && !findFiles(glob: buildDescriptorPattern)) {
|
||||
error "[${STEP_NAME}] buildTool configuration '${config.buildTool}' does not fit to your project, please set buildTool as genereal setting in your .pipeline/config.yml correctly, see also https://github.wdf.sap.corp/pages/ContinuousDelivery/piper-doc/configuration/"
|
||||
}
|
||||
}
|
||||
|
||||
private void initStashConfiguration (script, config) {
|
||||
Map stashConfiguration = readYaml(text: libraryResource(config.stashSettings))
|
||||
echo "Stash config: stashConfiguration"
|
||||
script.commonPipelineEnvironment.configuration.stageStashes = stashConfiguration
|
||||
}
|
||||
|
||||
private void setScmInfoOnCommonPipelineEnvironment(script, scmInfo) {
|
||||
|
||||
def gitUrl = scmInfo.GIT_URL
|
||||
|
||||
if (gitUrl.startsWith('http')) {
|
||||
def httpPattern = /(https?):\/\/([^:\/]+)(?:[:\d\/]*)(.*)/
|
||||
def gitMatcher = gitUrl =~ httpPattern
|
||||
if (!gitMatcher.hasGroup() && gitMatcher.groupCount() != 3) return
|
||||
script.commonPipelineEnvironment.setGitSshUrl("git@${gitMatcher[0][2]}:${gitMatcher[0][3]}")
|
||||
script.commonPipelineEnvironment.setGitHttpsUrl(gitUrl)
|
||||
} else if (gitUrl.startsWith('ssh')) {
|
||||
//(.*)@([^:\/]*)(?:[:\d\/]*)(.*)
|
||||
def httpPattern = /(.*)@([^:\/]*)(?:[:\d\/]*)(.*)/
|
||||
def gitMatcher = gitUrl =~ httpPattern
|
||||
if (!gitMatcher.hasGroup() && gitMatcher.groupCount() != 3) return
|
||||
script.commonPipelineEnvironment.setGitSshUrl(gitUrl)
|
||||
script.commonPipelineEnvironment.setGitHttpsUrl("https://${gitMatcher[0][2]}/${gitMatcher[0][3]}")
|
||||
}
|
||||
else if (gitUrl.indexOf('@') > 0) {
|
||||
script.commonPipelineEnvironment.setGitSshUrl(gitUrl)
|
||||
script.commonPipelineEnvironment.setGitHttpsUrl("https://${(gitUrl.split('@')[1]).replace(':', '/')}")
|
||||
}
|
||||
}
|
36
vars/piperPipelineStageIntegration.groovy
Normal file
36
vars/piperPipelineStageIntegration.groovy
Normal file
@ -0,0 +1,36 @@
|
||||
import com.sap.piper.ConfigurationHelper
|
||||
import com.sap.piper.Utils
|
||||
import groovy.transform.Field
|
||||
|
||||
import static com.sap.piper.Prerequisites.checkScript
|
||||
|
||||
@Field String STEP_NAME = getClass().getName()
|
||||
|
||||
@Field Set GENERAL_CONFIG_KEYS = []
|
||||
@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus([])
|
||||
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS
|
||||
|
||||
void call(Map parameters = [:]) {
|
||||
|
||||
def script = checkScript(this, parameters) ?: this
|
||||
def utils = parameters.juStabUtils ?: new Utils()
|
||||
|
||||
def stageName = parameters.stageName?:env.STAGE_NAME
|
||||
|
||||
Map config = ConfigurationHelper.newInstance(this)
|
||||
.loadStepDefaults()
|
||||
.mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS)
|
||||
.mixinStageConfig(script.commonPipelineEnvironment, stageName, STEP_CONFIG_KEYS)
|
||||
.mixin(parameters, PARAMETER_KEYS)
|
||||
.use()
|
||||
|
||||
piperStageWrapper (script: script, stageName: stageName) {
|
||||
|
||||
// telemetry reporting
|
||||
utils.pushToSWA([step: STEP_NAME], config)
|
||||
|
||||
//ToDO: provide stage implementation
|
||||
echo "${STEP_NAME}: Stage implementation is not provided yet. You can extend the stage using the provided stage extension mechanism."
|
||||
|
||||
}
|
||||
}
|
36
vars/piperPipelineStagePRVoting.groovy
Normal file
36
vars/piperPipelineStagePRVoting.groovy
Normal file
@ -0,0 +1,36 @@
|
||||
import com.sap.piper.ConfigurationHelper
|
||||
import com.sap.piper.Utils
|
||||
import groovy.transform.Field
|
||||
|
||||
import static com.sap.piper.Prerequisites.checkScript
|
||||
|
||||
@Field String STEP_NAME = getClass().getName()
|
||||
|
||||
@Field Set GENERAL_CONFIG_KEYS = []
|
||||
@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus([])
|
||||
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS
|
||||
|
||||
void call(Map parameters = [:]) {
|
||||
|
||||
def script = checkScript(this, parameters) ?: this
|
||||
def utils = parameters.juStabUtils ?: new Utils()
|
||||
|
||||
def stageName = parameters.stageName?:env.STAGE_NAME
|
||||
|
||||
Map config = ConfigurationHelper.newInstance(this)
|
||||
.loadStepDefaults()
|
||||
.mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS)
|
||||
.mixinStageConfig(script.commonPipelineEnvironment, stageName, STEP_CONFIG_KEYS)
|
||||
.mixin(parameters, PARAMETER_KEYS)
|
||||
.use()
|
||||
|
||||
piperStageWrapper (script: script, stageName: stageName) {
|
||||
|
||||
// telemetry reporting
|
||||
utils.pushToSWA([step: STEP_NAME], config)
|
||||
|
||||
//ToDO: provide stage implementation
|
||||
echo "${STEP_NAME}: Stage implementation is not provided yet. You can extend the stage using the provided stage extension mechanism."
|
||||
|
||||
}
|
||||
}
|
36
vars/piperPipelineStagePerformance.groovy
Normal file
36
vars/piperPipelineStagePerformance.groovy
Normal file
@ -0,0 +1,36 @@
|
||||
import com.sap.piper.ConfigurationHelper
|
||||
import com.sap.piper.Utils
|
||||
import groovy.transform.Field
|
||||
|
||||
import static com.sap.piper.Prerequisites.checkScript
|
||||
|
||||
@Field String STEP_NAME = getClass().getName()
|
||||
|
||||
@Field Set GENERAL_CONFIG_KEYS = []
|
||||
@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus([])
|
||||
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS
|
||||
|
||||
void call(Map parameters = [:]) {
|
||||
|
||||
def script = checkScript(this, parameters) ?: this
|
||||
def utils = parameters.juStabUtils ?: new Utils()
|
||||
|
||||
def stageName = parameters.stageName?:env.STAGE_NAME
|
||||
|
||||
Map config = ConfigurationHelper.newInstance(this)
|
||||
.loadStepDefaults()
|
||||
.mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS)
|
||||
.mixinStageConfig(script.commonPipelineEnvironment, stageName, STEP_CONFIG_KEYS)
|
||||
.mixin(parameters, PARAMETER_KEYS)
|
||||
.use()
|
||||
|
||||
piperStageWrapper (script: script, stageName: stageName) {
|
||||
|
||||
// telemetry reporting
|
||||
utils.pushToSWA([step: STEP_NAME], config)
|
||||
|
||||
//ToDO: provide stage implementation
|
||||
echo "${STEP_NAME}: Stage implementation is not provided yet. You can extend the stage using the provided stage extension mechanism."
|
||||
|
||||
}
|
||||
}
|
36
vars/piperPipelineStagePromote.groovy
Normal file
36
vars/piperPipelineStagePromote.groovy
Normal file
@ -0,0 +1,36 @@
|
||||
import com.sap.piper.ConfigurationHelper
|
||||
import com.sap.piper.Utils
|
||||
import groovy.transform.Field
|
||||
|
||||
import static com.sap.piper.Prerequisites.checkScript
|
||||
|
||||
@Field String STEP_NAME = getClass().getName()
|
||||
|
||||
@Field Set GENERAL_CONFIG_KEYS = []
|
||||
@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus([])
|
||||
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS
|
||||
|
||||
void call(Map parameters = [:]) {
|
||||
|
||||
def script = checkScript(this, parameters) ?: this
|
||||
def utils = parameters.juStabUtils ?: new Utils()
|
||||
|
||||
def stageName = parameters.stageName?:env.STAGE_NAME
|
||||
|
||||
Map config = ConfigurationHelper.newInstance(this)
|
||||
.loadStepDefaults()
|
||||
.mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS)
|
||||
.mixinStageConfig(script.commonPipelineEnvironment, stageName, STEP_CONFIG_KEYS)
|
||||
.mixin(parameters, PARAMETER_KEYS)
|
||||
.use()
|
||||
|
||||
piperStageWrapper (script: script, stageName: stageName) {
|
||||
|
||||
// telemetry reporting
|
||||
utils.pushToSWA([step: STEP_NAME], config)
|
||||
|
||||
//ToDO: provide stage implementation
|
||||
echo "${STEP_NAME}: Stage implementation is not provided yet. You can extend the stage using the provided stage extension mechanism."
|
||||
|
||||
}
|
||||
}
|
36
vars/piperPipelineStageRelease.groovy
Normal file
36
vars/piperPipelineStageRelease.groovy
Normal file
@ -0,0 +1,36 @@
|
||||
import com.sap.piper.ConfigurationHelper
|
||||
import com.sap.piper.Utils
|
||||
import groovy.transform.Field
|
||||
|
||||
import static com.sap.piper.Prerequisites.checkScript
|
||||
|
||||
@Field String STEP_NAME = getClass().getName()
|
||||
|
||||
@Field Set GENERAL_CONFIG_KEYS = []
|
||||
@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus([])
|
||||
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS
|
||||
|
||||
void call(Map parameters = [:]) {
|
||||
|
||||
def script = checkScript(this, parameters) ?: this
|
||||
def utils = parameters.juStabUtils ?: new Utils()
|
||||
|
||||
def stageName = parameters.stageName?:env.STAGE_NAME
|
||||
|
||||
Map config = ConfigurationHelper.newInstance(this)
|
||||
.loadStepDefaults()
|
||||
.mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS)
|
||||
.mixinStageConfig(script.commonPipelineEnvironment, stageName, STEP_CONFIG_KEYS)
|
||||
.mixin(parameters, PARAMETER_KEYS)
|
||||
.use()
|
||||
|
||||
piperStageWrapper (script: script, stageName: stageName) {
|
||||
|
||||
// telemetry reporting
|
||||
utils.pushToSWA([step: STEP_NAME], config)
|
||||
|
||||
//ToDO: provide stage implementation
|
||||
echo "${STEP_NAME}: Stage implementation is not provided yet. You can extend the stage using the provided stage extension mechanism."
|
||||
|
||||
}
|
||||
}
|
36
vars/piperPipelineStageSecurity.groovy
Normal file
36
vars/piperPipelineStageSecurity.groovy
Normal file
@ -0,0 +1,36 @@
|
||||
import com.sap.piper.ConfigurationHelper
|
||||
import com.sap.piper.Utils
|
||||
import groovy.transform.Field
|
||||
|
||||
import static com.sap.piper.Prerequisites.checkScript
|
||||
|
||||
@Field String STEP_NAME = getClass().getName()
|
||||
|
||||
@Field Set GENERAL_CONFIG_KEYS = []
|
||||
@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus([])
|
||||
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS
|
||||
|
||||
void call(Map parameters = [:]) {
|
||||
|
||||
def script = checkScript(this, parameters) ?: this
|
||||
def utils = parameters.juStabUtils ?: new Utils()
|
||||
|
||||
def stageName = parameters.stageName?:env.STAGE_NAME
|
||||
|
||||
Map config = ConfigurationHelper.newInstance(this)
|
||||
.loadStepDefaults()
|
||||
.mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS)
|
||||
.mixinStageConfig(script.commonPipelineEnvironment, stageName, STEP_CONFIG_KEYS)
|
||||
.mixin(parameters, PARAMETER_KEYS)
|
||||
.use()
|
||||
|
||||
piperStageWrapper (script: script, stageName: stageName) {
|
||||
|
||||
// telemetry reporting
|
||||
utils.pushToSWA([step: STEP_NAME], config)
|
||||
|
||||
//ToDO: provide stage implementation
|
||||
echo "${STEP_NAME}: Stage implementation is not provided yet. You can extend the stage using the provided stage extension mechanism."
|
||||
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@ import static com.sap.piper.Prerequisites.checkScript
|
||||
import com.cloudbees.groovy.cps.NonCPS
|
||||
|
||||
import com.sap.piper.ConfigurationHelper
|
||||
import com.sap.piper.JenkinsUtils
|
||||
import com.sap.piper.MapUtils
|
||||
import com.sap.piper.Utils
|
||||
import groovy.transform.Field
|
||||
@ -13,7 +14,9 @@ import groovy.transform.Field
|
||||
|
||||
@Field def STEP_NAME = getClass().getName()
|
||||
@Field Set GENERAL_CONFIG_KEYS = TOOLS
|
||||
@Field Set STEP_CONFIG_KEYS = TOOLS
|
||||
@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus([
|
||||
'failOnError'
|
||||
])
|
||||
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS
|
||||
|
||||
/**
|
||||
@ -24,10 +27,7 @@ import groovy.transform.Field
|
||||
*/
|
||||
void call(Map parameters = [:]) {
|
||||
handlePipelineStepErrors (stepName: STEP_NAME, stepParameters: parameters) {
|
||||
|
||||
def script = checkScript(this, parameters)
|
||||
if (script == null)
|
||||
script = this
|
||||
def script = checkScript(this, parameters) ?: this
|
||||
|
||||
prepare(parameters)
|
||||
|
||||
@ -46,13 +46,15 @@ void call(Map parameters = [:]) {
|
||||
stepParam1: parameters?.script == null
|
||||
], configuration)
|
||||
|
||||
// UNIT TESTS
|
||||
publishJUnitReport(configuration.get('junit'))
|
||||
// CODE COVERAGE
|
||||
publishJacocoReport(configuration.get('jacoco'))
|
||||
publishCoberturaReport(configuration.get('cobertura'))
|
||||
// PERFORMANCE
|
||||
publishJMeterReport(configuration.get('jmeter'))
|
||||
|
||||
if (configuration.failOnError && JenkinsUtils.hasTestFailures(script.currentBuild)) {
|
||||
script.currentBuild.result = 'FAILURE'
|
||||
error "[${STEP_NAME}] Some tests failed!"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user