1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2024-12-14 11:03:09 +02:00

Merge branch 'master' of https://github.com/weloli/jenkins-library into pr/fixStageDoc

This commit is contained in:
weloli 2019-02-15 09:31:28 +01:00
commit 08edf94bd0
10 changed files with 269 additions and 8 deletions

2
.gitignore vendored
View File

@ -15,3 +15,5 @@ hs_err_pid*
target/
targets/
documentation/docs-gen
consumer-test/workspace

View File

@ -35,7 +35,9 @@ jobs:
cp -r documentation/docs documentation/docs-tmp
documentation/bin/createDocu.sh vars documentation/docs-tmp/steps
docker run --rm -it -v ${TRAVIS_BUILD_DIR}:/docs -w /docs/documentation squidfunk/mkdocs-material:3.0.4 build --clean --verbose --strict
- name: Consumer Tests for s4sdk pipeline
script: cd consumer-test && chmod +x runTests.sh && ./runTests.sh
- stage: Docs
name: Deploy
if: repo = "SAP/jenkins-library" AND branch = master AND NOT type = pull_request

29
consumer-test/jenkins.yml Normal file
View File

@ -0,0 +1,29 @@
jenkins:
numExecutors: 10
unclassified:
globallibraries:
libraries:
- defaultVersion: "master"
name: "s4sdk-pipeline-library"
retriever:
modernSCM:
scm:
git:
remote: "https://github.com/SAP/cloud-s4-sdk-pipeline-lib.git"
- defaultVersion: "master"
name: "piper-library-os"
retriever:
modernSCM:
scm:
git:
remote: "https://github.com/__REPO_SLUG__.git"
credentials:
system:
domainCredentials:
- credentials:
- usernamePassword:
scope: GLOBAL
id: "devops-docker-images-IT-cf"
username: ${CX_INFRA_IT_CF_USERNAME}
password: ${CX_INFRA_IT_CF_PASSWORD}
description: "SAP CP Trail account for test deployment"

14
consumer-test/runTests.sh Executable file
View File

@ -0,0 +1,14 @@
#!/bin/bash -e
LIBRARY_VERSION_UNDER_TEST=$(git log --format="%H" -n 1)
REPOSITORY_UNDER_TEST=${TRAVIS_REPO_SLUG:-SAP/jenkins-library}
rm -rf workspace
git clone -b consumer-test https://github.com/sap/cloud-s4-sdk-book workspace
cp -f jenkins.yml workspace
cd workspace
sed -i -e "s:__REPO_SLUG__:${REPOSITORY_UNDER_TEST}:g" jenkins.yml
echo "@Library(\"piper-library-os@$LIBRARY_VERSION_UNDER_TEST\") _" | cat - Jenkinsfile > temp && mv temp Jenkinsfile
git commit --all --author="piper-testing-bot <null@null.com>" --message="Set piper lib version for test"
docker run -v /var/run/docker.sock:/var/run/docker.sock -v "${PWD}":/workspace -v /tmp -e CASC_JENKINS_CONFIG=/workspace/jenkins.yml -e CX_INFRA_IT_CF_USERNAME -e CX_INFRA_IT_CF_PASSWORD -e BRANCH_NAME=consumer-test ppiper/jenkinsfile-runner

View File

