Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Grunt - build your Titanium app and upload to Installr
  1. sudo npm install -g grunt-cli
  2. create the package.json file (template below) in your Titanium app's folder
  3. From your app's folder, run npm install to install the dependencies
  4. Create the Gruntfile.js file in your Titanium app's folder, make sure to fill in live values in the settings section
  5. From your app's folder: grunt to bump version numbers, build for both platforms, and upload to Installr
var _ = require('underscore')._;
module.exports = function(grunt) {
grunt.initConfig({
settings: {
appName: 'YourAppName',
ppUuid: 'uuid', /* Provisioning profile UUID */
distributionName: 'cert_name', /* Distr. certificate name */
keystoreLocation: '/Users/path/to/android.keystore', /* path to keystore */
storePassword: 'keystore_password', /* keystore password */
installrAppToken: 'token', /* API token, from My Account page */
releaseNotes: grunt.file.read("./CHANGELOG.md") /* create this file & put your release notes in it */
/*
or, specify from the command line by using
releaseNotes: grunt.option('notes') || 'CI build',
*/
},
copy: {
pre: {
src: 'config.installr.json',
dest: 'app/config.json',
},
post: {
src: 'config.production.json',
dest: 'app/config.json',
},
},
titanium: {
clean: {
options: {
command: 'clean'
}
},
ios: {
options: {
command: 'build',
projectDir: './',
platform: 'ios',
buildOnly: true,
target: 'dist-adhoc',
distributionName: '<%= settings.distributionName %>',
ppUuid: '<%= settings.ppUuid %>',
outputDir: './dist'
}
},
android: {
options: {
command: 'build',
projectDir: './',
platform: 'android',
keystore: '<%= settings.keystoreLocation %>',
storePassword: '<%= settings.storePassword %>',
buildOnly: true,
outputDir: './dist'
}
}
},
shell: {
ios: {
options: {
stdout: true
},
command: [
"curl -H 'X-InstallrAppToken: <%= settings.installrAppToken %>' https://www.installrapp.com/apps.json " +
"-F 'qqfile=@./dist/<%= settings.appName %>.ipa' " +
"-F 'releaseNotes=<%= settings.releaseNotes %>' " +
"-F 'notify=true'"
].join("&&")
},
android: {
options: {
stdout: true
},
command: [
"curl -H 'X-InstallrAppToken: <%= settings.installrAppToken %>' https://www.installrapp.com/apps.json " +
"-F 'qqfile=@./dist/<%= settings.appName %>.apk' " +
"-F 'releaseNotes=<%= settings.releaseNotes %>' " +
"-F 'notify=true'"
].join("&&")
}
},
});
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-titanium');
grunt.loadNpmTasks('grunt-shell');
grunt.registerTask('tiapp', function () {
var tiapp = require('tiapp.xml').load();
// bump iOS version
var version = tiapp.version.split('.'),
versionString = version[0] + '.' + version[1] + '.' + (parseInt(version[2], 10) + 1);
tiapp.version = versionString;
tiapp.write();
grunt.log.writeln(require('util').format('Bumped iOS version to: %s', tiapp.version));
// bump Android version, there's probably a better way
var doc = tiapp.doc.documentElement,
manifest;
_.each(doc.childNodes, function (child) {
if (child.nodeName === 'android') {
_.each(child.childNodes, function (c) {
if (c.nodeName === 'manifest') {
manifest = c;
}
});
}
});
if (manifest) {
var versionCode = parseInt(manifest.getAttribute('android:versionCode'), 10);
versionCode += 1;
manifest.setAttribute('android:versionCode', versionCode);
manifest.setAttribute('android:versionName', versionString);
tiapp.write();
grunt.log.writeln(require('util').format('Bumped Android version to: %s', versionString));
}
});
grunt.registerTask('default', ['copy:pre', 'tiapp', 'titanium', 'copy:post', 'shell']);
/*
use the following to build locally, without uploading to Installr
grunt.registerTask('default', ['copy:pre', 'tiapp', 'titanium', 'copy:post']);
*/
};
{
"name": "YourAppName",
"version": "1.0",
"devDependencies": {
"grunt": "~0.4.5",
"grunt-contrib-copy": "^0.8.1",
"grunt-contrib-jshint": "~0.11.0",
"grunt-contrib-uglify": "~0.8.0",
"grunt-shell": "~1.1.0",
"grunt-titanium": "~0.3.1",
"tiapp.xml": "~0.2.2",
"underscore": "~1.7.0"
}
}

FokkeZB commented Dec 4, 2014

Lines 99-100 are interesting. So versionCode 1 maps to versionName 1.1, 2 becomes 1.2 etc?

Owner

skypanther commented Aug 25, 2015

I've since updated the Android version updating code to use the same version string used for the iOS version. So, if iOS version became 2.0.5, the Android versionName would also be 2.0.5.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment