Skip to content

Commit

Permalink
Added build for Android Play store bundle.
Browse files Browse the repository at this point in the history
  • Loading branch information
mikeller committed Sep 7, 2021
1 parent f0bc821 commit 9f0ccee
Show file tree
Hide file tree
Showing 11 changed files with 1,229 additions and 308 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ debug/
release/
testresults/
.eslintcache
cordova/bundle.keystore

# OSX
.DS_store
Expand Down
2 changes: 1 addition & 1 deletion azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ stages:
displayName: 'Install Node.js 10.16.3'
- script: yarn install
displayName: 'Run yarn install'
- script: yarn gulp release --android
- script: yarn gulp debug-release --android
displayName: 'Run yarn release for android'
- task: PublishPipelineArtifact@1
displayName: 'Publish Android release'
Expand Down
10 changes: 0 additions & 10 deletions cordova/build.json

This file was deleted.

18 changes: 18 additions & 0 deletions cordova/build_template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"android": {
"debug": {
"keystore": "debug.keystore",
"storePassword": "betaflight_debug",
"alias": "betaflight_debug",
"password": "password",
"packageType": "apk"
},
"release": {
"keystore": "bundle.keystore",
"storePassword": "[INJECTED_BY_GULPFILE]",
"alias": "betaflight",
"password": "password",
"packageType": "bundle"
}
}
}
1 change: 1 addition & 0 deletions cordova/config_template.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
<preference name="SplashMaintainAspectRatio" value="true"/>
<preference name="SplashShowOnlyFirstTime" value="true"/>
<preference name="android-minSdkVersion" value="19"/>
<preference name="android-targetSdkVersion" value="30" />
<config-file parent="/manifest/application/activity" target="AndroidManifest.xml">
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"/>
Expand Down
Binary file added cordova/debug.keystore
Binary file not shown.
Binary file removed cordova/release.keystore
Binary file not shown.
179 changes: 138 additions & 41 deletions gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@ const os = require('os');
const git = require('simple-git')();
const source = require('vinyl-source-stream');
const stream = require('stream');
const prompt = require('gulp-prompt');

const cordova = require("cordova-lib").cordova;

const browserify = require('browserify');
const glob = require('glob');

Expand All @@ -45,7 +47,6 @@ const NODE_ENV = process.env.NODE_ENV || 'production';

const NAME_REGEX = /-/g;


