diff --git a/README.md b/README.md index bd0452b..2c2a5ec 100644 --- a/README.md +++ b/README.md @@ -6,14 +6,16 @@ taco-team-build is a node module designed to avoid common pitfalls when building Specifically it helps with the following challenges: -1. Handling multiple versions of Cordova from the same build server in a performant way on Windows +1. Handling multiple versions of Cordova from the same build server in a performant way on Windows, Linux, or a Mac. 2. Allowing developers to specify a location to store versions of Cordova, its plugins, and platforms outside of a user's home directory (useful in CI environments where a system user may run the build) -3. Generating an ipa for iOS when using versions of Cordova that do not automatically generate one -4. Automated detection of whether a platform should be added avoid a non-zero exit code for incremental builds (the default CLI behavior) -5. Removing plugins/android.json, plugins/ios.json, plugins/windows.json, or plugins/wp8.json files [which can cause strange results if present](http://go.microsoft.com/fwlink/?LinkID=691927) when adding a platform. (Though files are not removed if the Cordova platforms folder was added to source control.) -6. Fixes for problems with symlinks and execute bits being lost when a plugin or platform is added to source control from Windows (via a plugin) -7. Adds in support for the res/native folder that will overlay the contents of the platforms folder so you can add files to the native project without checking native code into source control (via a plugin) - Ex: res/native/Android/AndroidManifest.xml will overwrite the default one before Cordova's "prepare" step. -8. Some Windows packaging features and bug fixes (via a plugin) designed for use with versions of Cordova that pre-date the Windows platform's support of build.json +3. Automated detection of whether a platform should be added avoid a non-zero exit code for incremental builds (the default CLI behavior) +5. Fixes for problems where execute bits are lost in the hooks or platforms folder when added to control from Windows. +8. Generating an ipa for iOS when using versions of Cordova that do not automatically generate one. +6. Via [cordova-plugin-vs-taco-support](https://github.com/Microsoft/cordova-plugin-vs-taco-support): + 1. Removing plugins/android.json, plugins/ios.json, plugins/windows.json, or plugins/wp8.json files [which can cause strange results if present](http://go.microsoft.com/fwlink/?LinkID=691927) when adding a platform. (Though files are not removed if the Cordova platforms folder was added to source control.) + 2. Fixes for problems with symlinks are lost when a plugin is added to source control from Windows. + 3. Adds in support for the res/native folder that will overlay the contents of the platforms folder so you can add files to the native project without checking native code into source control (via a plugin) - Ex: res/native/Android/AndroidManifest.xml will overwrite the default one before Cordova's "prepare" step. + 4. Some Windows packaging features and bug fixes (via a plugin) designed for use with versions of Cordova that pre-date the Windows platform's support of build.json It is a generic node module so it can be used with any number of build systems including Gulp, Grunt, and Jake. @@ -52,7 +54,7 @@ var build = require('taco-team-build'); build.configure({ nodePackageName: "cordova-cli", moduleCache: "D:\\path\\to\\cache", - moduleVersion: "4.3.1", + moduleVersion: "6.0.0", projectPath: "myproject" }).done(); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -63,7 +65,7 @@ build.configure({ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { - "cordova-cli": "4.3.1" + "cordova-cli": "6.0.0" } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -102,16 +104,27 @@ The method automatically calls setupCordova() if it has not yet been called. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ var build = require('taco-team-build'), platforms = ["android", "windows"], - args = { android: ["--release", "--ant"], windows: ["--release"] }; + args = { android: ["--release", "--device", "--gradleArg=--no-daemon"], windows: ["--release"] }; build.buildProject(platforms, args).done(); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -**WARNING**: Unlike the Cordova CLI, you should not use the "double-double dash" when referencing platform specific arguments. Ex: Use "--ant" not "-- --ant" for Android. +**WARNING**: Unlike the Cordova CLI, you should not use the "double-double dash" when referencing platform specific arguments. Ex: Use "--gradleArg" not "-- --gradleArg" for Android. Not only will your flag not be picked up but older versions of the Cordova Android platform will error out if you specify unrecognized flags with a "TypeError: Cannot call method 'prepEnv' of undefined" error. (This particular error is fixed Cordova 4.3.0 but your flags will still be ignored.) +Note that for iOS you can also add a custom **[build-debug.xcconfig](https://github.com/apache/cordova-ios/blob/master/bin/templates/scripts/cordova/build-debug.xcconfig)** or **[build-release.xcconfig](https://github.com/apache/cordova-ios/blob/master/bin/templates/scripts/cordova/build-release.xcconfig)** file in the **res/native/ios/cordova** folder in your project to set these and other iOS [build settings](https://developer.apple.com/library/ios/documentation/DeveloperTools/Reference/XcodeBuildSettingRef/0-Introduction/introduction.html#//apple_ref/doc/uid/TP40003931-CH1-SW1). Be sure to grab the version of these files from the branch appropriate for the version of Cordova you are targeting - the "master" branch may not be compatible with your version. + +For iOS you may need to unlock the keychain to build your app depending on your build server. You can use some variant of the following shell command to do so: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +security unlock-keychain -p ${KEYCHAIN_PWD} ${HOME}/Library/Keychains/login.keychain +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +See packageProject for older versions of Cordova that do not automatically generate an ipa. + ### packageProject(platforms, args) +**[DEPRECATED] - This method does nothing if the version of Cordova being used already generates an ipa.** + Supported platforms: ios Runs any post-build packaging steps required for the specified platforms. The method returns a promise that is fulfilled once packaging is completed. Passed in **platforms** can be an array of platforms or a single platform string. Passed in **args** can be an array of arguments or an object with an array of arguments per platform name. @@ -134,13 +147,6 @@ iOS Arguments: build.packageProject("ios", ["--sign=/path/to/signing.p12" ", "--embed=/path/to/some.mobileprovision"]); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -You can also add a custom **[build-debug.xcconfig](https://github.com/apache/cordova-ios/blob/master/bin/templates/scripts/cordova/build-debug.xcconfig)** or **[build-release.xcconfig](https://github.com/apache/cordova-ios/blob/master/bin/templates/scripts/cordova/build-release.xcconfig)** file in the **res/native/ios/cordova** folder in your project to set these and other iOS [build settings](https://developer.apple.com/library/ios/documentation/DeveloperTools/Reference/XcodeBuildSettingRef/0-Introduction/introduction.html#//apple_ref/doc/uid/TP40003931-CH1-SW1). Be sure to grab the version of these files from the branch appropriate for the version of Cordova you are targeting - the "master" branch may not be compatible with your version. - -For iOS you may need to unlock the keychain to build your app depending on your build server. You can use some variant of the following shell command to do so: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -security unlock-keychain -p ${KEYCHAIN_PWD} ${HOME}/Library/Keychains/login.keychain -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - ### getInstalledPlatformVersion(projectPath, platform) Returns the version of the platform that is installed to the project. @@ -174,9 +180,9 @@ Config specifies both the name of the package and the expected version. Empty ve ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ var build = require('taco-team-build'), config = { - nodePackageName: "cordova-cli", + nodePackageName: "cordova", moduleCache: "D:\\path\\to\\cache", - moduleVersion: "4.3.1", + moduleVersion: "6.0.0", projectPath: "myproject" }; diff --git a/samples/gulp/gulpfile.js b/samples/gulp/gulpfile.js index 51bfd6b..4026a2e 100644 --- a/samples/gulp/gulpfile.js +++ b/samples/gulp/gulpfile.js @@ -1,3 +1,6 @@ +/// +"use strict"; + /* Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information. @@ -5,41 +8,104 @@ var gulp = require("gulp"), fs = require("fs"), ts = require("gulp-typescript"), + sass = require("gulp-sass"), + es = require('event-stream'), cordovaBuild = require("taco-team-build"); -var winPlatforms = ["android", "windows", "wp8"], +// Setup platforms to build that are supported on current hardware +var winPlatforms = ["android", "windows"], linuxPlatforms = ["android"], osxPlatforms = ["ios"], - buildArgs = { - android: ["--release","--device","--gradleArg=--no-daemon"], // Warning: Omit the extra "--" when referencing platform - ios: ["--release", "--device"], // specific preferences like "-- --ant" for Android - windows: ["--release", "--device"], // or "-- --win" for Windows. You may also encounter a - wp8: ["--release", "--device"] // "TypeError" after adding a flag Android doesn't recognize - }, // when using Cordova < 4.3.0. This is fixed in 4.3.0. - platformsToBuild = process.platform === "darwin" ? osxPlatforms : - (process.platform === "linux" ? linuxPlatforms : winPlatforms), // "Darwin" is the platform name returned for OSX. - tsconfigPath = "scripts/tsconfig.json"; // This could be extended to include Linux as well. + platformsToBuild = process.platform === "darwin" ? osxPlatforms : + (process.platform === "linux" ? linuxPlatforms : winPlatforms), -gulp.task("default", ["package"], function () { - // Copy results to bin folder - gulp.src("platforms/android/ant-build/*.apk").pipe(gulp.dest("bin/release/android")); // Ant build - gulp.src("platforms/android/bin/*.apk").pipe(gulp.dest("bin/release/android")); // Gradle build - gulp.src("platforms/windows/AppPackages/**/*").pipe(gulp.dest("bin/release/windows/AppPackages")); - gulp.src("platforms/wp8/bin/Release/*.xap").pipe(gulp.dest("bin/release/wp8")); - gulp.src("platforms/ios/build/device/*.ipa").pipe(gulp.dest("bin/release/ios")); + // Build config to use for build - Use Pascal case to match paths set by VS + buildConfig = "Release", + + // Arguments for build by platform. Warning: Omit the extra "--" when referencing platform + // specific options (Ex:"-- --gradleArg" is "--gradleArg"). + buildArgs = { + android: ["--" + buildConfig.toLocaleLowerCase(),"--device","--gradleArg=--no-daemon"], + ios: ["--" + buildConfig.toLocaleLowerCase(), "--device"], + windows: ["--" + buildConfig.toLocaleLowerCase(), "--device"] + }, + + // Paths used by build + paths = { + tsconfig: "scripts/tsconfig.json", + ts: "./scripts/**/*.ts", + sass: "./scss/**/*.scss", + sassCssTarget: "./www/css/", + apk:["./platforms/android/ant-build/*.apk", + "./platforms/android/bin/*.apk", + "./platforms/android/build/outputs/apk/*.apk"], + binApk: "./bin/Android/" + buildConfig, + ipa: ["./platforms/ios/build/device/*.ipa", + "./platforms/ios/build/device/*.app.dSYM"], + binIpa: "./bin/iOS/" + buildConfig, + appx: "./platforms/windows/AppPackages/**/*", + binAppx: "./bin/Windows/" + buildConfig + }; + +// Set the default to the build task +gulp.task("default", ["build"]); + +// Executes taks specified in winPlatforms, linuxPlatforms, or osxPlatforms based on +// the hardware Gulp is running on which are then placed in platformsToBuild +gulp.task("build", ["scripts", "sass"], function() { + return cordovaBuild.buildProject(platformsToBuild, buildArgs) + .then(function() { + // ** NOTE: Package not required in recent versions of Cordova + return cordovaBuild.packageProject(platformsToBuild) + .then(function() { + return es.concat( + gulp.src(paths.apk).pipe(gulp.dest(paths.binApk)), + gulp.src(paths.ipa).pipe(gulp.dest(paths.binIpa)), + gulp.src(paths.appx).pipe(gulp.dest(paths.binAppx))); + }); + }); }); +// Build Android, copy the results back to bin folder +gulp.task("build-android", ["scripts", "sass"], function() { + return cordovaBuild.buildProject("android", buildArgs) + .then(function() { + return gulp.src(paths.apk).pipe(gulp.dest(paths.binApk)); + }); +}); + +// Build iOS, copy the results back to bin folder +gulp.task("build-ios", ["scripts", "sass"], function() { + return cordovaBuild.buildProject("ios", buildArgs) + .then(function() { + // ** NOTE: Package not required in recent versions of Cordova + return cordovaBuild.packageProject(platformsToBuild) + .then(function() { + return gulp.src(paths.ipa).pipe(gulp.dest(paths.ipaBin)); + }); + }); +}); + +// Build Windows, copy the results back to bin folder +gulp.task("build-win", ["scripts", "sass"], function() { + return cordovaBuild.buildProject("windows", buildArgs) + .then(function() { + return gulp.src(paths.appx).pipe(gulp.dest(paths.appxBin)); + }); +}); + +// Typescript compile - Can add other things like minification here gulp.task("scripts", function () { // Compile TypeScript code - This sample is designed to compile anything under the "scripts" folder using settings - // in scripts/tsconfig.json if present or this gulpfile if not. Adjust as appropriate for your use case. - if (fs.existsSync(tsconfigPath)) { + // in tsconfig.json if present or this gulpfile if not. Adjust as appropriate for your use case. + if (fs.existsSync(paths.tsconfig)) { // Use settings from scripts/tsconfig.json - gulp.src("scripts/**/*.ts") - .pipe(ts(ts.createProject(tsconfigPath))) + gulp.src(paths.ts) + .pipe(ts(ts.createProject(paths.tsconfig))) .pipe(gulp.dest(".")); } else { // Otherwise use these default settings - gulp.src("scripts/**/*.ts") + gulp.src(paths.ts) .pipe(ts({ noImplicitAny: false, noEmitOnError: true, @@ -52,42 +118,9 @@ gulp.task("scripts", function () { } }); -gulp.task("build", ["scripts"], function () { - return cordovaBuild.buildProject(platformsToBuild, buildArgs); -}); - -gulp.task("build-win", ["scripts"], function() { - return cordovaBuild.buildProject("windows", buildArgs); -}); - -gulp.task("build-wp8", ["scripts"], function() { - return cordovaBuild.buildProject("wp8", buildArgs); -}); - -gulp.task("build-android", ["scripts"], function() { - return cordovaBuild.buildProject("android", buildArgs); -}); - -gulp.task("build-ios", ["scripts"], function() { - return cordovaBuild.buildProject("ios", buildArgs); -}); - -gulp.task("package", ["build"], function () { - return cordovaBuild.packageProject(platformsToBuild); -}); - -// Example of running the app on an attached device. -// Type "gulp run-ios" to execute. Note that ios-deploy will need to be installed globally. -gulp.task("run-ios", ["scripts"], function (callback) { - cordovaBuild.setupCordova().done(function (cordova) { - cordova.run({ platforms: ["ios"], options: ["--debug", "--device"] }, callback); - }); -}); - -// Example of running app on the iOS simulator -// Type "gulp sim-ios" to execute. Note that ios-sim will need to be installed globally. -gulp.task("sim-ios", ["scripts"], function (callback) { - cordovaBuild.setupCordova().done(function (cordova) { - cordova.emulate({ platforms: ["ios"], options: ["--debug"] }, callback); - }); +// SASS compile (ex in Ionic) +gulp.task("sass", function () { + return gulp.src(paths.sass) + .pipe(sass().on("error", sass.logError)) + .pipe(gulp.dest(paths.sassCssTarget)); }); diff --git a/samples/gulp/package.json b/samples/gulp/package.json index 18adb57..6503cbf 100644 --- a/samples/gulp/package.json +++ b/samples/gulp/package.json @@ -3,8 +3,10 @@ "version": "0.0.1", "dependencies": { }, "devDependencies": { - "gulp": "latest", - "gulp-typescript": "latest", - "taco-team-build": "latest" + "gulp": "^3.9.1", + "gulp-typescript": "^2.11.0", + "taco-team-build": "^0.2.1", + "gulp-sass": "^2.0.4", + "event-stream": "^3.3.2" } }