diff --git a/documentation/docs/steps/cloudFoundryDeploy.md b/documentation/docs/steps/cloudFoundryDeploy.md
index 1a80cd61e..aea6e46a8 100644
--- a/documentation/docs/steps/cloudFoundryDeploy.md
+++ b/documentation/docs/steps/cloudFoundryDeploy.md
@@ -1,18 +1,6 @@
-# cloudFoundryDeploy
+# ${docGenStepName}
-## Description
-
-The application will be deployed to a test or production space within Cloud Foundry.
-Deployment can be done
-
-* in a standard way
-* in a zero downtime manner (using a [blue-green deployment approach](https://martinfowler.com/bliki/BlueGreenDeployment.html))
-
-!!! note "Deployment supports multiple deployment tools"
- Currently the following are supported:
-
- * Standard `cf push` and [Bluemix blue-green plugin](https://github.com/bluemixgaragelondon/cf-blue-green-deploy#how-to-use)
- * [MTA CF CLI Plugin](https://github.com/cloudfoundry-incubator/multiapps-cli-plugin)
+## ${docGenDescription}
## Prerequisites
@@ -21,90 +9,9 @@ Deployment can be done

-## Parameters
+## ${docGenParameters}
-| parameter | mandatory | default | possible values |
-| ----------|-----------|---------|-----------------|
-| script | yes | | |
-| cloudFoundry | yes | | |
-| deployTool | no | cf_native | cf_native, mtaDeployPlugin |
-| deployType | no | standard | standard, blue-green |
-| keepOldInstance | no | false | true, false |
-| dockerImage | no | s4sdk/docker-cf-cli | |
-| dockerWorkspace | no | /home/piper | |
-| mtaDeployParameters | | for _deployType:standard_ `-f`
for _deployType:blue-green_ `-f --no-confirm` | |
-| mtaExtensionDescriptor | no | '' | |
-| mtaPath | no | '' | |
-| smokeTestScript | no | blueGreenCheckScript.sh (provided by library).
Can be overwritten using config property 'smokeTestScript' | |
-| smokeTestStatusCode | no | 200 | |
-| stashContent | no | [] | |
-
-* `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 retrieving e.g. configuration parameters.
-* `cloudFoundry` defines a map containing following properties:
- * `apiEndpoint`: Cloud Foundry API endpoint (default: `https://api.cf.eu10.hana.ondemand.com`)
- * `appName`: App name of application to be deployed (optional)
- * `credentialsId`: Credentials to be used for deployment (mandatory)
- * `manifest`: Manifest to be used for deployment
- * `org`: Cloud Foundry target organization (mandatory)
- * `space`: Cloud Foundry target space (mandatory)
-
- Example: `cloudFoundry: [apiEndpoint: 'https://test.server.com', appName:'cfAppName', credentialsId: 'cfCredentialsId', manifest: 'cfManifest', org: 'cfOrg', space: 'cfSpace']`
-
-!!! note
- It is also possible to use following configuration parameters instead of `cloudFoundry` map:
-
- - cfApiEndpoint
- - cfAppName
- - cfCredentialsId
- - cfManifest
- - cfOrg
- - cfSpace
-
-!!! note
- Due to [an incompatible change](https://github.com/cloudfoundry/cli/issues/1445) in the Cloud Foundry CLI, multiple buildpacks are not supported by this step.
- If your `application` contains a list of `buildpacks` instead a single `buildpack`, this will be automatically re-written by the step when blue-green deployment is used.
-
-* `deployTool` defines the tool which should be used for deployment.
-* `deployType` defines the type of deployment, either `standard` deployment which results in a system downtime or a zero-downtime `blue-green` deployment.
-* `keepOldInstance` in case of a `blue-green` deployment the old instance will be deleted by default. If this option is set to true the old instance will remain stopped in the Cloud Foundry space.
-* `dockerImage` defines the Docker image containing the deployment tools (like cf cli, ...) and `dockerWorkspace` defines the home directory of the default user of the `dockerImage`
-* `smokeTestScript` allows to specify a script which performs a check during blue-green deployment. The script gets the FQDN as parameter and returns `exit code 0` in case check returned `smokeTestStatusCode`. More details can be found [here](https://github.com/bluemixgaragelondon/cf-blue-green-deploy#how-to-use)
Currently this option is only considered for deployTool `cf_native`.
-* `stashContent` defines the stash names which should be unstashed at the beginning of the step. This makes the files available in case the step is started on an empty node.
-
-### Deployment with cf_native
-
-* `appName` in `cloudFoundry` map (or `cfAppName`) defines the name of the application which will be deployed to the Cloud Foundry space.
-* `manifest` in `cloudFoundry` maps (or `cfManifest`) defines the manifest to be used for Cloud Foundry deployment.
-
-!!! note
- Cloud Foundry supports the deployment of multiple applications using a single manifest file.
- This option is supported with Piper.
-
- In this case define `appName: ''` since the app name for the individual applications have to be defined via the manifest.
- You can find details in the [Cloud Foundry Documentation](https://docs.cloudfoundry.org/devguide/deploy-apps/manifest.html#multi-apps)
-
-### Deployment with mtaDeployPlugin
-
-* `mtaPath` define path to *.mtar for deployment.
-* `mtaExtensionDescriptor` defines additional extension descriptor file for deployment.
-* `mtaDeployParameters` defines additional parameters passed to mta deployment.
-
-## Step configuration
-
-The following parameters can also be specified as step/stage/general parameters using the [global configuration](../configuration.md):
-
-* cloudFoundry
-* deployUser
-* deployTool
-* deployType
-* dockerImage
-* dockerWorkspace
-* mtaDeployParameters
-* mtaExtensionDescriptor
-* mtaPath
-* smokeTestScript
-* smokeTestStatusCode
-* stashContent
+## ${docGenConfiguration}
## Example
diff --git a/test/groovy/CloudFoundryDeployTest.groovy b/test/groovy/CloudFoundryDeployTest.groovy
index beadba16b..deb56fcce 100644
--- a/test/groovy/CloudFoundryDeployTest.groovy
+++ b/test/groovy/CloudFoundryDeployTest.groovy
@@ -96,7 +96,7 @@ class CloudFoundryDeployTest extends BasePiperTest {
stageName: 'acceptance',
])
// asserts
- assertThat(loggingRule.log, containsString('[cloudFoundryDeploy] General parameters: deployTool=, deployType=standard, cfApiEndpoint=https://api.cf.eu10.hana.ondemand.com, cfOrg=testOrg, cfSpace=testSpace, cfCredentialsId=myCreds, deployUser=testUser'))
+ assertThat(loggingRule.log, containsString('[cloudFoundryDeploy] General parameters: deployTool=, deployType=standard, cfApiEndpoint=https://api.cf.eu10.hana.ondemand.com, cfOrg=testOrg, cfSpace=testSpace, cfCredentialsId=myCreds'))
}
@Test
@@ -125,7 +125,7 @@ class CloudFoundryDeployTest extends BasePiperTest {
stageName: 'acceptance'
])
// asserts
- assertThat(loggingRule.log, containsString('[cloudFoundryDeploy] General parameters: deployTool=notAvailable, deployType=standard, cfApiEndpoint=https://api.cf.eu10.hana.ondemand.com, cfOrg=testOrg, cfSpace=testSpace, cfCredentialsId=myCreds, deployUser=testUser'))
+ assertThat(loggingRule.log, containsString('[cloudFoundryDeploy] General parameters: deployTool=notAvailable, deployType=standard, cfApiEndpoint=https://api.cf.eu10.hana.ondemand.com, cfOrg=testOrg, cfSpace=testSpace, cfCredentialsId=myCreds'))
}
@Test
diff --git a/test/groovy/NeoDeployTest.groovy b/test/groovy/NeoDeployTest.groovy
index e25279735..6a0377bf6 100644
--- a/test/groovy/NeoDeployTest.groovy
+++ b/test/groovy/NeoDeployTest.groovy
@@ -6,6 +6,8 @@ import static org.hamcrest.Matchers.containsString
import static org.hamcrest.Matchers.not
import org.hamcrest.Matchers
+import org.hamcrest.BaseMatcher
+import org.hamcrest.Description
import org.jenkinsci.plugins.credentialsbinding.impl.CredentialNotFoundException
import org.junit.Assert
import org.junit.Before
@@ -460,4 +462,57 @@ class NeoDeployTest extends BasePiperTest {
size: 'lite'
])
}
+
+ @Test
+ void dontSwallowExceptionWhenUnableToProvideLogsTest() {
+
+ thrown.expect(AbortException)
+ thrown.expectMessage('Something went wrong during neo deployment')
+ thrown.expect(new BaseMatcher() {
+
+ def expectedException = AbortException
+ def expectedText = 'Cannot provide logs.'
+
+ boolean matches(def ex) {
+ def suppressed = ex.getSuppressed()
+ return (suppressed.size() == 1 &&
+ suppressed[0] in expectedException &&
+ suppressed[0].message == expectedText)
+
+ }
+
+ void describeTo(Description d) {
+ d.appendText(" a suppressed ${expectedException} with message ${expectedText}.")
+ }
+ })
+
+ loggingRule.expect('Unable to provide the logs.')
+
+ helper.registerAllowedMethod('fileExists', [String],
+ { f ->
+ f == 'archive.mtar'
+ }
+ )
+ helper.registerAllowedMethod('sh', [Map],
+ { m ->
+ if(m.script.toString().contains('neo.sh deploy-mta'))
+ throw new AbortException('Something went wrong during neo deployment.')
+ }
+ )
+
+ helper.registerAllowedMethod("sh", [String],
+ { cmd ->
+ if (cmd == 'cat logs/neo/*')
+ throw new AbortException('Cannot provide logs.')
+ }
+ )
+
+ stepRule.step.neoDeploy(script: nullScript,
+
+ source: archiveName,
+ neo:[credentialsId: 'myCredentialsId'],
+ deployMode: 'mta',
+ utils: utils,
+ )
+ }
}
diff --git a/vars/cloudFoundryDeploy.groovy b/vars/cloudFoundryDeploy.groovy
index 5128f6002..af5232fb5 100644
--- a/vars/cloudFoundryDeploy.groovy
+++ b/vars/cloudFoundryDeploy.groovy
@@ -2,6 +2,7 @@ import com.sap.piper.JenkinsUtils
import static com.sap.piper.Prerequisites.checkScript
+import com.sap.piper.GenerateDocumentation
import com.sap.piper.Utils
import com.sap.piper.ConfigurationHelper
import com.sap.piper.CfManifestUtils
@@ -14,22 +15,109 @@ import groovy.transform.Field
@Field Set STEP_CONFIG_KEYS = [
'cloudFoundry',
- 'deployUser',
+ /**
+ * Cloud Foundry API endpoint.
+ * @parentConfigKey cloudFoundry
+ */
+ 'apiEndpoint',
+ /**
+ * Defines the name of the application to be deployed to the Cloud Foundry space.
+ * @parentConfigKey cloudFoundry
+ */
+ 'appName',
+ /**
+ * Credentials to be used for deployment.
+ * @parentConfigKey cloudFoundry
+ */
+ 'credentialsId',
+ /**
+ * Defines the manifest to be used for deployment to Cloud Foundry.
+ * @parentConfigKey cloudFoundry
+ */
+ 'manifest',
+ /**
+ * Cloud Foundry target organization.
+ * @parentConfigKey cloudFoundry
+ */
+ 'org',
+ /**
+ * Cloud Foundry target space.
+ * @parentConfigKey cloudFoundry
+ */
+ 'space',
+ /**
+ * Defines the tool which should be used for deployment.
+ * @possibleValues 'cf_native', 'mtaDeployPlugin'
+ */
'deployTool',
+ /**
+ * Defines the type of deployment, either `standard` deployment which results in a system downtime or a zero-downtime `blue-green` deployment.
+ * @possibleValues 'standard', 'blue-green'
+ */
'deployType',
+ /**
+ * In case of a `blue-green` deployment the old instance will be deleted by default. If this option is set to true the old instance will remain stopped in the Cloud Foundry space.
+ * @possibleValues true, false
+ */
'keepOldInstance',
+ /** @see dockerExecute */
'dockerImage',
+ /** @see dockerExecute */
'dockerWorkspace',
+ /** @see dockerExecute */
+ 'stashContent',
+ /**
+ * Defines additional parameters passed to mta for deployment with the mtaDeployPlugin.
+ */
'mtaDeployParameters',
+ /**
+ * Defines additional extension descriptor file for deployment with the mtaDeployPlugin.
+ */
'mtaExtensionDescriptor',
+ /**
+ * Defines the path to *.mtar for deployment with the mtaDeployPlugin.
+ */
'mtaPath',
+ /**
+ * Allows to specify a script which performs a check during blue-green deployment. The script gets the FQDN as parameter and returns `exit code 0` in case check returned `smokeTestStatusCode`.
+ * More details can be found [here](https://github.com/bluemixgaragelondon/cf-blue-green-deploy#how-to-use)
Currently this option is only considered for deployTool `cf_native`.
+ */
'smokeTestScript',
- 'smokeTestStatusCode',
- 'stashContent']
+ /**
+ * Expected status code returned by the check.
+ */
+ 'smokeTestStatusCode'
+]
+
@Field Map CONFIG_KEY_COMPATIBILITY = [cloudFoundry: [apiEndpoint: 'cfApiEndpoint', appName:'cfAppName', credentialsId: 'cfCredentialsId', manifest: 'cfManifest', org: 'cfOrg', space: 'cfSpace']]
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS
+/**
+ * Deploys an application to a test or production space within Cloud Foundry.
+ * Deployment can be done
+ *
+ * * in a standard way
+ * * in a zero downtime manner (using a [blue-green deployment approach](https://martinfowler.com/bliki/BlueGreenDeployment.html))
+ *
+ * !!! note "Deployment supports multiple deployment tools"
+ * Currently the following are supported:
+ *
+ * * Standard `cf push` and [Bluemix blue-green plugin](https://github.com/bluemixgaragelondon/cf-blue-green-deploy#how-to-use)
+ * * [MTA CF CLI Plugin](https://github.com/cloudfoundry-incubator/multiapps-cli-plugin)
+ *
+ * !!! note
+ * Due to [an incompatible change](https://github.com/cloudfoundry/cli/issues/1445) in the Cloud Foundry CLI, multiple buildpacks are not supported by this step.
+ * If your `application` contains a list of `buildpacks` instead a single `buildpack`, this will be automatically re-written by the step when blue-green deployment is used.
+ *
+ * !!! note
+ * Cloud Foundry supports the deployment of multiple applications using a single manifest file.
+ * This option is supported with Piper.
+ *
+ * In this case define `appName: ''` since the app name for the individual applications have to be defined via the manifest.
+ * You can find details in the [Cloud Foundry Documentation](https://docs.cloudfoundry.org/devguide/deploy-apps/manifest.html#multi-apps)
+ */
+@GenerateDocumentation
void call(Map parameters = [:]) {
handlePipelineStepErrors (stepName: STEP_NAME, stepParameters: parameters) {
@@ -62,7 +150,7 @@ void call(Map parameters = [:]) {
stepParam3: parameters?.script == null
], config)
- echo "[${STEP_NAME}] General parameters: deployTool=${config.deployTool}, deployType=${config.deployType}, cfApiEndpoint=${config.cloudFoundry.apiEndpoint}, cfOrg=${config.cloudFoundry.org}, cfSpace=${config.cloudFoundry.space}, cfCredentialsId=${config.cloudFoundry.credentialsId}, deployUser=${config.deployUser}"
+ echo "[${STEP_NAME}] General parameters: deployTool=${config.deployTool}, deployType=${config.deployType}, cfApiEndpoint=${config.cloudFoundry.apiEndpoint}, cfOrg=${config.cloudFoundry.org}, cfSpace=${config.cloudFoundry.space}, cfCredentialsId=${config.cloudFoundry.credentialsId}"
//make sure that all relevant descriptors, are available in workspace
utils.unstashAll(config.stashContent)
diff --git a/vars/neoDeploy.groovy b/vars/neoDeploy.groovy
index c136fb6ab..a55ff837d 100644
--- a/vars/neoDeploy.groovy
+++ b/vars/neoDeploy.groovy
@@ -150,9 +150,15 @@ private deploy(script, utils, Map configuration, NeoCommandHelper neoCommandHelp
}
}
catch (Exception ex) {
+
if (dockerImage) {
echo "Error while deploying to SAP Cloud Platform. Here are the neo.sh logs:"
- sh "cat logs/neo/*"
+ try {
+ sh "cat logs/neo/*"
+ } catch(Exception e) {
+ echo "Unable to provide the logs."
+ ex.addSuppressed(e)
+ }
}
throw ex
}