Search code examples
ionic-frameworkautomationgulpapksigned

How to set up automated packaging of APK for ionic application using gulp


I am using gulp with my ionic application for automation. I have setup a gulp process for minifying my JS,CSS,HTML files and create a build directory. So basically I need to create android APK but for that I have to do following things

  1. Create a build folder www using gulp command
  2. Execute command to create release build: ionic cordova build --release android
  3. Use jarsigner command to sign APK: jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore my-release-key.keystore HelloWorld-release-unsigned.apk alias_name

Finally my APK gets ready and I copy it somewhere in today's date folder by updating it's name with additional version parameter. This is quite time consuming when we need more frequent build to deliver for QA.

My concern is now how can I create a deploy ready signed APK in one go using gulp process only?


Solution

  • I have developed the fantastic solution for creating signed APKs on fly by utilizing available methods and some nice links of google.

    Let's go step by step

    Step 1.

    Be ready with the gulp process which minifies and copies all CSS, JS, HTML files in build directory i.e www and verify android platform has been added to project.

    Step 2.

    Generate keystore of the application using following command

    keytool -genkey -v -keystore my-release-key.keystore -alias alias_name -keyalg RSA -keysize 2048

    Copy this keystore to your project root.

    Step 3.

    Create new file named as build.json in project's root directory and add following lines into it. Set the keystore name and password details which you have entered while creating keystore

    {
        "android": {
            "debug": {
                "keystore": "AnyName.keystore",
                "storePassword": "password",
                "alias": "AnyAliasName",
                "password" : "password",
                "keystoreType": ""
            },
            "release": {
                "keystore": "AnyName.keystore",
                "storePassword": "password",
                "alias": "AnyAliasName",
                "password" : "password",
                "keystoreType": ""
            }
        }
    }
    

    Step 4.

    Install following gulp plugins before adding code in gulpfile.js

    npm install --save-dev gulp-cheerio  
    npm install --save-dev gulp-util 
    npm install --save-dev gulp-if  
    npm install --save-dev run-sequence 
    npm install --save-dev gulp-rename
    npm install --save-dev yargs
    

    Step 5.

    Add following code in gulpfile.js for creating APK & copying it to the today's date directory and rename it. After adding following code kindly add build_app & release_task gulp tasks to your default gulp process.

        var if = require('gulp-if');
        var runSequence = require('run-sequence');
        var rename = require('gulp-rename');
    
        // This plugin used to read XML file
        var cheerio = require('gulp-cheerio');
    
        // This is gulp utility plugin
        var util = require("gulp-util");
    
        // Used for executing any command line command
        var exec = require('child_process').exec;
    
        /**
         * Command line options - defines whether this is a dev or release build
         * e.g gulp -r or gulp -d. (gulp --release or gulp --develop)
         * By default, just running 'gulp' is the same as running 'gulp -d'
         */
        var args = require('yargs')
          .alias('r', 'release')
          .alias('d', 'develop')
          .default('release', false)
          .argv;
    
        var release = args.release;
        // Used to create directory with today's date
        var releaseDirName = util.date('dd-mmm-yyyy');
    
        // Default path where signed apk is created
        APK_PATH = './platforms/android/build/outputs/apk/android-release.apk'
    
        APK_NAME = "<YOUR_APP_NAME>";
    
        // The following popup is used to give popup notification in windows when APK is ready
        var WINDOWS_POPUP = "msg * MESSAGE";
    
        // This command creates the signed APK using configuration in build.json
        var ANDROID_SIGNED_APK_COMMAND = 'cordova build android --release --buildConfig';
    
        /**
         * Create signed APK
         */
        gulp.task('build_app', function (cb) {
            if(args.signedAPK){
                console.log('Building signed apk...');
                exec(ANDROID_SIGNED_APK_COMMAND,
                {
                    cwd : './',
                    maxBuffer: 1024 * 1024
                },
                 function (err, stdout, stderr) {
                    console.log(stdout);
                    console.log(stderr);
                    cb(err);
                });
            }
        }
    
    
        /**
         * Common function for executing commands
         * @param cmd
         * @param cb
         * @returns
         */
        function execCMD(cmd, cb){
            exec(cmd,
            {
                cwd : './',
                maxBuffer: 1024 * 1024
            },
             function (err, stdout, stderr) {
                console.log(stdout);
                console.log(stderr);
                if(err){
                    cb(err);
                }else{
                    cb();
                }
            });
        }
    
        /**
         * Reads XML file for getting version
         */
        gulp.task('config_xml', function () {
          return gulp.src('./config.xml')
            .pipe(cheerio({
              run: function ($) {
    
                // set app version number
                APK_NAME += '_' + $('widget').attr('version');
              },
              parserOptions: {
                xmlMode: true
              }
            }))
            .pipe(gulp.dest('./'));
        });
    
        /**
         * release task
         */
        gulp.task('releaseTask',function(callback) {
            if(args.signedAPK){
                runSequence(
                    'copyAPK',
                     callback
                )
            }
        });
    
        /**
         * Rename android apk
         */
        gulp.task('copyAPK',function(callback) {
            return gulp.src(APK_PATH)
                .pipe(if(args.signedAPK,rename(APK_NAME)))
                .pipe(gulp.dest(releaseDirName + '/Android/'))
                .on('end', function(){
                    util.log(util.colors.green('Good Job! Your APK is ready at following location : ') + util.colors.cyan(releaseDirName + '/Android/' + APK_NAME))
                    execCMD(WINDOWS_POPUP.replace('MESSAGE','Good Job! Your APK is ready at following location : ' + releaseDirName + '/Android/' + APK_NAME), function(err){})
                });
        });
    

    Step 6.

    Create a bat file with any name. I have created it with Signed APK <My Project Name>.bat Put following code in bat file.

    cd /d %~dp0
    gulp --release --signedAPK
    cmd.exe
    

    Save this bat file in project's root directory.

    cd /d %~dp0 
    

    The above code jumps to the directory where bat file is residing.

    gulp --release --signedAPK
    

    And the above one creates the signed APK of android.

    Step 7.

    Don't wait for anything... Please go to project and double click the bat file and that's it... The Signed APK will be waiting for you in today's date folder in project.