Configuration and version management for Ionic apps

Spread the love

A good(and more than often required) software development practice is to always automatically maintain different configurations for development and production. I talked about achieving it here briefly in this blog post where we used environment variables in Ionic to enable or disable error logging.

Some configuration for Ionic and Cordova apps resides in config.xml and we want to separate it for development and production environments. Some examples would be:

  • Different API keys for Development and Production for external services such as google maps
  • Maintaining different names of the app in order to install both Development and production versions of the app
  • Configuration settings for Microsoft Code-Push

Again, there is no built in mechanism which ships with Ionic. In the post below we will see how to maintain configuration for Ionic apps and also do an end to end setup for tasks such as generation of APKs, deploying updates using Microsoft App center.

config.xml version management

We will be using NPM tasks for everything and it seems to work perfectly going forward. We will be adding the below commands to package.json and run them using npm run command. There are other ways to do this, using Task runners such as Grunt. The good thing about this setup: 0 dependencies

First, we create 2 configuration files in config/ folder, dev.xml and prod.xml. We will create tasks to copy the correct config.xml file.

"copy-config:dev": "cp config/dev.xml config.xml",
"copy-config:prod": "cp config/prod.xml config.xml",

Running the app

Now we will simply create more npm commands to Run apps using dev / prod settings.

"dev": "npm run copy-config:dev
        && ionic cordova run android",
"prod": "npm run copy-config:prod
         && ionic cordova run android --prod",

These can be executed for example using npm run dev. Any additional parameters can be added to the command line script using --
Examples:

npm run dev # Start Dev app
npm run dev -- --livereload # Start using livereload

Deploying using Microsoft AppCenter

We use the Microsoft’s Hot code push deployment procedure to deploy live code updates to our customers. It supports 2 environment, a Staging and a Production. Only Production updates are deployed to users running the app built using --prod variable from Ionic.

    "code-push": "code-push release-cordova kunalgrover05/LeanNutri android",
    "deploy-dev": "npm run copy-config:dev && npm run ionic:build && npm run code-push",
    "deploy-prod": "npm run copy-config:prod &&  npm run ionic:build --prod --release && npm run code-push -- -d Production",

Another important aspect when using CodePush is which version do the updates apply to. The default is to just apply updates to the current version. The version can either be set in the AppCenter dashboard or as an additional command line parameter.

For example, to deploy updates for all users with version above 1.0.0:

npm run deploy-prod -- -t ">1.0.0"

Versioning

Let’s go to Version management. This is extremely important for any production app to correctly manage and sync versions of code on Git, APKs delivered to users and the deployments done using Hot code push.

We use a common version in all of our config files, in package.json and also our APKs. We would be using NPM’s versioning which is synced to Git tags. We will need to script up to sync it with APKs and Code push deployments. NPM versions support 3 layers: [MAJOR VERSION].[MINOR VERSION].[PATCH VERSION]

Taking inspiration from this blog post, we will add a script and add it to package.json which will execute it whenever the pre-defined version command is called.

"version": "./change-version.sh"

Here is the file to be executed. It simply changes the version in config.xml, dev.xml and prod.xml whenever npm version is executed.

#!/bin/bash
NEW_VERSION=${npm_package_version}
echo $NEW_VERSION
for CONFIG in config.xml config/dev.xml config/prod.xml;
    do
        echo $CONFIG
        if [ -e $CONFIG ]; then
            # sed to replace version in config.xml
            sed -i "s/\(widget.*version=\"\)\([0-9,.]*\)\"/\1$NEW_VERSION\"/" $CONFIG
            git add $CONFIG
            echo "Updated $CONFIG with version $NEW_VERSION"
        else
            echo 'Could not find config.xml'
            exit 1
        fi
    done;

Building APKs

Finally, some commands to be able to create and package an APK. I have used the $npm_package_version environment variable to be able to define the version in the APK.

"jarsign": "jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore leanagri.keystore platforms/android/app/build/outputs/apk/release/app-release-unsigned.apk leanagri",
"zipalign": "rm -f builds/LeanNutri-$npm_package_version.apk 
             && zipalign -v 4 platforms/android/app/build/outputs/apk/release/app-release-unsigned.apk builds/LeanNutri-$npm_package_version.apk",
"apk-prod": "npm run copy-config:prod
             && ionic cordova build android --prod --release
             && npm run jarsign
             && npm run zipalign",

The APK can be built by using npm run apk-prod

What’s here and what’s missing?

We finally have the ability to programmatically use multiple configurations for our app, and also deploy them to Android apps or using AppCenter. We also have complete version management for our app allowing us to have a scalable release management.

I still don’t have here how to make config update automatically as expected when you add / remove any plugin using cordova plugin add plugin. It is still required to manually add any new plugin in both dev.xml and prod.xml whenever a plugin is added or upgraded.

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *