Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
Showing results for 
Search instead for 
Did you mean: 
This blog is part of a series on Continuous Integration with Mobile Services technology. Previous guide: Continuous Integration (CI) Best Practices with SAP: Cloud Platform SDK for Android

In this guide, I am going to show how to leverage SAP Repository-Based Shipment Channel and third-party CI platforms, in this case using the example of Github, to automate custom Fiori Client builds. Many customers today use the Mobile Services Cloud Build feature for that purpose today, but owning the project gives even greater configuration flexibility and it is easier than ever to provide new versions when SAP updates the Mobile Platform SDK. As usual, you can find the examples on Github. Please note that this is not a beginner-friendly guide: The prerequisites I spelled out in the first instalment of this series apply here, too. In addition, I strongly recommend reading the "Workflow Configuration" section, which explains how you obtain and configure the required signing keys for Android project since we are going to build on top of that here.

Important: This version currently only discusses Android Fiori Client builds. It will later be expanded to include instructions for iOS as well, but only after I wrote the corresponding native iOS CI guide. The reason is that as with Android, some aspects of native iOS development pertain to Cordova, too.


The sample project can be found on Github.

Project Configuration

Before we start, I would like to point out two possible approaches to CI with Fiori Client. We can handle its life cycle (i.e. mostly updates provided by SAP) in two ways:

  1. We set up a workflow that generates a completely new Fiori Client project whenever it is being run. The upside is that it is easy to "upgrade" Fiori Client versions when SAP updates the SDK and tools.

  2. We generate a Fiori Client project manually (and, if need be, upgrade manually) and put the project under source control. The upside is that it is easier to perform non-standard customizations (standard meaning just providing documented configuration, non-standard meaning touching code)

The good news is that the required build scripts are mostly the same: Option #2, in fact, requires a mere subset of what we need for #1, so I'll assume that you focus on providing up-to-date Fiori Clients whenever SAP rolls out SDK updates. Essentially, if you want to go from #1 to #2, adjust the build scripts so that the Fiori Client project simply isn't deleted and recreated.

Creating the project itself is fairly straightforward: Simply create a new folder and initiate an npm project in it by running "npm init". You may choose arbitrary values for everything that npm asks you - they aren't relevant. Next, in the new folder, create an ".npmrc" file with the following contents:

This ensures that when npm resolves dependencies for this project, for the "@sap" namespace only, it will refer to this registry instead of the public one. Please refer to this blog to learn how the "SAP_NPM_TOKEN" value can be obtained. As described in the previous guide, instead of hard-coding (and therefore potentially leaking) secrets, we will securely supply them from the build environment later on. For local builds, just configure your desktop environment accordingly and the builds will run locally, too. I recommend you do that now so that it is easier for you to set up and test builds before you run builds in Github.

