mirror of
https://github.com/expo/turtle.git
synced 2026-11-14 19:12:55 -10:00
Compare commits
17
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a9e15ca51c | ||
|
|
042dd2ccab | ||
|
|
99ae0d1cea | ||
|
|
ad2c87163b | ||
|
|
b4b9cf362e | ||
|
|
7ea4dac986 | ||
|
|
cd8da71711 | ||
|
|
2a2a0f39e0 | ||
|
|
fbabcdf521 | ||
|
|
0803811226 | ||
|
|
0976a642e1 | ||
|
|
16bd4fe7b6 | ||
|
|
3ccd705943 | ||
|
|
11cc4421dd | ||
|
|
32f5a0bb37 | ||
|
|
61a1906e01 | ||
|
|
19a17231b3 |
No files matched your search
@@ -10,6 +10,9 @@
|
||||
"release": true
|
||||
},
|
||||
"hooks": {
|
||||
"before:init": [
|
||||
"yarn"
|
||||
],
|
||||
"after:release": "yarn release:update:turtle-cli-example"
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,31 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## Unreleased
|
||||
|
||||
- Updated iOS shell app for SDK 38 with fixed integer tagging in expo-gl for iOS 14. ([#245](https://github.com/expo/turtle/pull/245))
|
||||
|
||||
# [0.17.1] - 2020-07-16
|
||||
|
||||
- Updated Android shell app for SDK 38 with `targetSdkVersion` bumped to 29. ([#244](https://github.com/expo/turtle/pull/244))
|
||||
|
||||
## [0.17.0] - 2020-07-16
|
||||
|
||||
### Added
|
||||
|
||||
- `--gradle-args` option for `turtle build:android` which makes it possible to specify custom Gradle arguments.
|
||||
|
||||
### Changed
|
||||
|
||||
- Gradle Wrapper doesn't print when dots when the appropriate version of Gradle is being downloaded.
|
||||
|
||||
## [0.16.2] - 2020-07-01
|
||||
|
||||
### Added
|
||||
|
||||
- Added `--allow-non-https-public-url` to allow bypass of protocol validation on `--public-url`.
|
||||
- Added support for dynamic configs (`app.config.ts`, `app.config.js`).
|
||||
|
||||
## [0.16.0] - 2020-06-25
|
||||
|
||||
### Added
|
||||
|
||||
- Added iOS shell app for Expo SDK38.
|
||||
|
||||
+6
-6
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "turtle-cli",
|
||||
"version": "0.16.0",
|
||||
"version": "0.17.0",
|
||||
"description": "The command-line tool for building standalone Expo apps",
|
||||
"preferGlobal": true,
|
||||
"scripts": {
|
||||
@@ -88,25 +88,25 @@
|
||||
"@types/webpack-dev-server": "^3.1.7",
|
||||
"@types/which": "^1.3.1",
|
||||
"husky": "^1.3.1",
|
||||
"jest": "^25.1.0",
|
||||
"jest": "^26.1.0",
|
||||
"lint-staged": "^8.1.5",
|
||||
"nock": "^10.0.1",
|
||||
"nodemon": "^2.0.2",
|
||||
"release-it": "^12.3.4",
|
||||
"rimraf": "^2.6.2",
|
||||
"ts-jest": "^25.2.1",
|
||||
"ts-jest": "^26.1.2",
|
||||
"ts-node": "^8.0.3",
|
||||
"ts-transformer-imports": "^0.4.1",
|
||||
"tsconfig-paths": "^3.8.0",
|
||||
"tslint": "^5.10.0",
|
||||
"tslint-eslint-rules": "^5.4.0",
|
||||
"ttypescript": "^1.5.6",
|
||||
"typescript": "^3.4.2"
|
||||
"typescript": "^3.9.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@expo/config": "^3.0.5",
|
||||
"@expo/config": "^3.2.14",
|
||||
"@expo/spawn-async": "^1.4.2",
|
||||
"@expo/xdl": "^57.9.13",
|
||||
"@expo/xdl": "57.9.25-alpha.1",
|
||||
"@google-cloud/logging-bunyan": "^2.0.3",
|
||||
"async-retry": "^1.2.1",
|
||||
"aws-sdk": "^2.226.1",
|
||||
|
||||
@@ -1 +1 @@
|
||||
s3://exp-artifacts/android-shell-builder-076a13fd8b4ee84a59eb6d2777f6db0a2c71fb6d.tar.gz
|
||||
s3://exp-artifacts/android-shell-builder-6cde8e00cd7bdf7a933cd8aad7f8e86981ea68a2.tar.gz
|
||||
@@ -1 +1 @@
|
||||
s3://exp-artifacts/ios-shell-builder-sdk-latest-b0acfb129b4526f771bd0b363f2896b35f007e83.tar.gz
|
||||
s3://exp-artifacts/ios-shell-builder-sdk-latest-6cde8e00cd7bdf7a933cd8aad7f8e86981ea68a2.tar.gz
|
||||
@@ -17,8 +17,7 @@ jest.mock('../builders/utils/uploader.ts', () => ({
|
||||
async function performSmokeTest(recording: string) {
|
||||
jest.setTimeout(60 * 60 * 1000);
|
||||
|
||||
// @ts-ignore
|
||||
const fixtureExists = await fs.exists(recording);
|
||||
const fixtureExists = await fs.pathExists(recording);
|
||||
if (fixtureExists) {
|
||||
logger.info('Fixture exists, test will use existing one.');
|
||||
|
||||
|
||||
@@ -136,7 +136,7 @@ function _addEmptyMetrics(metrics: IMetric[]) {
|
||||
acc.add(i.MetricName);
|
||||
}
|
||||
return acc;
|
||||
}, new Set());
|
||||
}, new Set<string>());
|
||||
|
||||
const nonEmptyMetrics = _.omitBy(state.registeredMetrics, ({ addEmpty }) => !addEmpty);
|
||||
const toAdd = _.difference(Object.keys(nonEmptyMetrics), Array.from(seenMetrics));
|
||||
|
||||
@@ -19,10 +19,10 @@ export default function calculateStatistics(metrics: IMetric[]) {
|
||||
});
|
||||
}
|
||||
|
||||
result.StatisticValues.Maximum = Math.max(result.StatisticValues.Maximum, i.Value);
|
||||
result.StatisticValues.Minimum = Math.min(result.StatisticValues.Minimum, i.Value);
|
||||
result.StatisticValues.SampleCount += 1;
|
||||
result.StatisticValues.Sum += i.Value;
|
||||
result!.StatisticValues.Maximum = Math.max(result!.StatisticValues.Maximum, i.Value);
|
||||
result!.StatisticValues.Minimum = Math.min(result!.StatisticValues.Minimum, i.Value);
|
||||
result!.StatisticValues.SampleCount += 1;
|
||||
result!.StatisticValues.Sum += i.Value;
|
||||
return result;
|
||||
}, null);
|
||||
return [reduced];
|
||||
|
||||
@@ -29,6 +29,11 @@ export default (program: any, setCommonCommandOptions: any) => {
|
||||
/^(debug|release)$/i,
|
||||
'release',
|
||||
)
|
||||
.option(
|
||||
'--gradle-args <gradle-args>',
|
||||
'optional arguments passed to gradle, make sure to surround them with double quotes'
|
||||
+ ' (e.g.: --gradle-args "--stacktrace --debug")',
|
||||
)
|
||||
.description(
|
||||
'Build a standalone APK or App Bundle for your project, either signed and ready for submission to'
|
||||
+ ' the Google Play Store or in debug mode.',
|
||||
|
||||
@@ -15,7 +15,12 @@ function setCommonCommandOptions(cmd: any) {
|
||||
.option('-o --output <output-file-path>', 'output file path')
|
||||
.option(
|
||||
'--public-url <url>',
|
||||
'the URL of an externally hosted manifest (for self-hosted apps), only HTTPS URLs are supported!',
|
||||
'the URL of an externally hosted manifest (for self-hosted apps), only HTTPS URLs are supported unless '
|
||||
+ '--allow-non-https-public-url is also set!',
|
||||
)
|
||||
.option(
|
||||
'--allow-non-https-public-url',
|
||||
'allows non-HTTPS URLs in --public-url; this should only be used when building an unpublished application',
|
||||
)
|
||||
.option(
|
||||
'--release-channel <channel-name>',
|
||||
|
||||
+16
-13
@@ -1,6 +1,6 @@
|
||||
import _url from 'url';
|
||||
|
||||
import { ConfigError, getExpoSDKVersion } from '@expo/config';
|
||||
import { ConfigError, getExpoSDKVersion, ProjectConfig } from '@expo/config';
|
||||
import { ExponentTools } from '@expo/xdl';
|
||||
import _ from 'lodash';
|
||||
import uuid from 'uuid';
|
||||
@@ -57,7 +57,7 @@ export function createBuilderAction({
|
||||
);
|
||||
}
|
||||
|
||||
if (cmd.publicUrl) {
|
||||
if (cmd.publicUrl && !cmd.allowNonHttpsPublicUrl) {
|
||||
const parsedPublicUrl = _url.parse(cmd.publicUrl);
|
||||
if (parsedPublicUrl.protocol !== 'https:') {
|
||||
throw new ErrorWithCommandHelp('--public-url is invalid - only HTTPS urls are supported');
|
||||
@@ -74,12 +74,12 @@ export function createBuilderAction({
|
||||
publicUrl: cmd.publicUrl,
|
||||
};
|
||||
|
||||
const appJSON = await ProjectUtils.loadAppJSON(projectDirArg, cmd.config);
|
||||
const sdkVersion = getExpoSDKVersionSafely(projectAbsoluteDir, appJSON);
|
||||
const projectConfig = await ProjectUtils.getConfig(projectDirArg, cmd.config);
|
||||
const sdkVersion = getExpoSDKVersionSafely(projectAbsoluteDir, projectConfig);
|
||||
await setup(platform, sdkVersion);
|
||||
const credentials = await prepareCredentials(cmd);
|
||||
const rawJob = {
|
||||
...await buildJobObject(platform, appJSON, args, credentials, sdkVersion),
|
||||
...await buildJobObject(cmd, platform, projectConfig, args, credentials, sdkVersion),
|
||||
...cmd.buildDir && { fakeUploadDir: ProjectUtils.resolveAbsoluteDir(cmd.buildDir) },
|
||||
...cmd.output && { fakeUploadBuildPath: ProjectUtils.resolveAbsoluteDir(cmd.output) },
|
||||
};
|
||||
@@ -97,9 +97,9 @@ export function createBuilderAction({
|
||||
};
|
||||
}
|
||||
|
||||
function getExpoSDKVersionSafely(projectDir: string, appJSON?: any) {
|
||||
function getExpoSDKVersionSafely(projectDir: string, projectConfig: ProjectConfig) {
|
||||
try {
|
||||
return getExpoSDKVersion(projectDir, appJSON && appJSON.expo);
|
||||
return getExpoSDKVersion(projectDir, projectConfig.exp);
|
||||
} catch (err) {
|
||||
if (err instanceof ConfigError) {
|
||||
throw new Error(
|
||||
@@ -113,22 +113,25 @@ function getExpoSDKVersionSafely(projectDir: string, appJSON?: any) {
|
||||
}
|
||||
|
||||
const buildJobObject = async (
|
||||
cmd: any,
|
||||
platform: 'android' | 'ios',
|
||||
appJSON: any,
|
||||
projectConfig: ProjectConfig,
|
||||
{ releaseChannel, buildType, buildMode, username, publicUrl, projectDir }: any,
|
||||
credentials: any,
|
||||
sdkVersion: string,
|
||||
) => {
|
||||
const experienceName = `@${_.get(appJSON, 'expo.owner', username)}/${_.get(appJSON, 'expo.slug')}`;
|
||||
const owner = projectConfig.exp.owner || username;
|
||||
const experienceName = `@${owner}/${projectConfig.exp.slug}`;
|
||||
const job = {
|
||||
config: {
|
||||
..._.get(appJSON, `expo.${platform}.config`, {}),
|
||||
...(projectConfig.exp?.[platform]?.config || {}),
|
||||
buildType,
|
||||
...(platform === 'android' ? { buildMode } : {}),
|
||||
releaseChannel,
|
||||
...(platform === 'ios' ? { bundleIdentifier: _.get(appJSON, 'expo.ios.bundleIdentifier') } : {}),
|
||||
...(platform === 'android' ? { androidPackage: _.get(appJSON, 'expo.android.package') } : {}),
|
||||
publicUrl,
|
||||
...(platform === 'android' && cmd.gradleArgs ? { gradleArgs: cmd.gradleArgs.split(' ') } : {}),
|
||||
...(platform === 'android' ? { buildMode } : {}),
|
||||
...(platform === 'android' ? { androidPackage: projectConfig.exp?.android?.package } : {}),
|
||||
...(platform === 'ios' ? { bundleIdentifier: projectConfig.exp?.ios?.bundleIdentifier } : {}),
|
||||
},
|
||||
id: uuid.v4(),
|
||||
platform,
|
||||
|
||||
+11
-13
@@ -1,20 +1,18 @@
|
||||
import fs from 'fs-extra';
|
||||
import path from 'path';
|
||||
|
||||
export async function loadAppJSON(projectDirArg: string, config: string | null) {
|
||||
let appJSONPath;
|
||||
import { getConfig as getProjectConfig, setCustomConfigPath } from '@expo/config';
|
||||
import fs from 'fs-extra';
|
||||
|
||||
export async function getConfig(projectDir: string, config: string | null) {
|
||||
projectDir = resolveAbsoluteDir(projectDir);
|
||||
if (config) {
|
||||
appJSONPath = resolveAbsoluteDir(config);
|
||||
} else {
|
||||
const projectDir = resolveAbsoluteDir(projectDirArg);
|
||||
appJSONPath = path.join(projectDir, 'app.json');
|
||||
}
|
||||
const appJSONExists = await fs.pathExists(appJSONPath);
|
||||
if (!appJSONExists) {
|
||||
throw new Error(`Couldn't find app.json.`);
|
||||
} else {
|
||||
return require(appJSONPath);
|
||||
const pathToConfig = path.resolve(process.cwd(), config);
|
||||
if (!await fs.pathExists(pathToConfig)) {
|
||||
throw new Error(`File at provided config path does not exist: ${pathToConfig}`);
|
||||
}
|
||||
setCustomConfigPath(projectDir, pathToConfig);
|
||||
}
|
||||
return await getProjectConfig(projectDir, {});
|
||||
}
|
||||
|
||||
export const resolveAbsoluteDir = (dir: string) => {
|
||||
|
||||
@@ -34,8 +34,8 @@ export default async function buildAndroid(jobData: IJob): Promise<IJobResult> {
|
||||
...config.builder.fakeUpload && {
|
||||
fakeUploadBuildPath:
|
||||
jobData.fakeUploadBuildPath
|
||||
? jobData.fakeUploadBuildPath
|
||||
: path.join(jobData.fakeUploadDir || config.directories.fakeUploadDir, fakeUploadFilename),
|
||||
? jobData.fakeUploadBuildPath
|
||||
: path.join(jobData.fakeUploadDir || config.directories.fakeUploadDir, fakeUploadFilename),
|
||||
},
|
||||
});
|
||||
|
||||
@@ -103,6 +103,7 @@ async function runShellAppBuilder(
|
||||
modules: enabledModules,
|
||||
buildType: jobData.config.buildType,
|
||||
buildMode: jobData.config.buildMode,
|
||||
gradleArgs: jobData.config.gradleArgs,
|
||||
});
|
||||
} catch (err) {
|
||||
commonUtils.logErrorOnce(err);
|
||||
|
||||
@@ -15,6 +15,7 @@ export interface IJob {
|
||||
// android
|
||||
androidPackage?: string;
|
||||
buildMode?: ANDROID_BUILD_MODES;
|
||||
gradleArgs?: string[];
|
||||
};
|
||||
credentials: {
|
||||
// android
|
||||
|
||||
@@ -15,6 +15,7 @@ export default baseJobSchema.concat(
|
||||
config: Joi.object().keys({
|
||||
buildMode: Joi.string().valid(Object.values(ANDROID_BUILD_MODES)).default(ANDROID_BUILD_MODES.RELEASE),
|
||||
buildType: Joi.string().valid(Object.values(ANDROID_BUILD_TYPES)).default(ANDROID_BUILD_TYPES.APK),
|
||||
gradleArgs: Joi.array().items(Joi.string()),
|
||||
}),
|
||||
}),
|
||||
);
|
||||
Reference in new issue
Block a user