Skip to content

Instantly share code, notes, and snippets.

@stephenfeather
Last active October 2, 2015 18:18
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save stephenfeather/6143887c14ddb30bdbd6 to your computer and use it in GitHub Desktop.
Save stephenfeather/6143887c14ddb30bdbd6 to your computer and use it in GitHub Desktop.
Appcelerator Gruntjs
module.exports = function(grunt) {
require('time-grunt')(grunt);
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
CHANGELOG: '',
// add tiapp.xml changes to the repo
gitadd: {
versionBump: {
options: {
force: true
},
files: {
src: ['tiapp.xml']
}
}
},
// commit tiapp.xml w/ message to the repo
gitcommit: {
versionBump: {
options: {
message: 'stuff'
},
files: {
src: ['tiapp.xml']
}
}
},
titanium: {
// clean our titanium project in preperation of a new build
cleanProject: {
options: {
command: 'clean',
quiet: 'false'
}
},
// build an ios binary and place it in our dist folder
build_ios: {
options: {
command: 'build',
projectDir: './',
platform: 'ios',
buildOnly: true,
target: 'dist-adhoc',
distributionName: '<%= pkg.gruntConfig.apple.distributionName %>',
ppUuid: '<%= pkg.gruntConfig.apple.ppUuid %>',
outputDir: './dist'
}
},
// build an android binary TODO: consider signing the binary with our release creds
build_android: {
options: {
command: 'build',
projectDir: './',
platform: 'android',
buildOnly: true,
}
}
},
shell: {
// remove the contents of our dist folder
cleanProject: {
options: {
stdout: true
},
command: 'rm -rf dist/*'
},
// generate a CHANGELOG from our git commits
createFullChangeLog: {
options: {
stdout: true
},
command: 'git log --oneline --decorate | grep -v Merge > CHANGELOG'
},
// installr has a limit on changelog length, so lets truncate to 4000 chars and drop in a seperate file
createShortChangeLog: {
options: {
stdout: true
},
command: "head -c 4000 CHANGELOG > ChangeLogShort"
},
// create an archive with our dSYM in it and place in dist folder
crittercism_create_dSYM_archive: {
options: {
stdout: true
},
command: 'zip --recurse-paths --quiet ./dist/<%= pkg.name %>.dSYM.zip ./build/iphone/build/Release-iphoneos/<%= pkg.name %>.app.dSYM'
},
// upload our dSYM archive to crittercism so we can use it for symbolication
crittercism_upload_dSYM_crittercism: {
options: {
stdout: true
},
command: 'curl "<%= pkg.gruntConfig.crittercism.url %><%= pkg.gruntConfig.crittercism.ios.APP_ID%>" --write-out %{http_code} --silent --output /dev/null -F dsym=@"./dist/<%= pkg.name %>.dSYM.zip" -F key="<%= pkg.gruntConfig.crittercism.ios.API_KEY %>"'
},
// upload iOS App to installr
installr_ios: {
options: {
stdout: true
},
command: [
"curl -H 'X-InstallrAppToken: <%= pkg.gruntConfig.installr_settings.appToken %>' https://www.installrapp.com/apps.json " +
"-F 'qqfile=@./dist/<%= pkg.name %>.ipa' " +
"-F 'releaseNotes=<%= CHANGELOG %>' " +
"-F 'notify=true'"
].join("&&")
},
// upload Android App to installr
installr_android: {
options: {
stdout: true
},
command: [
"curl -H 'X-InstallrAppToken: <%= pkg.gruntConfig.installr_settings.appToken %>' https://www.installrapp.com/apps.json " +
"-F 'qqfile=@./build/android/bin/<%= pkg.name %>.apk' " +
"-F 'releaseNotes=<%= CHANGELOG %>' " +
"-F 'notify=true'"
].join("&&")
}
},
});
// Load plugins
grunt.loadNpmTasks('grunt-titanium');
grunt.loadNpmTasks('grunt-shell');
grunt.loadNpmTasks('grunt-git');
grunt.registerTask('default', ['adhoc']);
grunt.registerTask('adhoc', 'Running dual platform adHoc build and upload', ['titanium:cleanProject', 'shell:cleanProject', 'tiapp', 'shell:createFullChangeLog', 'shell:createShortChangeLog', 'fetchChangelog', 'titanium:build_ios', 'titanium:build_android', 'shell:crittercism_create_dSYM_archive', 'shell:crittercism_upload_dSYM_crittercism', 'shell:installr_ios', 'shell:installr_android']);
grunt.registerTask('adhoc-ios', 'Running iOS only adhoc build and upload', ['titanium:cleanProject', 'shell:cleanProject', 'tiapp', 'shell:createFullChangeLog', 'shell:createShortChangeLog', 'fetchChangelog', 'titanium:build_ios', 'shell:crittercism_create_dSYM_archive', 'shell:crittercism_upload_dSYM_crittercism', 'shell:installr_ios']);
grunt.registerTask('adhoc-android', 'Running android only adhoc build and upload', ['titanium:cleanProject', 'shell:cleanProject', 'tiapp', 'shell:createFullChangeLog', 'shell:createShortChangeLog', 'fetchChangelog', 'titanium:build_android', 'shell:installr_android']);
grunt.registerTask('fetchChangelog', function() {
grunt.option('CHANGELOG', grunt.file.read('ChangeLogShort'));
});
grunt.registerTask('tiapp', function() {
var tiapp = require('tiapp.xml').load();
var versions = tiapp.version.split('.');
//TODO: if 3rd number reaches 999, reset to 1 and increment 2nd number
versions[2] = parseInt(versions[2]) + 1;
tiapp.version = versions.join('.');
var androids = tiapp.doc.documentElement.getElementsByTagName('android');
if (androids.length === 1) {
var manifests = androids.item(0).getElementsByTagName('manifest');
if (manifests.length === 1) {
var manifest = manifests.item(0);
var versionCode = parseInt(manifest.getAttribute('android:versionCode')) + 1;
grunt.log.writeln(versionCode);
manifest.setAttribute('android:versionName', versions.slice(0, 3).join('.'));
manifest.setAttribute('android:versionCode', versionCode);
}
}
tiapp.write();
grunt.log.writeln(require('util').format('Bumped version to: %s', tiapp.version));
});
};
{
"name": "Uinterview",
"version": "0.1.0",
"gruntConfig": {
"apple": {
"distributionName": "Your Apple Name (3XCFDVPQLY3)",
"ppUuid": "your certificate UUID"
},
"crittercism": {
"url": "https://api.crittercism.com/api_beta/dsym/",
"ios": {
"APP_ID": "crittercism app id for ios",
"API_KEY": "crittercism api key for ios"
},
"android": {
"APP_ID": "crittercism app id for android",
"API_KEY": "crittercism api key for android"
}
},
"installr_settings": {
"appToken": "installr app token"
}
},
"devDependencies": {
"grunt": "^0.4.5",
"grunt-git": "^0.3.1",
"grunt-shell": "^1.1.1",
"grunt-titanium": "^0.2.2",
"tiapp.xml": "^0.2.0",
"time-grunt": "^1.0.0"
}
}
@stephenfeather
Copy link
Author

TODO:
git integration is not in
allow roll up of version numbers
add android credentials for signing the APK
register sub tasks to allow for the checking of prerequisites.

Acknowledgements:
DaveHudson for the initial installer work.
Fokke partially for the versioning, although his implementation is wrong and this was modified to match android specs.

@FokkeZB
Copy link

FokkeZB commented Dec 4, 2014

@sfeather I agree on the versionCode. I will (for new apps) go back to incrementing again. What I wanted is to easily match an iOS and Android version of the same build. But frankly, I noticed the versionCode isn't even showing up in the crash logs so not of much help anyway. I will probably just include the timestamp (4th part) in the versionName.

@FokkeZB
Copy link

FokkeZB commented Dec 4, 2014

I also played with the git integration. I think I'll do it like npm publish, requiring a clean working copy before bumping the version and then committing the tiapp.xml change with a tag.

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