const nwBuilderOptions = {
version: '0.54.1',
files: `${DIST_DIR}**/*`,
Expand Down Expand Up @@ -110,18 +111,18 @@ const debugDistBuild = gulp.series(process_package_debug, dist_src, dist_changel
const distRebuild = gulp.series(clean_dist, distBuild);
gulp.task('dist', distRebuild);

const appsBuild = gulp.series(gulp.parallel(clean_apps, distRebuild), apps, gulp.series(cordova_apps()), gulp.parallel(listPostBuildTasks(APPS_DIR)));
const appsBuild = gulp.series(gulp.parallel(clean_apps, distRebuild), apps, gulp.series(cordova_apps(true)), gulp.parallel(listPostBuildTasks(APPS_DIR)));
gulp.task('apps', appsBuild);

const debugAppsBuild = gulp.series(gulp.parallel(clean_debug, gulp.series(clean_dist, debugDistBuild)), debug, gulp.series(cordova_apps()), gulp.parallel(listPostBuildTasks(DEBUG_DIR)));
const debugAppsBuild = gulp.series(gulp.parallel(clean_debug, gulp.series(clean_dist, debugDistBuild)), debug, gulp.series(cordova_apps(false)), gulp.parallel(listPostBuildTasks(DEBUG_DIR)));

const debugBuild = gulp.series(debugDistBuild, debug, gulp.parallel(listPostBuildTasks(DEBUG_DIR)), start_debug);
gulp.task('debug', debugBuild);

const releaseBuild = gulp.series(gulp.parallel(clean_release, appsBuild), gulp.parallel(listReleaseTasks(APPS_DIR)));
const releaseBuild = gulp.series(gulp.parallel(clean_release, appsBuild), gulp.parallel(listReleaseTasks(true, APPS_DIR)));
gulp.task('release', releaseBuild);

const debugReleaseBuild = gulp.series(gulp.parallel(clean_release, debugAppsBuild), gulp.parallel(listReleaseTasks(DEBUG_DIR)));
const debugReleaseBuild = gulp.series(gulp.parallel(clean_release, debugAppsBuild), gulp.parallel(listReleaseTasks(false, DEBUG_DIR)));
gulp.task('debug-release', debugReleaseBuild);

gulp.task('default', debugBuild);
Expand Down Expand Up @@ -292,21 +293,48 @@ function processPackage(done, gitRevision, isReleaseBuild) {
metadata.packageId = pkg.name;
}

const packageJson = new stream.Readable;
packageJson.push(JSON.stringify(pkg, undefined, 2));
packageJson.push(null);
function version_prompt() {
return gulp.src('.')
.pipe(prompt.prompt([{
type: 'input',
name: 'version',
message: `Package version (default: ${pkg.version}):`,
}, {
type: 'input',
name: 'storeVersion',
message: 'Google Play store version (<x.y.z>, default: package version):',
}], function(res) {
if (res.version) {
pkg.version = res.version;
}
if (res.storeVersion) {
metadata.storeVersion = res.storeVersion;
}
}));
}

Object.keys(pkg)
.filter(key => metadataKeys.includes(key))
.forEach((key) => {
metadata[key] = pkg[key];
});
function write_package_file() {
Object.keys(pkg)
.filter(key => metadataKeys.includes(key))
.forEach((key) => {
metadata[key] = pkg[key];
});

packageJson
.pipe(source('package.json'))
.pipe(gulp.dest(DIST_DIR));
const packageJson = new stream.Readable;
packageJson.push(JSON.stringify(pkg, undefined, 2));
packageJson.push(null);

done();
return packageJson
.pipe(source('package.json'))
.pipe(gulp.dest(DIST_DIR));
}

const platforms = getPlatforms();
if (platforms.indexOf('android') !== -1 && isReleaseBuild) {
gulp.series(version_prompt, write_package_file)(done);
} else {
gulp.series(write_package_file)(done);
}
}

function dist_src() {
Expand Down Expand Up @@ -465,7 +493,7 @@ function debug(done) {
buildNWAppsWrapper(platforms, 'sdk', DEBUG_DIR, done);
}

function injectARMCache(flavor, callback) {
function injectARMCache(flavor, done) {
const flavorPostfix = `-${flavor}`;
const flavorDownloadPostfix = flavor !== 'normal' ? `-${flavor}` : '';
clean_cache().then(function() {
Expand Down Expand Up @@ -528,7 +556,7 @@ function injectARMCache(flavor, callback) {
clean_debug();
process.exit(1);
}
callback();
done();
}
);
}
Expand Down Expand Up @@ -592,10 +620,10 @@ function buildNWApps(platforms, flavor, dir, done) {

function getGitRevision(done, callback, isReleaseBuild) {
let gitRevision = 'norevision';
git.diff([ '--shortstat' ], function (err, diff) {
if (!err && !diff) {
git.log([ '-1', '--pretty=format:%h' ], function (err, rev) {
if (!err) {
git.diff([ '--shortstat' ], function (err1, diff) {
if (!err1 && !diff) {
git.log([ '-1', '--pretty=format:%h' ], function (err2, rev) {
if (!err2) {
gitRevision = rev.latest.hash;
}

Expand All @@ -608,7 +636,6 @@ function getGitRevision(done, callback, isReleaseBuild) {
}

function start_debug(done) {

const platforms = getPlatforms();

if (platforms.length === 1) {
Expand Down Expand Up @@ -813,7 +840,7 @@ function createDirIfNotExists(dir) {
}

// Create a list of the gulp tasks to execute for release
function listReleaseTasks(appDirectory) {
function listReleaseTasks(isReleaseBuild, appDirectory) {

const platforms = getPlatforms();

Expand Down Expand Up @@ -869,7 +896,11 @@ function listReleaseTasks(appDirectory) {

if (platforms.indexOf('android') !== -1) {
releaseTasks.push(function release_android() {
return cordova_release();
if (isReleaseBuild) {
return cordova_release();
} else {
return cordova_debug_release();
}
});
}

Expand All @@ -891,6 +922,7 @@ function cordova_dist() {
distTasks.push(cordova_packagejson);
distTasks.push(cordova_manifestjson);
distTasks.push(cordova_configxml);
distTasks.push(cordova_rename_build_json);
distTasks.push(cordova_browserify);
distTasks.push(cordova_depedencies);
if (cordovaDependencies) {
Expand All @@ -903,11 +935,16 @@ function cordova_dist() {
}
return distTasks;
}
function cordova_apps() {

function cordova_apps(isReleaseBuild) {
const appsTasks = [];
const platforms = getPlatforms();
if (platforms.indexOf('android') !== -1) {
appsTasks.push(cordova_build);
if (isReleaseBuild) {
appsTasks.push(cordova_build);
} else {
appsTasks.push(cordova_debug_build);
}
} else {
appsTasks.push(function cordova_dist_none(done) {
done();
Expand All @@ -933,7 +970,6 @@ function cordova_copy_www() {
}

function cordova_resources() {

return gulp.src('assets/android/**')
.pipe(gulp.dest(`${CORDOVA_DIST_DIR}resources/android/`));
}
Expand All @@ -947,7 +983,7 @@ function cordova_include_www() {
}

function cordova_copy_src() {
return gulp.src([`${CORDOVA_DIR}**`, `!${CORDOVA_DIR}config_template.xml`, `!${CORDOVA_DIR}package_template.json`])
return gulp.src([`${CORDOVA_DIR}**`, `!${CORDOVA_DIR}config_template.xml`, `!${CORDOVA_DIR}package_template.json`, `!${CORDOVA_DIR}build_template.json`])
.pipe(gulp.dest(`${CORDOVA_DIST_DIR}`));
}

Expand All @@ -972,6 +1008,8 @@ function cordova_packagejson() {
'author': metadata.author,
'license': metadata.license,
}))
.pipe(gulp.dest(CORDOVA_DIST_DIR))
.pipe(rename('manifest.json'))
.pipe(gulp.dest(CORDOVA_DIST_DIR));
}

Expand All @@ -984,7 +1022,7 @@ function cordova_manifestjson() {
}

function cordova_configxml() {
let androidName = metadata.packageId.replace(NAME_REGEX, '_');
const androidName = metadata.packageId.replace(NAME_REGEX, '_');

return gulp.src([`${CORDOVA_DIST_DIR}config.xml`])
.pipe(xmlTransformer([
Expand All @@ -994,12 +1032,18 @@ function cordova_configxml() {
], 'http://www.w3.org/ns/widgets'))
.pipe(xmlTransformer([
{ path: '.', attr: { 'id': `com.betaflight.${androidName}` } },
{ path: '.', attr: { 'version': metadata.version } },
{ path: '.', attr: { 'version': metadata.storeVersion ? metadata.storeVersion : metadata.version } },
]))
.pipe(gulp.dest(CORDOVA_DIST_DIR));
}

function cordova_browserify(callback) {
function cordova_rename_build_json() {
return gulp.src(`${CORDOVA_DIR}build_template.json`)
.pipe(rename('build.json'))
.pipe(gulp.dest(CORDOVA_DIST_DIR));
}

function cordova_browserify(done) {
const readFile = function(file) {
return new Promise(function(resolve) {
if (!file.includes("node_modules")) {
Expand All @@ -1017,7 +1061,7 @@ function cordova_browserify(callback) {
glob(`${CORDOVA_DIST_DIR}www/**/*.js`, {}, function (err, files) {
const readLoop = function() {
if (files.length === 0) {
callback();
done();
} else {
const file = files.pop();
readFile(file).then(function() {
Expand Down Expand Up @@ -1056,24 +1100,77 @@ function cordova_debug() {
cordova.run();
}

function cordova_build(cb) {
function cordova_debug_build(done) {
cordova.build({
'platforms': ['android'],
'options': {
release: true,
release: false,
buildConfig: 'build.json',
},
}).then(function() {
process.chdir('../');
cb();

console.log(`APK has been generated at ${CORDOVA_DIST_DIR}platforms/android/app/build/outputs/apk/release/app-release.apk`);

done();
});
console.log(`APK will be generated at ${CORDOVA_DIST_DIR}platforms/android/app/build/outputs/apk/release/app-release.apk`);
}

async function cordova_release() {
const filename = await getReleaseFilename('android', 'apk');
function cordova_build(done) {
let storePassword = '';
return gulp.series(function password_prompt() {
return gulp.src('.')
.pipe(prompt.prompt({
type: 'password',
name: 'storePassword',
message: 'Please enter the keystore password:',
}, function(res) {
storePassword = res.storePassword;
}));
}, function set_password() {
return gulp.src(`build.json`)
.pipe(jeditor({
'android': {
'release' : {
'storePassword': storePassword,
},
},
}))
.pipe(gulp.dest('./'));
}, function build(done2) {
return cordova.build({
'platforms': ['android'],
'options': {
release: true,
buildConfig: 'build.json',
},
}).then(function() {
// Delete the file containing the store password
del(['build.json'], { force: true });
process.chdir('../');

console.log('AAB has been generated at dist_cordova/platforms/android/app/build/outputs/bundle/release/app.aab');
done2();
});
})(done);
}

async function cordova_debug_release() {
const filename = getReleaseFilename('android', 'apk');

console.log(`Release APK : release/${filename}`);
return gulp.src(`${CORDOVA_DIST_DIR}platforms/android/app/build/outputs/apk/release/app-release.apk`)

return gulp.src(`${CORDOVA_DIST_DIR}platforms/android/app/build/outputs/apk/debug/app-debug.apk`)
.pipe(rename(filename))
.pipe(gulp.dest(RELEASE_DIR));
}

async function cordova_release() {
const filename = getReleaseFilename('android', 'aab');

console.log(`Release AAB : release/${filename}`);

return gulp.src(`${CORDOVA_DIST_DIR}platforms/android/app/build/outputs/bundle/release/app.aab`)
.pipe(rename(filename))
.pipe(gulp.dest(RELEASE_DIR));
}
Loading

0 comments on commit 9f0ccee

Please sign in to comment.