Skip to content
This repository has been archived by the owner on Apr 7, 2023. It is now read-only.

Commit

Permalink
support android app bundles (#80)
Browse files Browse the repository at this point in the history
* support android app bundles

* add android build types in turtle-cli

* bump xdl version to 54.1.4

* update CHANGELOG.md
  • Loading branch information
wkozyra95 authored Jun 7, 2019
1 parent ed12f3c commit fe31b74
Show file tree
Hide file tree
Showing 15 changed files with 67 additions and 46 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Turtle CLI logo to the project (created by [@zularizal](https://github.com/zularizal))!
- Added shell apps for SDK 33.
- Support for Android App Bundles
### Changed
- Updated Android shell app for SDK 32 to fix AppAuth issue (https://github.com/expo/expo/pull/4115) and to fix a newer than expected JSC version.
- Default value for build timeout to 15 minutes.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@
},
"dependencies": {
"@expo/spawn-async": "^1.4.2",
"@expo/xdl": "54.1.3",
"@expo/xdl": "54.1.4",
"@google-cloud/logging-bunyan": "^0.9.5",
"async-retry": "^1.2.1",
"aws-sdk": "^2.226.1",
Expand Down
18 changes: 15 additions & 3 deletions src/bin/commands/build/android.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,18 @@ export default (program: any, setCommonCommandOptions: any) => {
.option(
'--keystore-path <app.jks>',
'path to your Keystore (please provide Keystore password and Key password as EXPO_ANDROID_KEYSTORE_PASSWORD'
+ 'and EXPO_ANDROID_KEY_PASSWORD env variables)',
+ ' and EXPO_ANDROID_KEY_PASSWORD env variables)',
)
.option('--keystore-alias <alias>', 'keystore Alias')
.option(
'-t --type <build>',
'type of build: app-bundle|apk',
/^(app-bundle|apk)$/i,
'app-bundle',
)
.description(
'Build a standalone APK for your project, signed and ready for submission to the Google Play Store.',
'Build a standalone APK or App Bundle for your project, signed and ready for submission to the Google Play'
+ ' Store.',
)
.asyncAction(
createBuilderAction({
Expand All @@ -34,12 +41,17 @@ export default (program: any, setCommonCommandOptions: any) => {
);
};

const buildJobObject = (appJSON: any, { releaseChannel, username, projectDir, publicUrl }: any, credentials: any) => ({
const buildJobObject = (
appJSON: any,
{ releaseChannel, username, projectDir, publicUrl, buildType }: any,
credentials: any,
) => ({
config: {
..._.get(appJSON, 'expo.android.config', {}),
releaseChannel,
androidPackage: _.get(appJSON, 'expo.android.package'),
publicUrl,
buildType,
},
id: uuid.v4(),
platform: PLATFORMS.ANDROID,
Expand Down
4 changes: 2 additions & 2 deletions src/bin/commands/build/ios.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import uuid from 'uuid';
import { ErrorWithCommandHelp } from 'turtle/bin/commands/ErrorWithCommandHelp';
import { createBuilderAction } from 'turtle/bin/utils/builder';
import builder from 'turtle/builders/ios';
import { IOS, PLATFORMS } from 'turtle/constants';
import { IOS_BUILD_TYPES, PLATFORMS } from 'turtle/constants';

export default (program: any, setCommonCommandOptions: any) => {
const command = program.command('build:ios [project-dir]');
Expand Down Expand Up @@ -56,7 +56,7 @@ const buildJobObject = (appJSON: any, { releaseChannel, buildType, username, pub
});

const prepareCredentials = async (cmd: any) => {
if (cmd.type !== IOS.BUILD_TYPES.ARCHIVE) {
if (cmd.type !== IOS_BUILD_TYPES.ARCHIVE) {
return null;
}

Expand Down
14 changes: 10 additions & 4 deletions src/builders/android.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { AndroidShellApp, ImageUtils } from '@expo/xdl';
import fs from 'fs-extra';
import _ from 'lodash';
import semver from 'semver';
import { ANDROID_BUILD_TYPES } from 'turtle/constants';
import uuidv4 from 'uuid/v4';

import getOrCreateCredentials from 'turtle/builders/utils/android/credentials';
Expand All @@ -20,13 +21,16 @@ import logger from 'turtle/logger';
export default async function buildAndroid(jobData: IJob): Promise<IJobResult> {
await ensureCanBuildSdkVersion(jobData);
const credentials = await getOrCreateCredentials(jobData);
const apkFilePath = await runShellAppBuilder(jobData, credentials);
const outputFilePath = await runShellAppBuilder(jobData, credentials);

const randomHex = uuidv4().replace(/-/g, '');
const s3Filename = `${jobData.experienceName}-${randomHex}-signed.apk`;
const s3FileExtension = jobData.config.buildType === ANDROID_BUILD_TYPES.APP_BUNDLE ? 'aab' : 'apk';
const s3Filename = `${jobData.experienceName}-${randomHex}-signed.${s3FileExtension}`;
const s3FileKey = `android/${s3Filename}`;
const fakeUploadFilename = s3Filename.replace('/', '\\');

const artifactUrl = await uploadBuildToS3({
uploadPath: apkFilePath,
uploadPath: outputFilePath,
s3FileKey,
...config.builder.fakeUpload && {
fakeUploadBuildPath:
Expand Down Expand Up @@ -62,7 +66,8 @@ async function runShellAppBuilder(
ImageUtils.setResizeImageFunction(imageHelpers.resizeIconWithSharpAsync);
ImageUtils.setGetImageDimensionsFunction(imageHelpers.getImageDimensionsWithSharpAsync);

const outputFilePath = path.join(temporaryFilesRoot, `shell-signed-${jobData.id}.apk`);
const fileExtension = jobData.config.buildType === ANDROID_BUILD_TYPES.APP_BUNDLE ? 'aab' : 'apk';
const outputFilePath = path.join(temporaryFilesRoot, `shell-signed-${jobData.id}.${fileExtension}`);

const { config: jobConfig, manifest, sdkVersion: sdkVersionFromJob } = jobData;
const sdkVersion = _.get(manifest, 'sdkVersion', sdkVersionFromJob);
Expand All @@ -87,6 +92,7 @@ async function runShellAppBuilder(
workingDir,
outputFile: outputFilePath,
modules: enabledModules,
buildType: jobData.config.buildType,
});
} catch (err) {
commonUtils.logErrorOnce(err);
Expand Down
13 changes: 6 additions & 7 deletions src/builders/ios/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { v4 as uuidv4 } from 'uuid';

import { formatShellAppDirectory } from 'turtle/builders/utils/ios/workingdir';
import config from 'turtle/config';
import { IOS, PLATFORMS } from 'turtle/constants/index';
import { IOS_BUILD_TYPES, PLATFORMS } from 'turtle/constants/index';
import { IJob } from 'turtle/job';

export interface IContext {
Expand All @@ -27,7 +27,6 @@ export interface IContext {
}

const { EXPOKIT_APP, EXPONENT_APP } = IosShellApp;
const { BUILD_TYPES } = IOS;

export function createBuilderContext(job: IJob): IContext {
const { join } = path;
Expand Down Expand Up @@ -57,7 +56,7 @@ export function createBuilderContext(job: IJob): IContext {
context.tempCertPath = join(context.appDir, 'cert.p12');
context.baseArchiveDir = join(context.appDir, 'archive');

if (buildType === BUILD_TYPES.CLIENT) {
if (buildType === IOS_BUILD_TYPES.CLIENT) {
context.applicationFilesSrc = join(
workingDir,
'expo-client-build',
Expand All @@ -74,7 +73,7 @@ export function createBuilderContext(job: IJob): IContext {
);
}

if (buildType === BUILD_TYPES.ARCHIVE) {
if (buildType === IOS_BUILD_TYPES.ARCHIVE) {
context.outputPath = join(context.appDir, 'archive.xcarchive');
context.uploadPath = join(context.buildDir, 'archive.ipa');
context.archiveDir = join(
Expand All @@ -92,7 +91,7 @@ export function createBuilderContext(job: IJob): IContext {
'default',
`${EXPOKIT_APP}.xcworkspace`,
);
} else if (buildType === BUILD_TYPES.CLIENT) {
} else if (buildType === IOS_BUILD_TYPES.CLIENT) {
context.outputPath = join(context.appDir, 'archive.xcarchive');
context.uploadPath = join(context.buildDir, 'archive.ipa');
context.archiveDir = join(
Expand All @@ -107,7 +106,7 @@ export function createBuilderContext(job: IJob): IContext {
'ios',
`${EXPONENT_APP}.xcworkspace`,
);
} else if (buildType === BUILD_TYPES.SIMULATOR) {
} else if (buildType === IOS_BUILD_TYPES.SIMULATOR) {
context.outputPath = join(context.appDir, 'archive.tar.gz');
context.uploadPath = join(context.appDir, 'archive.tar.gz');
context.archiveDir = join(
Expand All @@ -117,7 +116,7 @@ export function createBuilderContext(job: IJob): IContext {
);
}

const s3FileExtension = buildType === BUILD_TYPES.SIMULATOR ? 'tar.gz' : 'ipa';
const s3FileExtension = buildType === IOS_BUILD_TYPES.SIMULATOR ? 'tar.gz' : 'ipa';
const s3Filename = `${job.experienceName}-${appUUID}-${buildType}.${s3FileExtension}`;
if (config.builder.fakeUpload) {
const fakeUploadFilename = s3Filename.replace('/', '\\');
Expand Down
12 changes: 5 additions & 7 deletions src/builders/ios/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,11 @@ import prepareAdHocBuildCredentials from 'turtle/builders/utils/ios/adhocBuild';
import { uploadBuildToS3 } from 'turtle/builders/utils/uploader';
import { ensureCanBuildSdkVersion } from 'turtle/builders/utils/version';
import config from 'turtle/config';
import { IOS } from 'turtle/constants/index';
import { IOS_BUILD_TYPES } from 'turtle/constants';
import { IJob, IJobResult } from 'turtle/job';

const { BUILD_TYPES } = IOS;

export default async function iosBuilder(job: IJob): Promise<IJobResult> {
if (job.config.buildType !== BUILD_TYPES.CLIENT) {
if (job.config.buildType !== IOS_BUILD_TYPES.CLIENT) {
await ensureCanBuildSdkVersion(job);
}

Expand All @@ -26,13 +24,13 @@ export default async function iosBuilder(job: IJob): Promise<IJobResult> {

const { buildType } = job.config;

if (buildType === BUILD_TYPES.CLIENT) {
if (buildType === IOS_BUILD_TYPES.CLIENT) {
await prepareAdHocBuildCredentials(job);
}

if ([BUILD_TYPES.ARCHIVE, BUILD_TYPES.CLIENT].includes(buildType!)) {
if ([IOS_BUILD_TYPES.ARCHIVE, IOS_BUILD_TYPES.CLIENT].includes(buildType!)) {
await buildArchive(ctx, job);
} else if (buildType === BUILD_TYPES.SIMULATOR) {
} else if (buildType === IOS_BUILD_TYPES.SIMULATOR) {
await buildSimulator(ctx, job);
} else {
throw new Error(`Unsupported iOS build type: ${buildType}`);
Expand Down
4 changes: 2 additions & 2 deletions src/builders/utils/ios/shellAppBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import _ from 'lodash';
import { IContext } from 'turtle/builders/ios/context';
import * as commonUtils from 'turtle/builders/utils/common';
import * as imageHelpers from 'turtle/builders/utils/image';
import { IOS } from 'turtle/constants/index';
import { IOS_BUILD_TYPES } from 'turtle/constants/index';
import { IJob } from 'turtle/job';
import logger from 'turtle/logger/index';

Expand Down Expand Up @@ -37,7 +37,7 @@ export default async function runShellAppBuilder(ctx: IContext, job: IJob): Prom
output: ctx.outputPath,
verbose: true,
};
if (buildType === IOS.BUILD_TYPES.CLIENT) {
if (buildType === IOS_BUILD_TYPES.CLIENT) {
Object.assign(shellAppParams, {
workspacePath: path.join(ctx.workingDir, 'ios'),
});
Expand Down
4 changes: 2 additions & 2 deletions src/builders/utils/ios/workingdir.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import { ExponentTools } from '@expo/xdl';

import { IShellAppDirectoryConfig } from 'turtle/builders/utils/workingdir';
import config from 'turtle/config';
import { IOS, PLATFORMS } from 'turtle/constants';
import { IOS_BUILD_TYPES, PLATFORMS } from 'turtle/constants';

export function formatShellAppDirectory({ sdkVersion, buildType }: IShellAppDirectoryConfig) {
const { workingDir } = config.directories;
if (buildType === IOS.BUILD_TYPES.CLIENT) {
if (buildType === IOS_BUILD_TYPES.CLIENT) {
return path.join(workingDir, PLATFORMS.IOS, 'client');
} else if (config.builder.useLocalWorkingDir) {
return path.join(workingDir, 'local');
Expand Down
4 changes: 2 additions & 2 deletions src/builders/utils/workingdir.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { IOS } from 'turtle/constants';
import { ANDROID_BUILD_TYPES, IOS_BUILD_TYPES } from 'turtle/constants';

export interface IShellAppDirectoryConfig {
sdkVersion: string;
buildType?: IOS.BUILD_TYPES;
buildType?: IOS_BUILD_TYPES & ANDROID_BUILD_TYPES;
}
14 changes: 12 additions & 2 deletions src/constants/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
import * as BUILD from './build';
import * as IOS from './ios';

export enum PLATFORMS {
IOS = 'ios',
ANDROID = 'android',
}

export { IOS, BUILD };
export enum IOS_BUILD_TYPES {
ARCHIVE = 'archive',
CLIENT = 'client',
SIMULATOR = 'simulator',
}

export enum ANDROID_BUILD_TYPES {
APK = 'apk',
APP_BUNDLE = 'app-bundle',
}

export { BUILD };
5 changes: 0 additions & 5 deletions src/constants/ios.ts

This file was deleted.

4 changes: 2 additions & 2 deletions src/job.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { IOS } from 'turtle/constants';
import { ANDROID_BUILD_TYPES, IOS_BUILD_TYPES } from 'turtle/constants';

export interface IJob {
platform: 'android' | 'ios';
Expand All @@ -9,8 +9,8 @@ export interface IJob {
config: {
releaseChannel: string;
publicUrl?: string;
buildType: IOS_BUILD_TYPES & ANDROID_BUILD_TYPES;
// ios
buildType?: IOS.BUILD_TYPES;
bundleIdentifier?: string;
// android
androidPackage?: string;
Expand Down
6 changes: 3 additions & 3 deletions src/jobsSchemas/ios.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import Joi from 'joi';

import { IOS, PLATFORMS } from 'turtle/constants/index';
import { IOS_BUILD_TYPES, PLATFORMS } from 'turtle/constants/index';
import baseJobSchema from 'turtle/jobsSchemas/base';

export default baseJobSchema.concat(
Joi.object().keys({
platform: Joi.string().valid(PLATFORMS.IOS),
config: Joi.object().keys({
buildType: Joi.string().default(IOS.BUILD_TYPES.ARCHIVE),
buildType: Joi.string().default(IOS_BUILD_TYPES.ARCHIVE),
bundleIdentifier: Joi.string().regex(/^[a-zA-Z][a-zA-Z0-9\-.]+$/),
}),
credentials: Joi.object()
Expand All @@ -21,7 +21,7 @@ export default baseJobSchema.concat(
udids: Joi.array().items(Joi.string()),
})
.when('config.buildType', {
is: IOS.BUILD_TYPES.SIMULATOR,
is: IOS_BUILD_TYPES.SIMULATOR,
then: Joi.optional(),
otherwise: Joi.required(),
}),
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1116,10 +1116,10 @@
jimp "^0.6.0"
mime "^2.4.0"

"@expo/[email protected].3":
version "54.1.3"
resolved "https://registry.yarnpkg.com/@expo/xdl/-/xdl-54.1.3.tgz#02aa8c4c7acd35b01462ce62281235b81bf192a3"
integrity sha512-X5jP2qM9nHhxUjeYOar9sAZMH2rX1quQPm4SM51B6DlKlMCyt8uCPHWXly72oZsBT3vT4t0G/Q3y+bvsqRQvzA==
"@expo/[email protected].4":
version "54.1.4"
resolved "https://registry.yarnpkg.com/@expo/xdl/-/xdl-54.1.4.tgz#e92ca6efb57fea65262cf26385d0ef7f74bb627c"
integrity sha512-VfzVWNen8yowb0rwmh1DQ3SoVd+IyyQg8jwucOG7eQ5va5V595Ot2foKgloG/GGli3rocA79y/8PaDq/yvpXMw==
dependencies:
"@expo/bunyan" "3.0.2"
"@expo/config" "^2.0.0"
Expand Down

0 comments on commit fe31b74

Please sign in to comment.