Next, in "package.json", we add a few dependencies that we require to install the Fiori Client:
"name": "project-name",
"devDependencies": {
"@sap/create_fiori_client": "^4.3.1",
"cordova": "^9.0.0",
"cordova-ios": "^5.0.0",
"rimraf": "^3.0.2"

The first dependency is the command-line tool we require to generate Fiori Client projects. Cordova is added here because I strongly advise avoiding globally installed tools on developer computers: It is just so likely that over time, you'll end up having at least two projects requiring different tool versions. By having the build tools installed with the project build instead, you can fully circumvent this issue. "cordova-ios", on the other hand, is being added because there is an issue with version 5.x that the build will fail when it is not explicitly added to the package.json. Finally, we use "rimraf" (which is what you get when you pronounce the "rm -rf" command) to have a platform-independent way of clearing previous Fiori Client projects. When you are done, run "npm install" to have them downloaded and installed locally.

When you review the "package.json" file in the example project, you'll notice a few build tasks that I have added:
    "fc:configTemplate": "cp ./node_modules/@sap/create_fiori_client/config.json config.template.json",
"fc:appConfigTemplate": "cp ./node_modules/@sap/create_fiori_client/template/www/appConfig.js appConfig.template.js",
"fc:generate": "node ./node_modules/@sap/create_fiori_client/create_fiori_client.js config.json",
"fc:copyAppConfig": "cp -f appConfig.js project/www/appConfig.js",
"cordova:prepare": "cd project && cordova prepare",
"cordova:buildAndroid": "cd project && cordova build android --release",
"cordova:signAndroid": "jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore my-release-key.jks -keypass $ANDROID_KEY_PASSWORD -storepass $ANDROID_STORE_PASSWORD -signedjar project/platforms/android/app/build/outputs/apk/release/app-release.apk project/platforms/android/app/build/outputs/apk/release/app-release-unsigned.apk $ANDROID_KEY_ALIAS"

"fc:configTemplate" is a utility script that will "pull up" the Fiori Client project configuration example from the SAP-provided "create_fiori_client" dependency. It will put it as "config.template.json" in the project root. You should run that command (or otherwise obtain a valid configuration, if you already have one) and put it in the project root, e.g. as "config.json". The "fc:appConfigTemplate" script works similarly, only for the runtime app configuration.

"fc:generate" uses this configuration file to generate a new Fiori Client project. Please note that this command alone will fail if rune multiple times because it refuses to overwrite existing directories.

"fc:copyAppConfig" is meant to be run after "fc:generate" and copies the "appConfig.js" runtime configuration to the cordova project. This step is necessary because we delete the generated Fiori Client between builds and can be omitted otherwise.

"cordova:prepare" ensures that the Cordova project is correctly set up between builds. Most notably, if you decide to put the project under source control (see option #2 above), it is still advisable to remove the "platforms" and "plugins" folder, which are recreated at build time using this command. This should be done because these folders mostly contain binary dependencies, which, if possible, should not be checked in to Git. See the .gitignore file for the corresponding configuration.

"cordova:buildAndroid" and "signAndroid" should look very familiar from what you saw in the previous Android native guide. The main difference is that we used Gradle to sign in one go last time, but in the case of Cordova we need to make a release build and then sign it in an extra step. However, we still require the key store and corresponding secrets. As outlined in the intro, please refer to the Android CI guide to learn how to obtain and configure those values.

Finally, the "build" task is cobbled together from those individual steps:
    // Option #1: Regenerate and rebuild
"build": "rm -rf project && npm run fc:generate && npm run fc:copyAppConfig && npm run cordova:prepare && npm run cordova:buildAndroid",
// Option #2: Build only
"build": "npm run cordova:prepare && npm run cordova:buildAndroid",

And this is really all there is to it: Make sure you run the "fc:configTemplate" and "fc:appConfigTemplate" commands, adjust and rename the files according to your requirements, and you are ready to commit everything and push it to Github.

Workflow Configuration

Please follow the Android guide to learn how to provide the required configuration for "ANDROID_KEY_STORE", "ANDROID_KEY_ALIAS", "ANDROID_KEY_PASSWORD" and "ANDROID_STORE_PASSWORD". By now, you should also already have obtained the value for the "SAP_NPM_TOKEN" variable, so just add this as an additional Github variable next to the others.

When you compare the build workflow file to that of the Android project, you'll notice that it is indeed very similar: The main differences are that we removed the lint and test tasks (Fiori Client doesn't typically have any custom code in it, so there is no point in testing), and that the build and signing tasks have been replaced by invocations of the npm scripts described above.

Next Steps

As with signing and cloud shipment, the notes of the previous guide apply on how to deal with Continuous Delivery. However, there is one more thing I would like to highlight in the context of Fiori Client: As mentioned in the intro, most customers today use Cloud Build to have a low-maintenance way of providing up-to-date custom Fiori Clients to their users. While you can easily update version codes and trigger builds with this pipeline, there is one thing that can make it even easier: Depend-a-bot and the likes. These are crazy useful pieces of software that inspect your project dependencies, occasionally check for updates in linked binary repositories, and create pull requests whenever an update is available. Put differently, you can use these bots to actively notify you whenever there is an update rolled out by us (or anyone else), and keeping up to date with SAP releases boils down to occasionally checking your inbox for new pull requests and pushing the "merge" button on Github. I highly recommend looking into this if you intend going for even more frictionless automation.