@ -0,0 +1,73 @@
# slackSendNotification
## Description
Sends notifications to the Slack channel about the build status.
Notification contains:
* Build status;
* Repo Owner;
* Repo Name;
* Branch Name;
* Jenkins Build Number;
* Jenkins Build URL.
## Prerequisites
Installed and configured [Jenkins Slack plugin](https://github.com/jenkinsci/slack-plugin).
## Example
Usage of pipeline step:
```groovy
try {
stage('..') {..}
stage('..') {..}
stage('..') {..}
currentBuild.result = 'SUCCESS'
} catch (Throwable err) {
currentBuild.result = 'FAILURE'
throw err
} finally {
stage('report') {
slackSendNotification script: this
}
}
```
## Parameters
| parameter | mandatory | default | possible values |
| ----------|-----------|---------|-----------------|
|script|yes|||
|baseUrl|no|||
|channel|no|||
|color|no|`${buildStatus == 'SUCCESS'?'#008000':'#E60000'}`||
|credentialsId|no|||
|message|no|||
### Details
* `script` defines the global script environment of the Jenkinsfile run. Typically `this` is passed to this parameter. This allows the function to access the [`commonPipelineEnvironment`](commonPipelineEnvironment.md) for storing the measured duration.
* `baseUrl` allows overriding the Slack Plugin Integration Base Url specified in the global configuration.
* `color` defines the message color.
* If `channel` is defined another than the default channel will be used.
* `credentialsId` defines the Jenkins credentialId which holds the Slack token
* With parameter `message` a custom message can be defined which is sent into the Slack channel.
## 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||||
|baseUrl||X|X|
|channel||X|X|
|color||X|X|
|credentialsId||X|X|
|message||X|X|

View File

@ -30,6 +30,7 @@ nav:
- prepareDefaultValues: steps/prepareDefaultValues.md
- seleniumExecuteTests: steps/seleniumExecuteTests.md
- setupCommonPipelineEnvironment: steps/setupCommonPipelineEnvironment.md
- slackSendNotification: steps/slackSendNotification.md
- testsPublishResults: steps/testsPublishResults.md
- toolValidate: steps/toolValidate.md
- transportRequestCreate: steps/transportRequestCreate.md

View File

@ -305,6 +305,9 @@ steps:
dockerImage: 'node:8-stretch'
dockerName: 'npm'
dockerWorkspace: '/home/node'
slackSendNotification:
color: "${buildStatus == 'SUCCESS'?'#008000':'#E60000'}"
defaultMessage: "${buildStatus}: Job ${env.JOB_NAME} <${env.BUILD_URL}|#${env.BUILD_NUMBER}>"
snykExecute:
buildDescriptorFile: './package.json'
dockerImage: 'node:8-stretch'

View File

@ -0,0 +1,88 @@
#!groovy
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.rules.RuleChain
import util.BasePiperTest
import util.JenkinsLoggingRule
import util.JenkinsReadYamlRule
import util.JenkinsStepRule
import util.Rules
import static org.junit.Assert.*
class SlackSendNotificationTest extends BasePiperTest {
def slackCallMap = [:]
private JenkinsLoggingRule loggingRule = new JenkinsLoggingRule(this)
private JenkinsStepRule stepRule = new JenkinsStepRule(this)
@Rule
public RuleChain ruleChain = Rules
.getCommonRules(this)
.around(new JenkinsReadYamlRule(this))
.around(loggingRule)
.around(stepRule)
@Before
void init() throws Exception {
helper.registerAllowedMethod("slackSend", [Map.class], {m -> slackCallMap = m})
}
@Test
void testNotificationBuildSuccessDefaultChannel() throws Exception {
stepRule.step.slackSendNotification(script: [currentBuild: [result: 'SUCCESS']])
// asserts
assertEquals('Message not set correctly', 'SUCCESS: Job p <http://build.url|#1>', slackCallMap.message.toString())
assertNull('Channel not set correctly', slackCallMap.channel)
assertEquals('Color not set correctly', '#008000', slackCallMap.color)
assertJobStatusSuccess()
}
@Test
void testNotificationBuildSuccessCustomChannel() throws Exception {
stepRule.step.slackSendNotification(script: [currentBuild: [result: 'SUCCCESS']], channel: 'Test')
// asserts
assertEquals('Channel not set correctly', 'Test', slackCallMap.channel)
assertJobStatusSuccess()
}
@Test
void testNotificationBuildFailed() throws Exception {
stepRule.step.slackSendNotification(script: [currentBuild: [result: 'FAILURE']])
// asserts
assertEquals('Message not set correctly', 'FAILURE: Job p <http://build.url|#1>', slackCallMap.message.toString())
assertEquals('Color not set correctly', '#E60000', slackCallMap.color)
}
@Test
void testNotificationBuildStatusNull() throws Exception {
stepRule.step.slackSendNotification(script: [currentBuild: [:]])
// asserts
assertTrue('Missing build status not detected', loggingRule.log.contains('currentBuild.result is not set. Skipping Slack notification'))
assertJobStatusSuccess()
}
@Test
void testNotificationCustomMessageAndColor() throws Exception {
stepRule.step.slackSendNotification(script: [currentBuild: [:]], message: 'Custom Message', color: '#AAAAAA')
// asserts
assertEquals('Custom message not set correctly', 'Custom Message', slackCallMap.message.toString())
assertEquals('Custom color not set correctly', '#AAAAAA', slackCallMap.color)
assertJobStatusSuccess()
}
@Test
void testNotificationWithCustomCredentials() throws Exception {
stepRule.step.slackSendNotification(
script: [currentBuild: [:]],
message: 'I am no Message',
baseUrl: 'https://my.base.url',
credentialsId: 'MY_TOKEN_ID'
)
// asserts
assertEquals('Custom base url not set correctly', 'https://my.base.url', slackCallMap.baseUrl)
assertEquals('Custom token id not set correctly', 'MY_TOKEN_ID', slackCallMap.tokenCredentialId)
assertJobStatusSuccess()
}
}

View File

@ -16,17 +16,13 @@ import static com.sap.piper.cm.StepHelpers.getBackendTypeAndLogInfoIfCMIntegrati
@Field def STEP_NAME = getClass().getName()
@Field Set GENERAL_CONFIG_KEYS = STEP_CONFIG_KEYS
@Field Set STEP_CONFIG_KEYS = [
'changeManagement',
@Field Set GENERAL_CONFIG_KEYS = ['changeManagement']
@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus(
/**
* When set to `false` the step will not fail in case the step is not in status 'in development'.
* @possibleValues `true`, `false`
*/
'failIfStatusIsNotInDevelopment'
]
'failIfStatusIsNotInDevelopment')
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS.plus('changeDocumentId')
/**

View File

@ -0,0 +1,53 @@
import static com.sap.piper.Prerequisites.checkScript
import com.sap.piper.ConfigurationHelper
import com.sap.piper.Utils
import groovy.transform.Field
import groovy.text.SimpleTemplateEngine
@Field String STEP_NAME = getClass().getName()
@Field Set GENERAL_CONFIG_KEYS = []
@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus([
'baseUrl',
'channel',
'color',
'credentialsId',
'message'
])
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS
void call(Map parameters = [:]) {
handlePipelineStepErrors (stepName: STEP_NAME, stepParameters: parameters) {
def utils = parameters.juStabUtils ?: new Utils()
def script = checkScript(this, parameters) ?: this
// 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, parameters.stageName?:env.STAGE_NAME, STEP_CONFIG_KEYS)
.mixin(parameters, PARAMETER_KEYS)
.use()
new Utils().pushToSWA([step: STEP_NAME], config)
def buildStatus = script.currentBuild.result
// resolve templates
config.color = SimpleTemplateEngine.newInstance().createTemplate(config.color).make([buildStatus: buildStatus]).toString()
if (!config?.message){
if (!buildStatus) {
echo "[${STEP_NAME}] currentBuild.result is not set. Skipping Slack notification"
return
}
config.message = SimpleTemplateEngine.newInstance().createTemplate(config.defaultMessage).make([buildStatus: buildStatus, env: env]).toString()
}
Map options = [:]
if(config.credentialsId)
options.put('tokenCredentialId', config.credentialsId)
for(String entry : STEP_CONFIG_KEYS.minus('credentialsId'))
if(config.get(entry))
options.put(entry, config.get(entry))
slackSend(options)
}
}