mirror of
https://github.com/expo/turtle.git
synced 2026-11-14 19:12:55 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
81ef40da92 |
No files matched your search
+1
-22
@@ -5,35 +5,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [0.8.2] - 2019-06-11
|
||||
### Changed
|
||||
- Updated Android shell app for SDK33 to remove `expo-face-detector` and `expo-payments-stripe` from standalone builds.
|
||||
- Updated Android shell app for SDK33 to get rid of `node_modules` for `tools-public`.
|
||||
- From now on, `turtle-cli` installs dependencies for `tools-public` in shell apps for SDK versions < 33.
|
||||
### Fixed
|
||||
- Android builds with turtle-cli by installing all unmodules if `dependencies` is empty.
|
||||
|
||||
## [0.8.1] - 2019-06-10
|
||||
### Changed
|
||||
- Add expo dependencies when resolving unimodules.
|
||||
### Fixed
|
||||
- Support for Android tarballs without `universe-package.json`.
|
||||
|
||||
## [0.8.0] - 2019-06-07
|
||||
### Added
|
||||
- Turtle CLI logo to the project (created by [@zularizal](https://github.com/zularizal))!
|
||||
- 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.
|
||||
- Updated Android shell app for SDK 32 to fix AppAuth issue (https://github.com/expo/expo/pull/4115).
|
||||
- Default value for build timeout to 15 minutes.
|
||||
- Added filtering of logs (strips out download progress) when downloading SDK tools.
|
||||
- `xdl` -> `@expo/xdl`, updated `@expo/xdl`.
|
||||
### Fixed
|
||||
- Generating Android keystore in turtle when one is not passed to turtle-cli (https://github.com/expo/turtle/pull/65).
|
||||
- Upload logs to s3 if build has been canceled or timed out.
|
||||
- Unhandled exception on asset download (xdl).
|
||||
|
||||
## [0.7.2] - 2019-05-09
|
||||
### Added
|
||||
|
||||
+20
-12
@@ -20,7 +20,6 @@ RUN dpkg --add-architecture i386 && \
|
||||
libc6:i386\
|
||||
libncurses5:i386\
|
||||
libstdc++6:i386\
|
||||
rsync\
|
||||
unzip\
|
||||
yarn\
|
||||
zlib1g:i386\
|
||||
@@ -51,8 +50,20 @@ ENV PATH ${ANDROID_HOME}/tools:${PATH}
|
||||
ENV PATH ${ANDROID_HOME}/tools/bin:${PATH}
|
||||
ENV PATH ${ANDROID_HOME}/build-tools/28.0.3/:${PATH}
|
||||
|
||||
ADD scripts/cli/configureAndroidSdk.sh /tmp/configureAndroidSdk.sh
|
||||
RUN /tmp/configureAndroidSdk.sh
|
||||
RUN yes | sdkmanager --licenses > /dev/null
|
||||
RUN yes | sdkmanager \
|
||||
"platforms;android-23" \
|
||||
"platforms;android-24" \
|
||||
"platforms;android-25" \
|
||||
"platforms;android-26" \
|
||||
"platforms;android-27" \
|
||||
"platforms;android-28"
|
||||
RUN yes | sdkmanager "platform-tools"
|
||||
RUN yes | sdkmanager "build-tools;28.0.3"
|
||||
RUN yes | sdkmanager \
|
||||
"extras;android;m2repository" \
|
||||
"extras;google;m2repository" \
|
||||
"extras;google;google_play_services"
|
||||
|
||||
# Install Android NDK
|
||||
ENV ANDROID_NDK_VERSION android-ndk-r10e
|
||||
@@ -88,11 +99,9 @@ RUN rm gradle-4.4-all.zip
|
||||
ENV GRADLE_HOME /usr/local/gradle-4.4
|
||||
ENV PATH ${GRADLE_HOME}/bin:$PATH
|
||||
|
||||
ADD . /app/turtle
|
||||
ADD . /app
|
||||
|
||||
RUN mv /app/turtle/workingdir /app && \
|
||||
for SDK_VERSION in `ls /app/workingdir/android/`; do \
|
||||
echo "preparing $SDK_VERSION shell app" && \
|
||||
RUN for SDK_VERSION in `ls /app/workingdir/android/`; do \
|
||||
cd /app/workingdir/android/$SDK_VERSION && \
|
||||
if [ -f universe-package.json ]; then \
|
||||
mv package.json exponent-package.json && \
|
||||
@@ -103,12 +112,11 @@ RUN mv /app/turtle/workingdir /app && \
|
||||
else \
|
||||
yarn install; \
|
||||
fi \
|
||||
; done && \
|
||||
mv /app/workingdir /app/turtle
|
||||
; done
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
ENV NODE_ENV "production"
|
||||
ENV TURTLE_WORKING_DIR_PATH /app/turtle/workingdir/
|
||||
|
||||
WORKDIR /app/turtle
|
||||
ENV TURTLE_WORKING_DIR_PATH /app/workingdir/
|
||||
|
||||
CMD ["node", "./build/server.js"]
|
||||
@@ -22,7 +22,7 @@ spec:
|
||||
environment: ${NAMESPACE}
|
||||
spec:
|
||||
restartPolicy: Always
|
||||
terminationGracePeriodSeconds: 1200 ## wait 20 minutes for any builds to complete
|
||||
terminationGracePeriodSeconds: 1800 ## wait 30 minutes for any builds to complete
|
||||
tolerations:
|
||||
- key: dedicated
|
||||
operator: Equal
|
||||
@@ -128,16 +128,6 @@ spec:
|
||||
secretKeyRef:
|
||||
name: turtle-js-config
|
||||
key: api_port
|
||||
- name: DATADOG_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: turtle-js-config
|
||||
key: datadog_api_key
|
||||
- name: DATADOG_APP_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: turtle-js-config
|
||||
key: datadog_app_key
|
||||
# other vars
|
||||
- name: GRADLE_DAEMON_DISABLED
|
||||
value: "1"
|
||||
|
||||
+5
-6
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "turtle-cli",
|
||||
"version": "0.8.2",
|
||||
"version": "0.7.2",
|
||||
"description": "The command-line tool for building standalone Expo apps",
|
||||
"preferGlobal": true,
|
||||
"scripts": {
|
||||
@@ -83,7 +83,7 @@
|
||||
"@types/fs-extra": "^5.0.4",
|
||||
"@types/jest": "^23.3.9",
|
||||
"@types/joi": "^13.4.3",
|
||||
"@types/lodash": "^4.14.129",
|
||||
"@types/lodash": "^4.14.109",
|
||||
"@types/progress": "^2.0.1",
|
||||
"@types/raven": "^2.5.1",
|
||||
"@types/request": "^2.47.1",
|
||||
@@ -110,7 +110,6 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@expo/spawn-async": "^1.4.2",
|
||||
"@expo/xdl": "54.1.4",
|
||||
"@google-cloud/logging-bunyan": "^0.9.5",
|
||||
"async-retry": "^1.2.1",
|
||||
"aws-sdk": "^2.226.1",
|
||||
@@ -120,12 +119,11 @@
|
||||
"commander": "^2.15.1",
|
||||
"copy": "^0.3.1",
|
||||
"decompress": "^4.2.0",
|
||||
"dogapi": "^2.8.3",
|
||||
"fs-extra": "^6.0.0",
|
||||
"ioredis": "^3.2.2",
|
||||
"is-semver": "^1.0.8",
|
||||
"joi": "^13.2.0",
|
||||
"lodash": "^4.17.11",
|
||||
"lodash": "^4.17.10",
|
||||
"progress": "^2.0.0",
|
||||
"raven": "^2.6.2",
|
||||
"request": "^2.88.0",
|
||||
@@ -135,7 +133,8 @@
|
||||
"source-map-support": "^0.5.6",
|
||||
"tar": "^4.4.6",
|
||||
"uuid": "^3.2.1",
|
||||
"which": "^1.3.1"
|
||||
"which": "^1.3.1",
|
||||
"xdl": "53.7.3"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@expo/traveling-fastlane-darwin": "1.9.4"
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#!/usr/bin/env bash
|
||||
#!/bin/bash
|
||||
|
||||
SDKMANAGER=$ANDROID_HOME/tools/bin/sdkmanager
|
||||
|
||||
yes | $SDKMANAGER --licenses > /dev/null
|
||||
yes | $SDKMANAGER "platforms;android-28" | grep -v '='; [[ ${PIPESTATUS[1]} = 0 ]]
|
||||
yes | $SDKMANAGER "platform-tools" | grep -v '='; [[ ${PIPESTATUS[1]} = 0 ]]
|
||||
yes | $SDKMANAGER "build-tools;28.0.3" | grep -v '='; [[ ${PIPESTATUS[1]} = 0 ]]
|
||||
yes | $SDKMANAGER "platforms;android-28"
|
||||
yes | $SDKMANAGER "platform-tools"
|
||||
yes | $SDKMANAGER "build-tools;28.0.3"
|
||||
yes | $SDKMANAGER \
|
||||
"extras;android;m2repository" \
|
||||
"extras;google;m2repository" \
|
||||
"extras;google;google_play_services" | grep -v '='; [[ ${PIPESTATUS[1]} = 0 ]]
|
||||
"extras;google;google_play_services"
|
||||
@@ -61,10 +61,6 @@ setup_remote() {
|
||||
mv $sdk/package.json $sdk/exponent-package.json
|
||||
mv $sdk/universe-package.json $sdk/package.json
|
||||
cd $sdk && yarn
|
||||
else
|
||||
if [[ -f "$sdk/package.json" ]]; then
|
||||
cd $sdk && yarn
|
||||
fi
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
@@ -21,6 +21,5 @@ export API_HOSTNAME="staging.expo.io"
|
||||
export API_PORT="443"
|
||||
export REDIS_URL="noop"
|
||||
export REDIS_CONFIG_URL="noop"
|
||||
export DATADOG_DISABLED="true"
|
||||
|
||||
yarn test:smoke:android
|
||||
@@ -19,7 +19,6 @@ export API_HOSTNAME="staging.expo.io"
|
||||
export API_PORT="443"
|
||||
export REDIS_URL="noop"
|
||||
export REDIS_CONFIG_URL="noop"
|
||||
export DATADOG_DISABLED="true"
|
||||
|
||||
ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )"/../.. && pwd )"
|
||||
SDK_VERSION=sdk32 $ROOT_DIR/scripts/ios/fetchRemoteIosTarball.sh
|
||||
|
||||
@@ -21,6 +21,5 @@ export API_HOSTNAME="noop"
|
||||
export API_PORT="443"
|
||||
export REDIS_URL="noop"
|
||||
export REDIS_CONFIG_URL="noop"
|
||||
export DATADOG_DISABLED="true"
|
||||
|
||||
yarn test:unit
|
||||
@@ -0,0 +1 @@
|
||||
s3://exp-artifacts/android-shell-builder-c19ce0d88a153f481fd790e23bdcd6f2d5ea7fd6.tar.gz
|
||||
@@ -1 +1 @@
|
||||
s3://exp-artifacts/android-shell-builder-f796aaffa0b5715079b2950faf26c2ff4e53e4c0.tar.gz
|
||||
s3://exp-artifacts/android-shell-builder-c4ba6f73ab341afa378732f863e261a10fc71356.tar.gz
|
||||
@@ -1 +0,0 @@
|
||||
s3://exp-artifacts/android-shell-builder-e244e865ed8cb8e20d29ea00b6373845d1c61068.tar.gz
|
||||
@@ -1 +1 @@
|
||||
s3://exp-artifacts/ios-expo-client-a2b1e16f330b36fa0dc627a76caabe4d2ff45f77.tar.gz
|
||||
s3://exp-artifacts/ios-expo-client-15bb883c22173d5b01df19421580170e776041d0.tar.gz
|
||||
@@ -0,0 +1 @@
|
||||
s3://exp-artifacts/ios-shell-builder-sdk-26-db356a09877642d64023af98e4e2e1e632fbe4df.tar.gz
|
||||
@@ -1 +0,0 @@
|
||||
s3://exp-artifacts/ios-shell-builder-sdk-latest-a2b1e16f330b36fa0dc627a76caabe4d2ff45f77.tar.gz
|
||||
@@ -13,28 +13,3 @@ export const TYPE_DIMENSIONS = (type: string) => [
|
||||
{ Name: 'host', Value: config.hostname },
|
||||
],
|
||||
];
|
||||
|
||||
export const PRIORITY_DIMENSIONS = (type: string, priority: string) => [
|
||||
[
|
||||
{ Name: 'env', Value: config.deploymentEnv },
|
||||
{ Name: 'platform', Value: config.platform },
|
||||
{ Name: 'priority', Value: priority },
|
||||
],
|
||||
[
|
||||
{ Name: 'env', Value: config.deploymentEnv },
|
||||
{ Name: 'platform', Value: config.platform },
|
||||
{ Name: 'type', Value: type },
|
||||
],
|
||||
[
|
||||
{ Name: 'env', Value: config.deploymentEnv },
|
||||
{ Name: 'platform', Value: config.platform },
|
||||
{ Name: 'type', Value: type },
|
||||
{ Name: 'priority', Value: priority },
|
||||
],
|
||||
[
|
||||
{ Name: 'env', Value: config.deploymentEnv },
|
||||
{ Name: 'platform', Value: config.platform },
|
||||
{ Name: 'type', Value: type },
|
||||
{ Name: 'host', Value: config.hostname },
|
||||
],
|
||||
];
|
||||
@@ -15,18 +15,11 @@ 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 or App Bundle for your project, signed and ready for submission to the Google Play'
|
||||
+ ' Store.',
|
||||
'Build a standalone APK for your project, signed and ready for submission to the Google Play Store.',
|
||||
)
|
||||
.asyncAction(
|
||||
createBuilderAction({
|
||||
@@ -41,17 +34,12 @@ export default (program: any, setCommonCommandOptions: any) => {
|
||||
);
|
||||
};
|
||||
|
||||
const buildJobObject = (
|
||||
appJSON: any,
|
||||
{ releaseChannel, username, projectDir, publicUrl, buildType }: any,
|
||||
credentials: any,
|
||||
) => ({
|
||||
const buildJobObject = (appJSON: any, { releaseChannel, username, projectDir, publicUrl }: any, credentials: any) => ({
|
||||
config: {
|
||||
..._.get(appJSON, 'expo.android.config', {}),
|
||||
releaseChannel,
|
||||
androidPackage: _.get(appJSON, 'expo.android.package'),
|
||||
publicUrl,
|
||||
buildType,
|
||||
},
|
||||
id: uuid.v4(),
|
||||
platform: PLATFORMS.ANDROID,
|
||||
|
||||
@@ -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_BUILD_TYPES, PLATFORMS } from 'turtle/constants';
|
||||
import { IOS, PLATFORMS } from 'turtle/constants';
|
||||
|
||||
export default (program: any, setCommonCommandOptions: any) => {
|
||||
const command = program.command('build:ios [project-dir]');
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1,8 +1,8 @@
|
||||
import path from 'path';
|
||||
|
||||
import { LoggerDetach, ModuleVersion } from '@expo/xdl';
|
||||
import program, { Command } from 'commander';
|
||||
import fs from 'fs-extra';
|
||||
import { LoggerDetach, ModuleVersion } from 'xdl';
|
||||
|
||||
import * as commands from 'turtle/bin/commands';
|
||||
import logger from 'turtle/logger';
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import path from 'path';
|
||||
import util from 'util';
|
||||
|
||||
import { ExponentTools } from '@expo/xdl';
|
||||
import fs from 'fs-extra';
|
||||
import _which from 'which';
|
||||
import { ExponentTools } from 'xdl';
|
||||
|
||||
import ensureAndroidNDKIsPresent from 'turtle/bin/setup/android/ndk';
|
||||
import ensureAndroidSDKIsPresent from 'turtle/bin/setup/android/sdk';
|
||||
@@ -67,26 +67,18 @@ function formatShellAppTarballUriPath(sdkMajorVersion: string) {
|
||||
return path.join(config.directories.shellTarballsDir, PLATFORMS.ANDROID, `sdk${sdkMajorVersion}`);
|
||||
}
|
||||
|
||||
async function _shellAppPostDownloadAction(sdkVersion: string, workingdir: string) {
|
||||
async function _shellAppPostDownloadAction(workingdir: string) {
|
||||
const inWorkingdir = (filename: string) => path.join(workingdir, filename);
|
||||
|
||||
if (await fs.pathExists(inWorkingdir('universe-package.json'))) {
|
||||
// legacy shell app built from universe
|
||||
await fs.move(inWorkingdir('package.json'), inWorkingdir('exponent-package.json'));
|
||||
await fs.move(inWorkingdir('universe-package.json'), inWorkingdir('package.json'));
|
||||
await _installNodeModules(workingdir);
|
||||
await fs.move(inWorkingdir('package.json'), inWorkingdir('universe-package.json'));
|
||||
await fs.move(inWorkingdir('exponent-package.json'), inWorkingdir('package.json'));
|
||||
} else {
|
||||
// new shell app built from expo or not
|
||||
await _installNodeModules(workingdir);
|
||||
}
|
||||
await fs.move(inWorkingdir('package.json'), inWorkingdir('exponent-package.json'));
|
||||
await fs.move(inWorkingdir('universe-package.json'), inWorkingdir('package.json'));
|
||||
await _installNodeModules(workingdir);
|
||||
await fs.move(inWorkingdir('package.json'), inWorkingdir('universe-package.json'));
|
||||
await fs.move(inWorkingdir('exponent-package.json'), inWorkingdir('package.json'));
|
||||
|
||||
// TODO: remove this after making sure that we don't need node_modules in tools-public for older sdks
|
||||
if (ExponentTools.parseSdkMajorVersion(sdkVersion) < 33) {
|
||||
const toolsPublicDir = path.join(workingdir, 'tools-public');
|
||||
await _installNodeModules(toolsPublicDir);
|
||||
}
|
||||
// TODO: remove following lines after upgrading android shell app
|
||||
const toolsPublicDir = path.join(workingdir, 'tools-public');
|
||||
await _installNodeModules(toolsPublicDir);
|
||||
}
|
||||
|
||||
async function _installNodeModules(cwd: string) {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import os from 'os';
|
||||
import path from 'path';
|
||||
|
||||
import { ExponentTools } from '@expo/xdl';
|
||||
import decompress from 'decompress';
|
||||
import fs from 'fs-extra';
|
||||
import { ExponentTools } from 'xdl';
|
||||
|
||||
import { formatArtifactDownloadPath } from 'turtle/bin/setup/utils/common';
|
||||
import download from 'turtle/bin/setup/utils/downloader';
|
||||
|
||||
@@ -3,7 +3,7 @@ import trim from 'lodash/trim';
|
||||
import path from 'path';
|
||||
import semver from 'semver';
|
||||
|
||||
import { ExponentTools } from '@expo/xdl';
|
||||
import { ExponentTools } from 'xdl';
|
||||
|
||||
import { checkSystem, ensureShellAppIsPresent } from 'turtle/bin/setup/utils/common';
|
||||
import { IToolDefinition } from 'turtle/bin/setup/utils/toolsDetector';
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import path from 'path';
|
||||
|
||||
import { ExponentTools } from '@expo/xdl';
|
||||
import fs from 'fs-extra';
|
||||
import tar from 'tar';
|
||||
import { ExponentTools } from 'xdl';
|
||||
|
||||
import download from 'turtle/bin/setup/utils/downloader';
|
||||
import { ensureToolsAreInstalled, IToolDefinition } from 'turtle/bin/setup/utils/toolsDetector';
|
||||
@@ -17,7 +17,7 @@ interface IShellAppFormaters {
|
||||
formatShellAppTarballUriPath: (sdkMajorVersion: string) => string;
|
||||
}
|
||||
|
||||
type PostDownloadAction = (sdkVersion: string, workingdir: string) => void;
|
||||
type PostDownloadAction = (workingdir: string) => void;
|
||||
|
||||
export async function checkSystem(requiredTools: IToolDefinition[]) {
|
||||
await ensureToolsAreInstalled(requiredTools);
|
||||
@@ -35,7 +35,7 @@ export async function ensureShellAppIsPresent(
|
||||
l.info(`shell app for SDK ${sdkVersion} doesn't exist, downloading...`);
|
||||
await _downloadShellApp(sdkVersion, workingdir, formatters);
|
||||
if (postDownloadAction) {
|
||||
await postDownloadAction(sdkVersion, workingdir);
|
||||
await postDownloadAction(workingdir);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { User as UserManager } from '@expo/xdl';
|
||||
import { User as UserManager } from 'xdl';
|
||||
|
||||
import { ErrorWithProgramHelp } from 'turtle/bin/commands/ErrorWithProgramHelp';
|
||||
|
||||
|
||||
+6
-12
@@ -1,11 +1,10 @@
|
||||
import path from 'path';
|
||||
|
||||
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 { AndroidShellApp, ImageUtils } from 'xdl';
|
||||
|
||||
import getOrCreateCredentials from 'turtle/builders/utils/android/credentials';
|
||||
import { formatShellAppDirectory } from 'turtle/builders/utils/android/workingdir';
|
||||
@@ -21,16 +20,13 @@ import logger from 'turtle/logger';
|
||||
export default async function buildAndroid(jobData: IJob): Promise<IJobResult> {
|
||||
await ensureCanBuildSdkVersion(jobData);
|
||||
const credentials = await getOrCreateCredentials(jobData);
|
||||
const outputFilePath = await runShellAppBuilder(jobData, credentials);
|
||||
|
||||
const apkFilePath = await runShellAppBuilder(jobData, credentials);
|
||||
const randomHex = uuidv4().replace(/-/g, '');
|
||||
const s3FileExtension = jobData.config.buildType === ANDROID_BUILD_TYPES.APP_BUNDLE ? 'aab' : 'apk';
|
||||
const s3Filename = `${jobData.experienceName}-${randomHex}-signed.${s3FileExtension}`;
|
||||
const s3Filename = `${jobData.experienceName}-${randomHex}-signed.apk`;
|
||||
const s3FileKey = `android/${s3Filename}`;
|
||||
const fakeUploadFilename = s3Filename.replace('/', '\\');
|
||||
|
||||
const artifactUrl = await uploadBuildToS3({
|
||||
uploadPath: outputFilePath,
|
||||
uploadPath: apkFilePath,
|
||||
s3FileKey,
|
||||
...config.builder.fakeUpload && {
|
||||
fakeUploadBuildPath:
|
||||
@@ -66,8 +62,7 @@ async function runShellAppBuilder(
|
||||
ImageUtils.setResizeImageFunction(imageHelpers.resizeIconWithSharpAsync);
|
||||
ImageUtils.setGetImageDimensionsFunction(imageHelpers.getImageDimensionsWithSharpAsync);
|
||||
|
||||
const fileExtension = jobData.config.buildType === ANDROID_BUILD_TYPES.APP_BUNDLE ? 'aab' : 'apk';
|
||||
const outputFilePath = path.join(temporaryFilesRoot, `shell-signed-${jobData.id}.${fileExtension}`);
|
||||
const outputFilePath = path.join(temporaryFilesRoot, `shell-signed-${jobData.id}.apk`);
|
||||
|
||||
const { config: jobConfig, manifest, sdkVersion: sdkVersionFromJob } = jobData;
|
||||
const sdkVersion = _.get(manifest, 'sdkVersion', sdkVersionFromJob);
|
||||
@@ -75,7 +70,7 @@ async function runShellAppBuilder(
|
||||
|
||||
logger.info({ buildPhase: 'resolve native modules' }, 'Resolving universal modules dependencies');
|
||||
const enabledModules = semver.satisfies(sdkVersion, '>= 33.0.0')
|
||||
? await resolveNativeModules(workingDir, manifest && manifest.dependencies)
|
||||
? await resolveNativeModules(workingDir, manifest.dependencies)
|
||||
: null;
|
||||
|
||||
try {
|
||||
@@ -92,7 +87,6 @@ async function runShellAppBuilder(
|
||||
workingDir,
|
||||
outputFile: outputFilePath,
|
||||
modules: enabledModules,
|
||||
buildType: jobData.config.buildType,
|
||||
});
|
||||
} catch (err) {
|
||||
commonUtils.logErrorOnce(err);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { IosIPABuilder as createIPABuilder } from '@expo/xdl';
|
||||
import _ from 'lodash';
|
||||
import { IosIPABuilder as createIPABuilder } from 'xdl';
|
||||
|
||||
import { IContext } from 'turtle/builders/ios/context';
|
||||
import { logErrorOnce } from 'turtle/builders/utils/common';
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import * as path from 'path';
|
||||
|
||||
import { IosShellApp } from '@expo/xdl';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { IosShellApp } from 'xdl';
|
||||
|
||||
import { formatShellAppDirectory } from 'turtle/builders/utils/ios/workingdir';
|
||||
import config from 'turtle/config';
|
||||
import { IOS_BUILD_TYPES, PLATFORMS } from 'turtle/constants/index';
|
||||
import { IOS, PLATFORMS } from 'turtle/constants/index';
|
||||
import { IJob } from 'turtle/job';
|
||||
|
||||
export interface IContext {
|
||||
@@ -27,6 +27,7 @@ export interface IContext {
|
||||
}
|
||||
|
||||
const { EXPOKIT_APP, EXPONENT_APP } = IosShellApp;
|
||||
const { BUILD_TYPES } = IOS;
|
||||
|
||||
export function createBuilderContext(job: IJob): IContext {
|
||||
const { join } = path;
|
||||
@@ -56,7 +57,7 @@ export function createBuilderContext(job: IJob): IContext {
|
||||
context.tempCertPath = join(context.appDir, 'cert.p12');
|
||||
context.baseArchiveDir = join(context.appDir, 'archive');
|
||||
|
||||
if (buildType === IOS_BUILD_TYPES.CLIENT) {
|
||||
if (buildType === BUILD_TYPES.CLIENT) {
|
||||
context.applicationFilesSrc = join(
|
||||
workingDir,
|
||||
'expo-client-build',
|
||||
@@ -73,7 +74,7 @@ export function createBuilderContext(job: IJob): IContext {
|
||||
);
|
||||
}
|
||||
|
||||
if (buildType === IOS_BUILD_TYPES.ARCHIVE) {
|
||||
if (buildType === BUILD_TYPES.ARCHIVE) {
|
||||
context.outputPath = join(context.appDir, 'archive.xcarchive');
|
||||
context.uploadPath = join(context.buildDir, 'archive.ipa');
|
||||
context.archiveDir = join(
|
||||
@@ -91,7 +92,7 @@ export function createBuilderContext(job: IJob): IContext {
|
||||
'default',
|
||||
`${EXPOKIT_APP}.xcworkspace`,
|
||||
);
|
||||
} else if (buildType === IOS_BUILD_TYPES.CLIENT) {
|
||||
} else if (buildType === BUILD_TYPES.CLIENT) {
|
||||
context.outputPath = join(context.appDir, 'archive.xcarchive');
|
||||
context.uploadPath = join(context.buildDir, 'archive.ipa');
|
||||
context.archiveDir = join(
|
||||
@@ -106,7 +107,7 @@ export function createBuilderContext(job: IJob): IContext {
|
||||
'ios',
|
||||
`${EXPONENT_APP}.xcworkspace`,
|
||||
);
|
||||
} else if (buildType === IOS_BUILD_TYPES.SIMULATOR) {
|
||||
} else if (buildType === BUILD_TYPES.SIMULATOR) {
|
||||
context.outputPath = join(context.appDir, 'archive.tar.gz');
|
||||
context.uploadPath = join(context.appDir, 'archive.tar.gz');
|
||||
context.archiveDir = join(
|
||||
@@ -116,7 +117,7 @@ export function createBuilderContext(job: IJob): IContext {
|
||||
);
|
||||
}
|
||||
|
||||
const s3FileExtension = buildType === IOS_BUILD_TYPES.SIMULATOR ? 'tar.gz' : 'ipa';
|
||||
const s3FileExtension = buildType === BUILD_TYPES.SIMULATOR ? 'tar.gz' : 'ipa';
|
||||
const s3Filename = `${job.experienceName}-${appUUID}-${buildType}.${s3FileExtension}`;
|
||||
if (config.builder.fakeUpload) {
|
||||
const fakeUploadFilename = s3Filename.replace('/', '\\');
|
||||
|
||||
@@ -9,11 +9,13 @@ 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_BUILD_TYPES } from 'turtle/constants';
|
||||
import { IOS } from 'turtle/constants/index';
|
||||
import { IJob, IJobResult } from 'turtle/job';
|
||||
|
||||
const { BUILD_TYPES } = IOS;
|
||||
|
||||
export default async function iosBuilder(job: IJob): Promise<IJobResult> {
|
||||
if (job.config.buildType !== IOS_BUILD_TYPES.CLIENT) {
|
||||
if (job.config.buildType !== BUILD_TYPES.CLIENT) {
|
||||
await ensureCanBuildSdkVersion(job);
|
||||
}
|
||||
|
||||
@@ -24,13 +26,13 @@ export default async function iosBuilder(job: IJob): Promise<IJobResult> {
|
||||
|
||||
const { buildType } = job.config;
|
||||
|
||||
if (buildType === IOS_BUILD_TYPES.CLIENT) {
|
||||
if (buildType === BUILD_TYPES.CLIENT) {
|
||||
await prepareAdHocBuildCredentials(job);
|
||||
}
|
||||
|
||||
if ([IOS_BUILD_TYPES.ARCHIVE, IOS_BUILD_TYPES.CLIENT].includes(buildType!)) {
|
||||
if ([BUILD_TYPES.ARCHIVE, BUILD_TYPES.CLIENT].includes(buildType!)) {
|
||||
await buildArchive(ctx, job);
|
||||
} else if (buildType === IOS_BUILD_TYPES.SIMULATOR) {
|
||||
} else if (buildType === BUILD_TYPES.SIMULATOR) {
|
||||
await buildSimulator(ctx, job);
|
||||
} else {
|
||||
throw new Error(`Unsupported iOS build type: ${buildType}`);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import path from 'path';
|
||||
|
||||
import { Credentials } from '@expo/xdl';
|
||||
import fs from 'fs-extra';
|
||||
import get from 'lodash/get';
|
||||
import uuidv4 from 'uuid/v4';
|
||||
import { Credentials } from 'xdl';
|
||||
|
||||
import * as sqs from 'turtle/aws/sqs';
|
||||
import { UPDATE_CREDENTIALS } from 'turtle/constants/build';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import path from 'path';
|
||||
|
||||
import { ExponentTools } from '@expo/xdl';
|
||||
import { ExponentTools } from 'xdl';
|
||||
|
||||
import { IShellAppDirectoryConfig } from 'turtle/builders/utils/workingdir';
|
||||
import config from 'turtle/config';
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import path from 'path';
|
||||
|
||||
import spawnAsync from '@expo/spawn-async';
|
||||
import { IosCodeSigning } from '@expo/xdl';
|
||||
import fs from 'fs-extra';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
import { IosCodeSigning } from 'xdl';
|
||||
|
||||
import * as sqs from 'turtle/aws/sqs';
|
||||
import BuildError, { BuildErrorReason } from 'turtle/builders/BuildError';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { IosKeychain } from '@expo/xdl';
|
||||
import { IosKeychain } from 'xdl';
|
||||
|
||||
import { IContext } from 'turtle/builders/ios/context';
|
||||
import * as fileUtils from 'turtle/builders/utils/file';
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import path from 'path';
|
||||
import util from 'util';
|
||||
|
||||
import { ImageUtils, IosShellApp } from '@expo/xdl';
|
||||
import copy from 'copy';
|
||||
import _ from 'lodash';
|
||||
import { ImageUtils, IosShellApp } from 'xdl';
|
||||
|
||||
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_BUILD_TYPES } from 'turtle/constants/index';
|
||||
import { IOS } from 'turtle/constants/index';
|
||||
import { IJob } from 'turtle/job';
|
||||
import logger from 'turtle/logger/index';
|
||||
|
||||
@@ -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'),
|
||||
});
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import path from 'path';
|
||||
|
||||
import { ExponentTools } from '@expo/xdl';
|
||||
import { ExponentTools } from 'xdl';
|
||||
|
||||
import { IShellAppDirectoryConfig } from 'turtle/builders/utils/workingdir';
|
||||
import config from 'turtle/config';
|
||||
import { IOS_BUILD_TYPES, PLATFORMS } from 'turtle/constants';
|
||||
import { IOS, 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');
|
||||
|
||||
@@ -44,11 +44,9 @@ export async function resolveNativeModules(workingdir: string, packages?: string
|
||||
|
||||
async function readCorePackages(workingdir: string) {
|
||||
const pkgJsonPath = path.join(workingdir, 'node_modules', 'react-native-unimodules', 'package.json');
|
||||
const expoPkgJsonPath = path.join(workingdir, 'packages', 'expo', 'package.json');
|
||||
if (await fs.pathExists(pkgJsonPath) && await fs.pathExists(expoPkgJsonPath)) {
|
||||
if (await fs.pathExists(pkgJsonPath)) {
|
||||
const packageJson = JSON.parse(await fs.readFile(pkgJsonPath, 'utf-8'));
|
||||
const expoPackageJson = JSON.parse(await fs.readFile(expoPkgJsonPath, 'utf-8'));
|
||||
return keys(packageJson.dependencies).concat(keys(expoPackageJson.dependencies));
|
||||
return keys(packageJson.dependencies);
|
||||
} else {
|
||||
logger.warn('No core packages detected');
|
||||
return [];
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ExponentTools } from '@expo/xdl';
|
||||
import fs from 'fs-extra';
|
||||
import path from 'path';
|
||||
import { ExponentTools } from 'xdl';
|
||||
|
||||
import config from 'turtle/config';
|
||||
import { IJob } from 'turtle/job';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ANDROID_BUILD_TYPES, IOS_BUILD_TYPES } from 'turtle/constants';
|
||||
import { IOS } from 'turtle/constants';
|
||||
|
||||
export interface IShellAppDirectoryConfig {
|
||||
sdkVersion: string;
|
||||
buildType?: IOS_BUILD_TYPES & ANDROID_BUILD_TYPES;
|
||||
buildType?: IOS.BUILD_TYPES;
|
||||
}
|
||||
+1
-7
@@ -2,7 +2,7 @@ import os from 'os';
|
||||
import path from 'path';
|
||||
|
||||
import { PLATFORMS } from 'turtle/constants';
|
||||
import { env, envBoolean, envNum, envOptional, envTransform } from 'turtle/utils/env';
|
||||
import { env, envNum, envOptional, envTransform } from 'turtle/utils/env';
|
||||
|
||||
export default {
|
||||
env: env('NODE_ENV'),
|
||||
@@ -37,12 +37,6 @@ export default {
|
||||
intervalMs: envNum('AWS_CLOUDWATCH_INTERVAL_MS', 30000),
|
||||
namespace: env('AWS_CLOUDWATCH_NAMESPACE', 'Turtle'),
|
||||
},
|
||||
datadog: {
|
||||
disabled: envBoolean('DATADOG_DISABLED', false),
|
||||
apiKey: envOptional('DATADOG_API_KEY'),
|
||||
appKey: envOptional('DATADOG_APP_KEY'),
|
||||
intervalMs: env('DATADOG_INTERVAL_MS', 5 * 60 * 1000),
|
||||
},
|
||||
redis: {
|
||||
url: env('REDIS_URL'),
|
||||
configUrl: env('REDIS_CONFIG_URL'),
|
||||
|
||||
+2
-12
@@ -1,19 +1,9 @@
|
||||
import * as BUILD from './build';
|
||||
import * as IOS from './ios';
|
||||
|
||||
export enum PLATFORMS {
|
||||
IOS = 'ios',
|
||||
ANDROID = 'android',
|
||||
}
|
||||
|
||||
export enum IOS_BUILD_TYPES {
|
||||
ARCHIVE = 'archive',
|
||||
CLIENT = 'client',
|
||||
SIMULATOR = 'simulator',
|
||||
}
|
||||
|
||||
export enum ANDROID_BUILD_TYPES {
|
||||
APK = 'apk',
|
||||
APP_BUNDLE = 'app-bundle',
|
||||
}
|
||||
|
||||
export { BUILD };
|
||||
export { IOS, BUILD };
|
||||
@@ -0,0 +1,5 @@
|
||||
export enum BUILD_TYPES {
|
||||
ARCHIVE = 'archive',
|
||||
CLIENT = 'client',
|
||||
SIMULATOR = 'simulator',
|
||||
}
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
import { ANDROID_BUILD_TYPES, IOS_BUILD_TYPES } from 'turtle/constants';
|
||||
import { IOS } from 'turtle/constants';
|
||||
|
||||
export interface IJob {
|
||||
platform: 'android' | 'ios';
|
||||
@@ -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;
|
||||
|
||||
+2
-2
@@ -76,10 +76,10 @@ async function processJob(jobData: any) {
|
||||
const buildType = _.get(job, 'config.buildType', 'default');
|
||||
try {
|
||||
const status = await build(job);
|
||||
buildStatusMetric.add(buildType, priority, status);
|
||||
buildStatusMetric.add(buildType, status);
|
||||
buildFailed = !status;
|
||||
} catch (err) {
|
||||
buildStatusMetric.add(buildType, priority, false);
|
||||
buildStatusMetric.add(buildType, false);
|
||||
buildFailed = true;
|
||||
throw err;
|
||||
} finally {
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import Joi from 'joi';
|
||||
|
||||
import { IOS_BUILD_TYPES, PLATFORMS } from 'turtle/constants/index';
|
||||
import { IOS, 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()
|
||||
@@ -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(),
|
||||
}),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as cloudwatch from 'turtle/aws/cloudwatch';
|
||||
import { PRIORITY_DIMENSIONS } from 'turtle/aws/cloudwatch/dimensions';
|
||||
import { TYPE_DIMENSIONS } from 'turtle/aws/cloudwatch/dimensions';
|
||||
import * as reducers from 'turtle/aws/cloudwatch/reducers';
|
||||
import config from 'turtle/config';
|
||||
import logger from 'turtle/logger';
|
||||
@@ -24,11 +24,11 @@ export function register() {
|
||||
});
|
||||
}
|
||||
|
||||
export function add(type: string, priority: string, success = true) {
|
||||
export function add(type: string, success = true) {
|
||||
cloudwatch.addMetricData({
|
||||
name: BUILD_METRIC_NAME,
|
||||
value: 1,
|
||||
success,
|
||||
extraDimensions: PRIORITY_DIMENSIONS(type, priority),
|
||||
extraDimensions: TYPE_DIMENSIONS(type),
|
||||
});
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
import groupBy from 'lodash/groupBy';
|
||||
import mapValues from 'lodash/mapValues';
|
||||
import take from 'lodash/take';
|
||||
|
||||
import logger from 'turtle/logger';
|
||||
import { sendMetric } from 'turtle/metrics/datadog';
|
||||
import { getReplicaCount } from 'turtle/utils/metadata';
|
||||
import { getLabeledConfiguration, TurtleModeLabels } from 'turtle/utils/priorities';
|
||||
|
||||
const createMetricName = () => `turtle.replicaCount`;
|
||||
const createModeMetricName = (mode: TurtleModeLabels) => `${createMetricName()}.${mode}`;
|
||||
const createModeTag = (mode: TurtleModeLabels) => `mode:${mode}`;
|
||||
|
||||
export default async function sendConfigToDatadog() {
|
||||
const configuration = await getLabeledConfiguration();
|
||||
const replicaCount = await getReplicaCount();
|
||||
const currentReplicaCount = replicaCount === null ? configuration.length : replicaCount;
|
||||
|
||||
const replicaCounts = mapValues(
|
||||
groupBy<string>(take(configuration, currentReplicaCount)),
|
||||
(i) => i.length,
|
||||
);
|
||||
|
||||
const metricName = createMetricName();
|
||||
|
||||
const normalReplicaCount = replicaCounts[TurtleModeLabels.Normal] || 0;
|
||||
const highReplicaCount = replicaCounts[TurtleModeLabels.High] || 0;
|
||||
const highOnlyReplicaCount = replicaCounts[TurtleModeLabels.HighOnly] || 0;
|
||||
|
||||
const normalTag = createModeTag(TurtleModeLabels.Normal);
|
||||
const normalMetricName = createModeMetricName(TurtleModeLabels.Normal);
|
||||
logger.debug(
|
||||
`Sending ${metricName}=${normalReplicaCount} (${normalTag}), ${normalMetricName}=${normalReplicaCount} to Datadog`,
|
||||
);
|
||||
await sendMetric(metricName, normalReplicaCount, [normalTag]);
|
||||
await sendMetric(normalMetricName, normalReplicaCount);
|
||||
|
||||
const highTag = createModeTag(TurtleModeLabels.High);
|
||||
const highMetricName = createModeMetricName(TurtleModeLabels.High);
|
||||
logger.debug(
|
||||
`Sending ${metricName}=${highReplicaCount} (${highTag}), ${highMetricName}=${highReplicaCount} to Datadog`,
|
||||
);
|
||||
await sendMetric(metricName, highReplicaCount, [highTag]);
|
||||
await sendMetric(highMetricName, highReplicaCount);
|
||||
|
||||
const highOnlyTag = createModeTag(TurtleModeLabels.HighOnly);
|
||||
const highOnlyMetricName = createModeMetricName(TurtleModeLabels.HighOnly);
|
||||
logger.debug(
|
||||
`Sending ${metricName}=${highOnlyReplicaCount} (${highOnlyTag}),`
|
||||
+ ` ${highOnlyMetricName}=${highOnlyReplicaCount} to Datadog`,
|
||||
);
|
||||
await sendMetric(metricName, highOnlyReplicaCount, [highOnlyTag]);
|
||||
await sendMetric(highOnlyMetricName, highOnlyReplicaCount);
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
import dogapi from 'dogapi';
|
||||
import util from 'util';
|
||||
|
||||
import config from 'turtle/config';
|
||||
|
||||
const datadogSendMetric = util.promisify(dogapi.metric.send);
|
||||
|
||||
if (!config.datadog.disabled) {
|
||||
dogapi.initialize({
|
||||
api_key: config.datadog.apiKey,
|
||||
app_key: config.datadog.appKey,
|
||||
});
|
||||
}
|
||||
|
||||
const tags = [
|
||||
`env:${config.deploymentEnv}`,
|
||||
`platform:${config.platform}`,
|
||||
];
|
||||
|
||||
export function sendMetric(name: string, value: number, additionalTags?: string[]) {
|
||||
if (!config.datadog.disabled) {
|
||||
return datadogSendMetric(name, value, { tags: [...tags, ...(additionalTags || [])] });
|
||||
}
|
||||
}
|
||||
@@ -43,13 +43,13 @@ const AVAILABLE_CONFIGURATIONS_ANDROID = [
|
||||
HIGH_CONFIGURATION,
|
||||
HIGH_CONFIGURATION,
|
||||
HIGH_CONFIGURATION,
|
||||
HIGH_CONFIGURATION,
|
||||
HIGH_CONFIGURATION,
|
||||
HIGH_CONFIGURATION,
|
||||
HIGH_CONFIGURATION,
|
||||
HIGH_CONFIGURATION,
|
||||
HIGH_CONFIGURATION,
|
||||
HIGH_CONFIGURATION,
|
||||
HIGH_ONLY_CONFIGURATION,
|
||||
HIGH_ONLY_CONFIGURATION,
|
||||
HIGH_ONLY_CONFIGURATION,
|
||||
HIGH_ONLY_CONFIGURATION,
|
||||
HIGH_ONLY_CONFIGURATION,
|
||||
HIGH_ONLY_CONFIGURATION,
|
||||
HIGH_ONLY_CONFIGURATION,
|
||||
HIGH_CONFIGURATION,
|
||||
HIGH_CONFIGURATION,
|
||||
HIGH_CONFIGURATION,
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import isNaN from 'lodash/isNaN';
|
||||
|
||||
import { PLATFORMS } from 'turtle/constants';
|
||||
import logger from 'turtle/logger';
|
||||
import { setReplicaCount } from 'turtle/utils/metadata';
|
||||
import { getRedisClient, RedisClient } from 'turtle/utils/redis';
|
||||
import { connect, RedisClient } from 'turtle/utils/redis';
|
||||
|
||||
const REDIS_CONNECTION_TIMEOUT = 10000;
|
||||
|
||||
async function run() {
|
||||
const platform = process.env.SCRIPT_PLATFORM;
|
||||
@@ -22,9 +23,11 @@ async function run() {
|
||||
throw new Error(`Wrong value for replica count: ${replicaCountRaw}`);
|
||||
}
|
||||
|
||||
const redis = await getRedisClient(RedisClient.Configuration);
|
||||
const redis = await connect(REDIS_CONNECTION_TIMEOUT, RedisClient.Configuration);
|
||||
logger.info(`[${platform}] Setting replica count in redis to ${replicaCount}`);
|
||||
await setReplicaCount(platform as PLATFORMS, replicaCount);
|
||||
|
||||
await setReplicaCount(redis, platform as PLATFORMS, replicaCount);
|
||||
|
||||
redis.disconnect();
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import { LoggerDetach } from '@expo/xdl';
|
||||
import { LoggerDetach } from 'xdl';
|
||||
|
||||
import config from 'turtle/config';
|
||||
import { doJob } from 'turtle/jobManager';
|
||||
|
||||
@@ -1,23 +1,10 @@
|
||||
import fs from 'fs-extra';
|
||||
|
||||
import config from 'turtle/config';
|
||||
import logger from 'turtle/logger';
|
||||
import * as metrics from 'turtle/metrics';
|
||||
import sendConfigToDatadog from 'turtle/metrics/buildersConfig';
|
||||
|
||||
export default async function commonSetup() {
|
||||
announceBuildersConfig();
|
||||
await metrics.init();
|
||||
await fs.remove(config.directories.temporaryFilesRoot);
|
||||
await fs.remove(config.directories.tempS3LogsDir);
|
||||
}
|
||||
|
||||
async function announceBuildersConfig() {
|
||||
try {
|
||||
await sendConfigToDatadog();
|
||||
} catch (err) {
|
||||
logger.error({ err }, 'Failed to send metrics to Datadog');
|
||||
} finally {
|
||||
setTimeout(announceBuildersConfig, config.datadog.intervalMs);
|
||||
}
|
||||
}
|
||||
Vendored
+4
-5
@@ -1,10 +1,9 @@
|
||||
declare module 'async-retry';
|
||||
declare module 'copy';
|
||||
declare module 'xdl';
|
||||
declare module 'bunyan';
|
||||
declare module 'bunyan-sentry-stream';
|
||||
declare module 'bunyan-debug-stream';
|
||||
declare module 'copy';
|
||||
declare module 'dogapi';
|
||||
declare module 'async-retry';
|
||||
declare module 'ioredis';
|
||||
declare module 'is-semver';
|
||||
declare module 'request-progress';
|
||||
declare module '@expo/xdl';
|
||||
declare module 'is-semver';
|
||||
@@ -16,16 +16,5 @@ export const env = (varName: string, defaultValue?: any) => {
|
||||
export const envOptional = (varName: string) => env(varName, null);
|
||||
export const envTransform = (varName: string, defaultValue: any, fn: any) => fn(env(varName, defaultValue));
|
||||
export const envNum = (varName: string, defaultValue?: number) => parseInt(env(varName, defaultValue), 10);
|
||||
export const envBoolean = (varName: string, defaultValue?: boolean) => {
|
||||
let defaultString;
|
||||
if (defaultValue === true) {
|
||||
defaultString = 'true';
|
||||
} else if (defaultValue === false) {
|
||||
defaultString = 'false';
|
||||
} else {
|
||||
defaultString = defaultValue;
|
||||
}
|
||||
return env(varName, defaultString) === 'true';
|
||||
};
|
||||
|
||||
const isOffline = () => process.env.TURTLE_MODE === 'offline';
|
||||
+1
-10
@@ -1,21 +1,12 @@
|
||||
import config from 'turtle/config';
|
||||
import { PLATFORMS } from 'turtle/constants';
|
||||
import { getRedisClient, RedisClient } from 'turtle/utils/redis';
|
||||
|
||||
const createKeyPrefix = (platform: PLATFORMS) => `${config.deploymentEnv}:${platform}`;
|
||||
const createReplicaCountKey = (platform: PLATFORMS) => `${createKeyPrefix(platform)}:replicaCount`;
|
||||
|
||||
export async function setReplicaCount(platform: PLATFORMS, replicaCount: number) {
|
||||
const redis = await getRedisClient(RedisClient.Configuration);
|
||||
export async function setReplicaCount(redis: any, platform: PLATFORMS, replicaCount: number) {
|
||||
await redis.set(
|
||||
createReplicaCountKey(platform),
|
||||
replicaCount,
|
||||
);
|
||||
}
|
||||
|
||||
export async function getReplicaCount(maybePlatform?: PLATFORMS) {
|
||||
const platform = maybePlatform || config.platform;
|
||||
const redis = await getRedisClient(RedisClient.Configuration);
|
||||
const result = await redis.get(createReplicaCountKey(platform));
|
||||
return result === null ? null : Number(result);
|
||||
}
|
||||
+1
-26
@@ -1,5 +1,4 @@
|
||||
import Joi from 'joi';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
import os from 'os';
|
||||
|
||||
import config from 'turtle/config';
|
||||
@@ -9,12 +8,6 @@ import { getRedisClient, RedisClient } from 'turtle/utils/redis';
|
||||
export const NORMAL = 'normalPriority';
|
||||
export const HIGH = 'highPriority';
|
||||
|
||||
export enum TurtleModeLabels {
|
||||
Normal = 'normal',
|
||||
High = 'high',
|
||||
HighOnly = 'highOnly',
|
||||
}
|
||||
|
||||
export const NORMAL_CONFIGURATION = [NORMAL, HIGH];
|
||||
export const HIGH_CONFIGURATION = [HIGH, NORMAL];
|
||||
export const HIGH_ONLY_CONFIGURATION = [HIGH];
|
||||
@@ -63,7 +56,7 @@ export async function getPriorities() {
|
||||
}
|
||||
|
||||
try {
|
||||
const configurations = await getConfiguration(redis);
|
||||
const configurations = JSON.parse(await redis.get(createConfigurationsKey()));
|
||||
const configurationsIndex = await redis.getConfig(createConfigurationsKey(), os.hostname());
|
||||
logger.debug(`Using configuration at index ${configurationsIndex} pulled from redis`);
|
||||
const { error, value: configValue } = configSchema.validate(configurations[configurationsIndex]);
|
||||
@@ -92,21 +85,3 @@ export async function getPriorities() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function getConfiguration(currentRedisClient: any) {
|
||||
const redis = currentRedisClient || await getRedisClient(RedisClient.Configuration);
|
||||
return JSON.parse(await redis.get(createConfigurationsKey()));
|
||||
}
|
||||
|
||||
export async function getLabeledConfiguration(currentRedisClient?: any) {
|
||||
const configuration = await getConfiguration(currentRedisClient);
|
||||
return configuration.map((i: string[]) => {
|
||||
if (isEqual(i, NORMAL_CONFIGURATION)) {
|
||||
return TurtleModeLabels.Normal;
|
||||
} else if (isEqual(i, HIGH_CONFIGURATION)) {
|
||||
return TurtleModeLabels.High;
|
||||
} else {
|
||||
return TurtleModeLabels.HighOnly;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -919,24 +919,22 @@
|
||||
mv "~2"
|
||||
safe-json-stringify "~1"
|
||||
|
||||
"@expo/config@^2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@expo/config/-/config-2.0.0.tgz#7fe6a5dd84524875d478451932393e202d026be0"
|
||||
integrity sha512-wtwAI5O01pSP8sk0z1FfC2XdnMjcMl2QohpPJ+u8nmFrpGfr4Fro+GCnPGJUDjhQXTebvvARVFawJtjLmcyZgA==
|
||||
"@expo/config@^1.0.4":
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@expo/config/-/config-1.0.4.tgz#d615f4a24f617f42ba3664bf28bb0b381084335e"
|
||||
integrity sha512-LcyOAWMRHnXmKs8q6J9ajmEdhJoqceHrA9wmNoOYcytJCM+iP0o+o3Z3t0JDGMRYppHBhnjRPmIB08TFyh+T9g==
|
||||
dependencies:
|
||||
"@expo/json-file" "^8.1.4"
|
||||
find-yarn-workspace-root "^1.2.1"
|
||||
"@expo/json-file" "^8.1.2"
|
||||
fs-extra "^7.0.1"
|
||||
resolve-from "^5.0.0"
|
||||
resolve-from "^4.0.0"
|
||||
slugify "^1.3.4"
|
||||
|
||||
"@expo/json-file@^8.1.4":
|
||||
version "8.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@expo/json-file/-/json-file-8.1.4.tgz#160f68a2ad08a1c1a34e9edfef6e87293ce0a6ac"
|
||||
integrity sha512-0M6Hq2+iNV+wqc9hSffa05NgTwqmg08TVhpUSSBuHjOscYw2gxMi8JbTJ1v6fg5NqRW1AOga8mZb6Py8SE/b+g==
|
||||
"@expo/json-file@^8.1.2":
|
||||
version "8.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@expo/json-file/-/json-file-8.1.2.tgz#e05710fc6c09f3fadcbf57bd7ebc6ab8461c0195"
|
||||
integrity sha512-JA57pKlRpWZ11YwpPSBhtcNWdDFkcxpn+12LAqKMP9ZHGiu7UNchBNdGMGL7xcsJR8tZhG+UoR0svF8TqQTZ/A==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.0.0-beta.44"
|
||||
fs-extra "^8.0.1"
|
||||
json5 "^1.0.1"
|
||||
lodash "^4.17.4"
|
||||
util.promisify "^1.0.0"
|
||||
@@ -1026,18 +1024,19 @@
|
||||
request "^2.81.0"
|
||||
uuid "^3.0.0"
|
||||
|
||||
"@expo/osascript@^2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@expo/osascript/-/osascript-2.0.0.tgz#b7108c4fab7bf0f3b64c2295a0c9241e47b4dbef"
|
||||
integrity sha512-xlj+WQJ9bMMWu2XNfsJy9gyO2+ytxvfd19Wdi6YGouB3MUSqIzU9JlxnBi6pvAW0aPWJuldC5da5GWIU5mFX0g==
|
||||
"@expo/osascript@^1.9.2":
|
||||
version "1.9.2"
|
||||
resolved "https://registry.yarnpkg.com/@expo/osascript/-/osascript-1.9.2.tgz#09de523a07d38e5cefca0db55ac7984e5d5776ca"
|
||||
integrity sha512-jsT+Nauqp+ZnWsTJEPSPYImJzGY1L22cQEmaOZvWzgc6MTdBgfWG9KoKVHvn3WvPYHio7sOMk1zGocM1CW95LQ==
|
||||
dependencies:
|
||||
"@expo/spawn-async" "^1.5.0"
|
||||
"@expo/spawn-async" "^1.2.8"
|
||||
babel-runtime "^6.23.0"
|
||||
exec-async "^2.2.0"
|
||||
|
||||
"@expo/schemer@^1.2.5":
|
||||
version "1.2.5"
|
||||
resolved "https://registry.yarnpkg.com/@expo/schemer/-/schemer-1.2.5.tgz#f2d457ee7aeae3edf29dd98d3dfa84af6b11dfc3"
|
||||
integrity sha512-j74QDjk5gka5yeIgdiBFg1YQB3upnOedct6Ji8K1+iIQ1OErN4grf1YxCH/v81rhrsbBjKT5wgn0eKH7wqdsRw==
|
||||
"@expo/schemer@^1.2.4":
|
||||
version "1.2.4"
|
||||
resolved "https://registry.yarnpkg.com/@expo/schemer/-/schemer-1.2.4.tgz#b54296add1a0d6bdffa706cd9747f5ba28773def"
|
||||
integrity sha512-mc6FAknziXnh5vu/RKD7LKp9qPwOTlGSFcu3foR+eoDHg2OZNeQKVMoGv0eQHtQOoYQj1XGm4R3rPCV1aT9Whg==
|
||||
dependencies:
|
||||
ajv "^5.2.2"
|
||||
babel-polyfill "^6.23.0"
|
||||
@@ -1048,34 +1047,35 @@
|
||||
probe-image-size "^3.1.0"
|
||||
read-chunk "^2.0.0"
|
||||
|
||||
"@expo/spawn-async@1.5.0", "@expo/spawn-async@^1.5.0":
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@expo/spawn-async/-/spawn-async-1.5.0.tgz#799827edd8c10ef07eb1a2ff9dcfe081d596a395"
|
||||
integrity sha512-LB7jWkqrHo+5fJHNrLAFdimuSXQ2MQ4lA7SQW5bf/HbsXuV2VrT/jN/M8f/KoWt0uJMGN4k/j7Opx4AvOOxSew==
|
||||
dependencies:
|
||||
cross-spawn "^6.0.5"
|
||||
|
||||
"@expo/spawn-async@^1.4.2":
|
||||
"@expo/spawn-async@1.4.2", "@expo/spawn-async@^1.4.2":
|
||||
version "1.4.2"
|
||||
resolved "https://registry.yarnpkg.com/@expo/spawn-async/-/spawn-async-1.4.2.tgz#334b28215e3850071cede3a23d898f977904e01a"
|
||||
integrity sha512-afevfRz0S/R63MfAVQstrowC/M5cwWdIKkim4wqFSYmnvOejq8B8RAeWZ0lKimPmP2QfuvA/FG2L0SzonrHTKQ==
|
||||
dependencies:
|
||||
cross-spawn "^6.0.5"
|
||||
|
||||
"@expo/spawn-async@^1.2.8":
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@expo/spawn-async/-/spawn-async-1.4.0.tgz#39f7777bdee22e1f48d03898c9ed2f150a7f4cbd"
|
||||
integrity sha512-jE9zSZ14eOfKxXs+WJZofweKtsAeuQiOpntsb+zp8Ti9/wk+9ZjKkffdld7UfANr8asmzuJYnEoVyL+hMy3SWw==
|
||||
dependencies:
|
||||
"@types/cross-spawn" "^6.0.0"
|
||||
cross-spawn "^6.0.5"
|
||||
|
||||
"@expo/[email protected]":
|
||||
version "1.9.4"
|
||||
resolved "https://registry.yarnpkg.com/@expo/traveling-fastlane-darwin/-/traveling-fastlane-darwin-1.9.4.tgz#29b370a6d6e115e69c4c4ea53003d679779b4592"
|
||||
integrity sha512-bKw/sRPd0gXyzXhrvU9ewhav6FXstQC/g9P9ulf3x0Y2bxNYu7g1zv3hrNJxVbKx0DsFMzXqesV8HD8mU6jwrw==
|
||||
|
||||
"@expo/webpack-config@^0.5.8":
|
||||
version "0.5.8"
|
||||
resolved "https://registry.yarnpkg.com/@expo/webpack-config/-/webpack-config-0.5.8.tgz#eb03e7d00cb21acb82c1ebe25e0c2d13145c0037"
|
||||
integrity sha512-ItLjs17nvuumaJz7uLZkaRE3UbDRuJgZIhgB/kouU6gm+faDMMVc9OPNAL7J7CW3RAB15Luyy4cRTStWSwAzhQ==
|
||||
"@expo/webpack-config@^0.5.6":
|
||||
version "0.5.6"
|
||||
resolved "https://registry.yarnpkg.com/@expo/webpack-config/-/webpack-config-0.5.6.tgz#476229b6cc854d041415cef6c84f8dd1f51a0007"
|
||||
integrity sha512-4Whn6eCs+gxLBaKuIKpkMG1VJyddffoKDljQXXFI+25H6nTL5JDASCbW3OyKzVwdWbBraUI8xJYZ7AcpEZH6yg==
|
||||
dependencies:
|
||||
"@babel/core" "^7.0.0"
|
||||
"@babel/polyfill" "^7.2.5"
|
||||
"@babel/runtime" "^7.3.4"
|
||||
"@expo/config" "^2.0.0"
|
||||
"@expo/config" "^1.0.4"
|
||||
"@expo/webpack-pwa-manifest-plugin" "^1.0.5"
|
||||
babel-loader "^8.0.5"
|
||||
babel-preset-expo "^5.1.1"
|
||||
@@ -1116,80 +1116,6 @@
|
||||
jimp "^0.6.0"
|
||||
mime "^2.4.0"
|
||||
|
||||
"@expo/[email protected]":
|
||||
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"
|
||||
"@expo/json-file" "^8.1.4"
|
||||
"@expo/ngrok" "2.4.3"
|
||||
"@expo/osascript" "^2.0.0"
|
||||
"@expo/schemer" "^1.2.5"
|
||||
"@expo/spawn-async" "1.5.0"
|
||||
"@expo/webpack-config" "^0.5.8"
|
||||
analytics-node "^2.1.0"
|
||||
axios v0.19.0-beta.1
|
||||
chalk "2.4.1"
|
||||
concat-stream "1.6.2"
|
||||
decache "4.4.0"
|
||||
delay-async "1.1.0"
|
||||
es6-error "4.1.1"
|
||||
escape-string-regexp "1.0.5"
|
||||
express "4.16.4"
|
||||
form-data "2.3.2"
|
||||
freeport-async "1.1.1"
|
||||
fs-extra "6.0.1"
|
||||
getenv "0.7.0"
|
||||
glob "7.1.2"
|
||||
glob-promise "3.4.0"
|
||||
globby "6.1.0"
|
||||
hasbin "1.2.3"
|
||||
hashids "1.1.4"
|
||||
home-dir "1.0.0"
|
||||
idx "2.4.0"
|
||||
indent-string "3.2.0"
|
||||
inquirer "5.2.0"
|
||||
invariant "2.2.4"
|
||||
joi "14.0.4"
|
||||
latest-version "4.0.0"
|
||||
lodash "4.17.10"
|
||||
md5hex "1.0.0"
|
||||
minimatch "3.0.4"
|
||||
minipass "2.3.5"
|
||||
mv "2.1.1"
|
||||
ncp "2.0.0"
|
||||
node-forge "0.7.6"
|
||||
opn "5.4.0"
|
||||
p-timeout "2.0.1"
|
||||
pacote "9.3.0"
|
||||
plist "2.1.0"
|
||||
probe-image-size "^4.0.0"
|
||||
querystring "0.2.0"
|
||||
raven "2.6.3"
|
||||
read-chunk "2.1.0"
|
||||
read-last-lines "1.6.0"
|
||||
replace-string "1.1.0"
|
||||
request "2.88.0"
|
||||
request-promise-native "1.0.5"
|
||||
resolve-from "4.0.0"
|
||||
semver "5.5.0"
|
||||
sharp "^0.22.1"
|
||||
slugid "1.1.0"
|
||||
slugify "1.3.1"
|
||||
source-map-support "0.4.18"
|
||||
split "1.0.1"
|
||||
tar "4.4.6"
|
||||
tree-kill "1.2.0"
|
||||
url "0.11.0"
|
||||
url-join "4.0.0"
|
||||
util.promisify "1.0.0"
|
||||
uuid "3.3.2"
|
||||
webpack "4.24.0"
|
||||
webpack-dev-server "3.2.0"
|
||||
xmldom "0.1.27"
|
||||
|
||||
"@google-cloud/common-grpc@^0.10.0":
|
||||
version "0.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@google-cloud/common-grpc/-/common-grpc-0.10.0.tgz#ffb5723768e463a77ea3e5896f2fb9ebe55bcecb"
|
||||
@@ -1690,6 +1616,13 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/caseless/-/caseless-0.12.1.tgz#9794c69c8385d0192acc471a540d1f8e0d16218a"
|
||||
integrity sha512-FhlMa34NHp9K5MY1Uz8yb+ZvuX0pnvn3jScRSNAb75KHGB8d3rEU6hqMs3Z2vjuytcMfRg6c5CHMc3wtYyD2/A==
|
||||
|
||||
"@types/cross-spawn@^6.0.0":
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/cross-spawn/-/cross-spawn-6.0.0.tgz#320aaf1d1a12979f1b84fe7a5590a7e860bf3a80"
|
||||
integrity sha512-evp2ZGsFw9YKprDbg8ySgC9NA15g3YgiI8ANkGmKKvvi0P2aDGYLPxQIC5qfeKNUOe3TjABVGuah6omPRpIYhg==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/decompress@^4.2.3":
|
||||
version "4.2.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/decompress/-/decompress-4.2.3.tgz#98eed48af80001038aa05690b2094915f296fe65"
|
||||
@@ -1747,10 +1680,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
|
||||
integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4=
|
||||
|
||||
"@types/lodash@^4.14.129":
|
||||
version "4.14.129"
|
||||
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.129.tgz#9aaca391db126802482655c48dd79a814488202f"
|
||||
integrity sha512-oYaV0eSlnOacOr7i4X1FFdH8ttSlb57gu3I9MuStIv2CYkISEY84dNHYsC3bF6sNH7qYcu1BtVrCtQ8Q4KPTfQ==
|
||||
"@types/lodash@^4.14.109":
|
||||
version "4.14.121"
|
||||
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.121.tgz#9327e20d49b95fc2bf983fc2f045b2c6effc80b9"
|
||||
integrity sha512-ORj7IBWj13iYufXt/VXrCNMbUuCTJfhzme5kx9U/UtcIPdJYuvPDUAlHlbNhz/8lKCLy9XGIZnGrqXOtQbPGoQ==
|
||||
|
||||
"@types/long@^4.0.0":
|
||||
version "4.0.0"
|
||||
@@ -2679,7 +2612,7 @@ babel-register@^6.26.0:
|
||||
mkdirp "^0.5.1"
|
||||
source-map-support "^0.4.15"
|
||||
|
||||
babel-runtime@^6.22.0, babel-runtime@^6.26.0:
|
||||
babel-runtime@^6.22.0, babel-runtime@^6.23.0, babel-runtime@^6.26.0:
|
||||
version "6.26.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe"
|
||||
integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4=
|
||||
@@ -2793,11 +2726,6 @@ bignumber.js@^7.0.0:
|
||||
resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-7.2.1.tgz#80c048759d826800807c4bfd521e50edbba57a5f"
|
||||
integrity sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ==
|
||||
|
||||
bignumber.js@~1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-1.1.1.tgz#1a415d9ac014c13256af1feed9d1a3e5717a8cf7"
|
||||
integrity sha1-GkFdmsAUwTJWrx/u2dGj5XF6jPc=
|
||||
|
||||
binary-extensions@^1.0.0:
|
||||
version "1.13.0"
|
||||
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.0.tgz#9523e001306a32444b907423f1de2164222f6ab1"
|
||||
@@ -4844,17 +4772,6 @@ [email protected]:
|
||||
esutils "^1.1.6"
|
||||
isarray "0.0.1"
|
||||
|
||||
dogapi@^2.8.3:
|
||||
version "2.8.3"
|
||||
resolved "https://registry.yarnpkg.com/dogapi/-/dogapi-2.8.3.tgz#f7b2210bb03e17b54bd7c9fce7894152efc15481"
|
||||
integrity sha512-CzJIllAcv17H8hylyuljldJv+2EGal5+Fa+gsXFrXDo1zl8cq9jk7FDCXDqH4C/tPNAusS9ckV8wuBFtCiuTUg==
|
||||
dependencies:
|
||||
extend "^3.0.0"
|
||||
json-bigint "^0.1.4"
|
||||
lodash "^4.17.10"
|
||||
minimist "^1.1.1"
|
||||
rc "^1.2.8"
|
||||
|
||||
dom-converter@^0.2:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768"
|
||||
@@ -5898,15 +5815,6 @@ fs-extra@^7.0.0, fs-extra@^7.0.1:
|
||||
jsonfile "^4.0.0"
|
||||
universalify "^0.1.0"
|
||||
|
||||
fs-extra@^8.0.1:
|
||||
version "8.0.1"
|
||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.0.1.tgz#90294081f978b1f182f347a440a209154344285b"
|
||||
integrity sha512-W+XLrggcDzlle47X/XnS7FXrXu9sDo+Ze9zpndeBxdgv88FHLm1HtmkhEwavruS6koanBjp098rUpHs65EmG7A==
|
||||
dependencies:
|
||||
graceful-fs "^4.1.2"
|
||||
jsonfile "^4.0.0"
|
||||
universalify "^0.1.0"
|
||||
|
||||
fs-minipass@^1.2.5:
|
||||
version "1.2.5"
|
||||
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d"
|
||||
@@ -8165,13 +8073,6 @@ jsesc@~0.5.0:
|
||||
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d"
|
||||
integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=
|
||||
|
||||
json-bigint@^0.1.4:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/json-bigint/-/json-bigint-0.1.4.tgz#b5d40b8a9009e92f157f7c079db097001830e01e"
|
||||
integrity sha1-tdQLipAJ6S8Vf3wHnbCXABgw4B4=
|
||||
dependencies:
|
||||
bignumber.js "~1.1.1"
|
||||
|
||||
json-bigint@^0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/json-bigint/-/json-bigint-0.3.0.tgz#0ccd912c4b8270d05f056fbd13814b53d3825b1e"
|
||||
@@ -11219,7 +11120,7 @@ [email protected]:
|
||||
iconv-lite "0.4.23"
|
||||
unpipe "1.0.0"
|
||||
|
||||
rc@^1.0.1, rc@^1.1.6, rc@^1.2.7, rc@^1.2.8:
|
||||
rc@^1.0.1, rc@^1.1.6, rc@^1.2.7:
|
||||
version "1.2.8"
|
||||
resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
|
||||
integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==
|
||||
@@ -11723,7 +11624,7 @@ resolve-dir@^0.1.0:
|
||||
expand-tilde "^1.2.2"
|
||||
global-modules "^0.2.3"
|
||||
|
||||
[email protected]:
|
||||
[email protected], resolve-from@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
|
||||
integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
|
||||
@@ -11733,11 +11634,6 @@ resolve-from@^3.0.0:
|
||||
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748"
|
||||
integrity sha1-six699nWiBvItuZTM17rywoYh0g=
|
||||
|
||||
resolve-from@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69"
|
||||
integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==
|
||||
|
||||
resolve-url@^0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
|
||||
@@ -14224,6 +14120,80 @@ xdg-basedir@^3.0.0:
|
||||
resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4"
|
||||
integrity sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=
|
||||
|
||||
[email protected]:
|
||||
version "53.7.3"
|
||||
resolved "https://registry.yarnpkg.com/xdl/-/xdl-53.7.3.tgz#1fa227062a27a52951383d40f9d905d5a076fd73"
|
||||
integrity sha512-HDiz+AWQwLaf3HsP74eKlSPbVeuWRy3iRExtk8F5qlMaPoUUuWT7YqFERLjP+ynabavuh61Is9HNond5JMAd4A==
|
||||
dependencies:
|
||||
"@expo/bunyan" "3.0.2"
|
||||
"@expo/config" "^1.0.4"
|
||||
"@expo/json-file" "^8.1.2"
|
||||
"@expo/ngrok" "2.4.3"
|
||||
"@expo/osascript" "^1.9.2"
|
||||
"@expo/schemer" "^1.2.4"
|
||||
"@expo/spawn-async" "1.4.2"
|
||||
"@expo/webpack-config" "^0.5.6"
|
||||
analytics-node "^2.1.0"
|
||||
axios v0.19.0-beta.1
|
||||
chalk "2.4.1"
|
||||
concat-stream "1.6.2"
|
||||
decache "4.4.0"
|
||||
delay-async "1.1.0"
|
||||
es6-error "4.1.1"
|
||||
escape-string-regexp "1.0.5"
|
||||
express "4.16.4"
|
||||
form-data "2.3.2"
|
||||
freeport-async "1.1.1"
|
||||
fs-extra "6.0.1"
|
||||
getenv "0.7.0"
|
||||
glob "7.1.2"
|
||||
glob-promise "3.4.0"
|
||||
globby "6.1.0"
|
||||
hasbin "1.2.3"
|
||||
hashids "1.1.4"
|
||||
home-dir "1.0.0"
|
||||
idx "2.4.0"
|
||||
indent-string "3.2.0"
|
||||
inquirer "5.2.0"
|
||||
invariant "2.2.4"
|
||||
joi "14.0.4"
|
||||
latest-version "4.0.0"
|
||||
lodash "4.17.10"
|
||||
md5hex "1.0.0"
|
||||
minimatch "3.0.4"
|
||||
minipass "2.3.5"
|
||||
mv "2.1.1"
|
||||
ncp "2.0.0"
|
||||
node-forge "0.7.6"
|
||||
opn "5.4.0"
|
||||
p-timeout "2.0.1"
|
||||
pacote "9.3.0"
|
||||
plist "2.1.0"
|
||||
probe-image-size "^4.0.0"
|
||||
querystring "0.2.0"
|
||||
raven "2.6.3"
|
||||
read-chunk "2.1.0"
|
||||
read-last-lines "1.6.0"
|
||||
replace-string "1.1.0"
|
||||
request "2.88.0"
|
||||
request-promise-native "1.0.5"
|
||||
resolve-from "4.0.0"
|
||||
semver "5.5.0"
|
||||
sharp "^0.22.1"
|
||||
slugid "1.1.0"
|
||||
slugify "1.3.1"
|
||||
source-map-support "0.4.18"
|
||||
split "1.0.1"
|
||||
tar "4.4.6"
|
||||
tree-kill "1.2.0"
|
||||
url "0.11.0"
|
||||
url-join "4.0.0"
|
||||
util.promisify "1.0.0"
|
||||
uuid "3.3.2"
|
||||
webpack "4.24.0"
|
||||
webpack-dev-server "3.2.0"
|
||||
xmldom "0.1.27"
|
||||
|
||||
xhr@^2.0.1:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.5.0.tgz#bed8d1676d5ca36108667692b74b316c496e49dd"
|
||||
|
||||
Reference in new issue
Block a user