mirror of
https://github.com/SAP/jenkins-library.git
synced 2025-01-04 04:07:16 +02:00
New Scenario Step: SAP UI5 on SAP Cloud Platform (#388)
This scenario builds a UI5 app and deploys it to SAP Cloud Platform (neo).
This commit is contained in:
parent
20a54cf094
commit
db5022a4ff
@ -10,7 +10,7 @@ plugins:
|
||||
editorconfig: .editorconfig
|
||||
# https://docs.codeclimate.com/docs/advanced-configuration#section-exclude-patterns
|
||||
exclude_patterns:
|
||||
- "documentation/docs/images/"
|
||||
- "documentation/**/images/"
|
||||
- "cfg/id_rsa.enc"
|
||||
fixme:
|
||||
enabled: true
|
||||
|
87
documentation/docs/scenarios/ui5-sap-cp/Readme.md
Normal file
87
documentation/docs/scenarios/ui5-sap-cp/Readme.md
Normal file
@ -0,0 +1,87 @@
|
||||
# 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.
|
||||
|
||||
|
||||
## Prerequisites
|
||||
|
||||
* 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/).
|
||||
* You have installed the SAP Cloud Platform Neo Environment SDK. See [SAP Development Tools](https://tools.hana.ondemand.com/#cloud).
|
||||
|
||||
|
||||
### 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:
|
||||
|
||||
| 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. |
|
||||
|
||||
|
||||
## 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 pipeline in Jenkins Blue Ocean](images/pipeline.jpg)
|
||||
|
||||
## Example
|
||||
|
||||
### Jenkinsfile
|
||||
|
||||
Following the convention for pipeline definitions, use a `Jenkinsfile` which resides in the root directory of your development sources.
|
||||
|
||||
```groovy
|
||||
@Library('piper-lib-os') _
|
||||
|
||||
fioriOnCloudPlatformPipeline script:this
|
||||
```
|
||||
|
||||
### Configuration (`.pipeline/config.yml`)
|
||||
|
||||
This is a basic configuration example, which is also located in the sources of the project.
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
mtaBuild:
|
||||
buildTarget: 'NEO'
|
||||
mtaJarLocation: '/opt/sap/mta.jar'
|
||||
neoDeploy:
|
||||
neoCredentialsId: 'NEO_DEPLOY'
|
||||
neoHome: '/opt/sap/neo-sdk/'
|
||||
account: 'your-account-id'
|
||||
host: 'hana.ondemand.com'
|
||||
```
|
||||
|
||||
#### Configuration for the MTA Build
|
||||
|
||||
| Parameter | Description |
|
||||
| -----------------|----------------|
|
||||
| `buildTarget` | The target platform to which the mtar can be deployed. Possible values are: `CF`, `NEO`, `XSA` |
|
||||
| `mtaJarLocation` | The location of the multi-target application archive builder jar file, including file name and extension. |
|
||||
|
||||
|
||||
#### Configuration for the Deployment to SAP Cloud Platform
|
||||
|
||||
| Parameter | Description |
|
||||
| -------------------|-------------|
|
||||
| `account` | The SAP Cloud Platform account to deploy to. |
|
||||
| `host` | The SAP Cloud Platform host to deploy to. |
|
||||
| `neoCredentialsId` | The Jenkins credentials that contain the user and password which are used for the deployment on SAP Cloud Platform. |
|
||||
| `neoHome` | The path to the `neo-java-web-sdk` tool that is used for the deployment. |
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
For the detailed description of the relevant parameters, see:
|
||||
|
||||
* [mtaBuild](https://sap.github.io/jenkins-library/steps/mtaBuild/)
|
||||
* [neoDeploy](https://sap.github.io/jenkins-library/steps/neoDeploy/)
|
11
documentation/docs/scenarios/ui5-sap-cp/files/.npmrc
Normal file
11
documentation/docs/scenarios/ui5-sap-cp/files/.npmrc
Normal file
@ -0,0 +1,11 @@
|
||||
# This file can be ommitted in the project if it is ensured
|
||||
# that the corresponding configuration is provided on a
|
||||
# higher level in the npm config (either on user level ~/.npmrc or
|
||||
# globally). For more details with regards to configuring npm check
|
||||
# man pages for npm-config/npmrc
|
||||
|
||||
# The public npm registry from where to fetch e.g. Grunt
|
||||
registry=https://registry.npmjs.org
|
||||
|
||||
# The SAP npm registry from where to fetch SAP specific Grunt modules
|
||||
@sap:registry=https://npm.sap.com
|
10
documentation/docs/scenarios/ui5-sap-cp/files/Gruntfile.js
Normal file
10
documentation/docs/scenarios/ui5-sap-cp/files/Gruntfile.js
Normal file
@ -0,0 +1,10 @@
|
||||
module.exports = function (grunt) {
|
||||
'use strict';
|
||||
grunt.loadNpmTasks('@sap/grunt-sapui5-bestpractice-build');
|
||||
|
||||
grunt.registerTask('default', [
|
||||
'lint',
|
||||
'clean',
|
||||
'build'
|
||||
]);
|
||||
};
|
16
documentation/docs/scenarios/ui5-sap-cp/files/mta.yaml
Normal file
16
documentation/docs/scenarios/ui5-sap-cp/files/mta.yaml
Normal file
@ -0,0 +1,16 @@
|
||||
_schema-version: "2.0.0"
|
||||
ID: "<Id of your MTA>"
|
||||
version: <version number of your application>
|
||||
|
||||
parameters:
|
||||
hcp-deployer-version: "1.0.0"
|
||||
|
||||
modules:
|
||||
- name: "<Name of your Fiori application>"
|
||||
type: html5
|
||||
path: .
|
||||
parameters:
|
||||
version: <version number of your application>-${timestamp}
|
||||
build-parameters:
|
||||
builder: grunt
|
||||
build-result: dist
|
10
documentation/docs/scenarios/ui5-sap-cp/files/package.json
Normal file
10
documentation/docs/scenarios/ui5-sap-cp/files/package.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "<name of the package>",
|
||||
"version": "<version of the package>",
|
||||
"description": "<description of the package>",
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"grunt": "1.0.1",
|
||||
"@sap/grunt-sapui5-bestpractice-build": "1.3.17"
|
||||
}
|
||||
}
|
BIN
documentation/docs/scenarios/ui5-sap-cp/images/pipeline.jpg
Normal file
BIN
documentation/docs/scenarios/ui5-sap-cp/images/pipeline.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
@ -34,6 +34,8 @@ nav:
|
||||
- transportRequestCreate: steps/transportRequestCreate.md
|
||||
- transportRequestRelease: steps/transportRequestRelease.md
|
||||
- transportRequestUploadFile: steps/transportRequestUploadFile.md
|
||||
- 'Scenarios':
|
||||
- 'Fiori (MTA) build and deployment to SAP Cloud Platform': scenarios/ui5-sap-cp/Readme.md
|
||||
- 'Required Plugins': jenkins/requiredPlugins.md
|
||||
|
||||
theme:
|
||||
|
136
test/groovy/FioriOnCloudPlatformPipelineTest.groovy
Normal file
136
test/groovy/FioriOnCloudPlatformPipelineTest.groovy
Normal file
@ -0,0 +1,136 @@
|
||||
import static org.hamcrest.Matchers.allOf
|
||||
import static org.hamcrest.Matchers.containsString
|
||||
import static org.hamcrest.Matchers.equalTo
|
||||
import static org.hamcrest.Matchers.hasItem
|
||||
import static org.hamcrest.Matchers.is
|
||||
import static org.hamcrest.Matchers.subString
|
||||
import static org.junit.Assert.assertThat
|
||||
|
||||
import org.hamcrest.Matchers
|
||||
import org.junit.Assert
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.RuleChain
|
||||
|
||||
import com.sap.piper.JenkinsUtils
|
||||
|
||||
import util.BasePiperTest
|
||||
import util.JenkinsCredentialsRule
|
||||
import util.JenkinsReadYamlRule
|
||||
import util.JenkinsShellCallRule
|
||||
import util.JenkinsStepRule
|
||||
import util.Rules
|
||||
|
||||
class FioriOnCloudPlatformPipelineTest extends BasePiperTest {
|
||||
|
||||
/* This scenario builds a fiori app and deploys it into an neo account.
|
||||
The build is performed using mta, which delegates to grunt. grunt in
|
||||
turn makes use of the 'sap/grunt-sapui5-bestpractice-build' plugin.
|
||||
The dependencies are resolved via npm.
|
||||
|
||||
In order to run the scenario the project needs to fullfill these
|
||||
prerequisites:
|
||||
|
||||
Build tools:
|
||||
* mta.jar available
|
||||
* npm installed
|
||||
|
||||
Project configuration:
|
||||
* sap registry `@sap:registry=https://npm.sap.com` configured in
|
||||
.npmrc (either in the project or on any other suitable level)
|
||||
* dependency to `@sap/grunt-sapui5-bestpractice-build` declared in
|
||||
package.json
|
||||
* npmTask `@sap/grunt-sapui5-bestpractice-build` loaded inside
|
||||
Gruntfile.js and configure default tasks (e.g. lint, clean, build)
|
||||
* mta.yaml
|
||||
*/
|
||||
|
||||
JenkinsStepRule jsr = new JenkinsStepRule(this)
|
||||
JenkinsReadYamlRule jryr = new JenkinsReadYamlRule(this)
|
||||
JenkinsShellCallRule jscr = new JenkinsShellCallRule(this)
|
||||
|
||||
@Rule
|
||||
public RuleChain ruleChain = Rules
|
||||
.getCommonRules(this)
|
||||
.around(jryr)
|
||||
.around(jsr)
|
||||
.around(jscr)
|
||||
.around(new JenkinsCredentialsRule(this)
|
||||
.withCredentials('CI_CREDENTIALS_ID', 'foo', 'terceSpot'))
|
||||
|
||||
@Before
|
||||
void setup() {
|
||||
//
|
||||
// needed since we have dockerExecute inside mtaBuild
|
||||
JenkinsUtils.metaClass.static.isPluginActive = {def s -> false}
|
||||
|
||||
//
|
||||
// Things we validate:
|
||||
jscr.setReturnValue(JenkinsShellCallRule.Type.REGEX, '.*echo \\$JAVA_HOME.*', '/opt/sap/java')
|
||||
jscr.setReturnValue(JenkinsShellCallRule.Type.REGEX, '.*echo \\$MTA_JAR_LOCATION.*', '/opt/sap')
|
||||
jscr.setReturnValue(JenkinsShellCallRule.Type.REGEX, '.*echo \\$NEO_HOME.*', '/opt/sap/neo')
|
||||
jscr.setReturnValue(JenkinsShellCallRule.Type.REGEX, ".*bin/java -version.*", '1.8.0') // the java version
|
||||
jscr.setReturnValue(JenkinsShellCallRule.Type.REGEX, ".*bin/java -jar .*mta.jar", '1.36.0') // the mta version
|
||||
|
||||
//
|
||||
// there is a check for the mta.yaml file and for the deployable test.mtar file
|
||||
helper.registerAllowedMethod('fileExists', [String],{
|
||||
|
||||
it ->
|
||||
|
||||
// called inside mtaBuild, this file contains build config
|
||||
it == 'mta.yaml' ||
|
||||
|
||||
// called inside neo deploy, this file gets deployed
|
||||
it == 'test.mtar'
|
||||
})
|
||||
|
||||
//
|
||||
// the properties below we read out of the yaml file
|
||||
jryr.registerYaml('mta.yaml', ('''
|
||||
|ID : "test"
|
||||
|PATH : "."
|
||||
|''' as CharSequence).stripMargin())
|
||||
|
||||
//
|
||||
// we need the path variable since we extend the path in the mtaBuild step. In order
|
||||
// to be able to extend the path we have to have some initial value.
|
||||
binding.setVariable('PATH', '/usr/bin')
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void straightForwardTest() {
|
||||
|
||||
nullScript
|
||||
.commonPipelineEnvironment
|
||||
.configuration = [steps:
|
||||
[neoDeploy:
|
||||
[ host: 'hana.example.com',
|
||||
account: 'myTestAccount',
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
jsr.step.fioriOnCloudPlatformPipeline(script: nullScript)
|
||||
|
||||
//
|
||||
// the mta build call:
|
||||
assertThat(jscr.shell, hasItem(
|
||||
allOf( containsString('java -jar /opt/sap/mta.jar'),
|
||||
containsString('--mtar test.mtar'),
|
||||
containsString('--build-target=NEO'),
|
||||
containsString('build'))))
|
||||
|
||||
//
|
||||
// the deployable is exchanged between the involved steps via this property:
|
||||
assertThat(nullScript.commonPipelineEnvironment.getMtarFilePath(), is(equalTo('test.mtar')))
|
||||
|
||||
//
|
||||
// the neo deploy call:
|
||||
assertThat(jscr.shell, hasItem('#!/bin/bash "/opt/sap/neo/tools/neo.sh" deploy-mta --source "test.mtar" ' +
|
||||
'--host \'hana.example.com\' --account \'myTestAccount\' --synchronous ' +
|
||||
'--user \'foo\' --password \'terceSpot\''))
|
||||
}
|
||||
}
|
50
vars/fioriOnCloudPlatformPipeline.groovy
Normal file
50
vars/fioriOnCloudPlatformPipeline.groovy
Normal file
@ -0,0 +1,50 @@
|
||||
import static com.sap.piper.Prerequisites.checkScript
|
||||
|
||||
import groovy.transform.Field
|
||||
|
||||
@Field def STEP_NAME = getClass().getName()
|
||||
|
||||
@Field def GENERAL_CONFIG_KEYS = []
|
||||
@Field def PARAMETER_KEYS = []
|
||||
@Field def STEP_CONFIG_KEYS = []
|
||||
|
||||
/** The Scenario is intended for building and uploading a fiori application.
|
||||
*
|
||||
* It needs to be called from a pipeline script (Jenkinsfile) like:
|
||||
* ```
|
||||
* @Library('piper-lib-os') _
|
||||
* @Library('your-additional-lib') __ // optional
|
||||
*
|
||||
* // parameter 'customDefaults' below is optional
|
||||
* fioriOnCloudPlatformPipeline(script: this, customDefaults: '<configFile>')
|
||||
* ```
|
||||
*/
|
||||
void call(parameters = [:]) {
|
||||
|
||||
checkScript(this, parameters)
|
||||
|
||||
node(parameters.label) {
|
||||
|
||||
//
|
||||
// Cut and paste lines below in order to create a pipeline from this scenario
|
||||
// In this case `parameters` needs to be replaced by `script: this`.
|
||||
|
||||
stage('prepare') {
|
||||
|
||||
setupCommonPipelineEnvironment(parameters)
|
||||
}
|
||||
|
||||
stage('build') {
|
||||
|
||||
mtaBuild(parameters)
|
||||
}
|
||||
|
||||
stage('deploy') {
|
||||
|
||||
neoDeploy(parameters)
|
||||
}
|
||||
|
||||
// Cut and paste lines above in order to create a pipeline from this scenario
|
||||
//
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user