Skip to content

Commit

Permalink
feat(cli): --remoteExpoBuildScript flag (#22)
Browse files Browse the repository at this point in the history
  • Loading branch information
dawidk92 authored Jun 26, 2024
1 parent 3e97c50 commit 4faeff7
Show file tree
Hide file tree
Showing 12 changed files with 205 additions and 67 deletions.
21 changes: 12 additions & 9 deletions packages/action/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ async function run(): Promise<void> {
const projectRoot = getOptionalInput('projectRoot');
const config = getOptionalInput('config');
const android = getOptionalInput('android');
const overrideCommitName = getOptionalInput('commitName');
const ios = getOptionalInput('ios');
const async = getOptionalInput('async') === 'true';
const asyncBuildIndexString = getOptionalInput('asyncBuildIndex');
const asyncBuildIndex = asyncBuildIndexString ? Number(asyncBuildIndexString) : undefined;
const remoteExpo = getOptionalInput('remoteExpo');
const remoteExpoBuildScript = getOptionalInput('remoteExpoBuildScript');
const async = getOptionalInput('async');
const asyncBuildIndex = getOptionalInput('asyncBuildIndex');
const overrideCommitName = getOptionalInput('commitName');

const { context } = github;

Expand Down Expand Up @@ -44,13 +45,15 @@ async function run(): Promise<void> {
}

const { buildIndex, url } = await main({
android,
ios,
config,
async,
asyncBuildIndex,
projectRoot,
config,
token: emptyStringToUndefined(process.env.SHERLO_TOKEN), // Action returns an empty string if not defined
android,
ios,
remoteExpo: remoteExpo === 'true',
remoteExpoBuildScript,
async: async === 'true',
asyncBuildIndex: asyncBuildIndex ? Number(asyncBuildIndex) : undefined,
gitInfo,
});

Expand Down
4 changes: 2 additions & 2 deletions packages/cli/eas-hooks/eas-build-on-success.sh
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ if [[ "$EAS_BUILD_PROFILE" == "$SHERLO_BUILD_PROFILE" ]]; then
exit 0
fi

# Check for sherlo.json file
SHERLO_BUILD_FILE="./.expo/sherlo.json"
# Check for sherlo data temp file
SHERLO_BUILD_FILE="./.sherlo/data.json"
if [ ! -f "$SHERLO_BUILD_FILE" ]; then
echo "Error: File $SHERLO_BUILD_FILE does not exist. If you're using monorepo make sure to provide a valid 'projectRoot' option in CLI or Github Action"
exit 1
Expand Down
1 change: 1 addition & 0 deletions packages/cli/src/commands/main/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export const docsLink = {
configDevices: `${docsDomain}/getting-started/config#devices`,
devices: `${docsDomain}/devices`,
remoteExpoBuilds: `${docsDomain}/getting-started/builds?framework=expo&eas-build=remote`,
sherloScript: `${docsDomain}/getting-started/testing#sherlo-script`,
scriptFlags: `${docsDomain}/getting-started/testing#supported-flags`,
};

Expand Down
33 changes: 22 additions & 11 deletions packages/cli/src/commands/main/helpers/getArguments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,17 @@ import {
validateConfigToken,
} from './utils';

type ParameterDefaults = { config: string; projectRoot: string };
type Parameters<T extends 'default' | 'withDefaults' = 'default'> = {
token?: string;
token?: string; // only CLI
android?: string;
ios?: string;
remoteExpo?: boolean;
remoteExpoBuildScript?: string;
async?: boolean;
asyncBuildIndex?: number;
gitInfo?: Build['gitInfo']; // Can be passed only in GitHub Action
gitInfo?: Build['gitInfo']; // only GitHub Action
} & (T extends 'withDefaults' ? ParameterDefaults : Partial<ParameterDefaults>);
type ParameterDefaults = { config: string; projectRoot: string };

type Arguments = SyncArguments | AsyncInitArguments | AsyncUploadArguments;
type SyncArguments = {
Expand All @@ -32,11 +33,13 @@ type SyncArguments = {
gitInfo: Build['gitInfo'];
};
type AsyncInitArguments = {
mode: 'asyncInit' | 'remoteExpo';
mode: 'asyncInit';
token: string;
config: Config<'withoutBuildPaths'>;
gitInfo: Build['gitInfo'];
projectRoot: string;
remoteExpo: boolean | undefined;
remoteExpoBuildScript: string | undefined;
};
type AsyncUploadArguments = {
mode: 'asyncUpload';
Expand All @@ -55,9 +58,11 @@ function getArguments(githubActionParameters?: Parameters): Arguments {
const config = getConfig(configFile, parameters);

let mode: Mode = 'sync';
if (parameters.remoteExpo) {
mode = 'remoteExpo';
} else if (parameters.async && !parameters.asyncBuildIndex) {
if (
parameters.remoteExpo ||
parameters.remoteExpoBuildScript ||
(parameters.async && !parameters.asyncBuildIndex) // Allows to pass `asyncBuildIndex` along with `async` -> "asyncUpload" mode
) {
mode = 'asyncInit';
} else if (parameters.asyncBuildIndex) {
mode = 'asyncUpload';
Expand All @@ -80,7 +85,6 @@ function getArguments(githubActionParameters?: Parameters): Arguments {
} satisfies SyncArguments;
}

case 'remoteExpo':
case 'asyncInit': {
// validateConfigPlatforms(config, 'withoutBuildPaths');
validateConfigDevices(config);
Expand All @@ -92,6 +96,8 @@ function getArguments(githubActionParameters?: Parameters): Arguments {
config: config as Config<'withoutBuildPaths'>,
gitInfo: githubActionParameters?.gitInfo ?? getGitInfo(),
projectRoot: parameters.projectRoot,
remoteExpo: parameters.remoteExpo,
remoteExpoBuildScript: parameters.remoteExpoBuildScript,
} satisfies AsyncInitArguments;
}

Expand Down Expand Up @@ -128,14 +134,19 @@ const DEFAULT_PROJECT_ROOT = '.';

const command = new Command();
command
.name('sherlo')
.option('--token <token>', 'Project token')
.option('--android <path>', 'Path to Android build in .apk format')
.option('--ios <path>', 'Path to iOS build in .app (or compressed .tar.gz / .tar) format')
.option('--android <path>', 'Path to the Android build in .apk format')
.option('--ios <path>', 'Path to the iOS build in .app (or compressed .tar.gz / .tar) format')
.option('--config <path>', 'Config file path', DEFAULT_CONFIG_PATH)
.option('--projectRoot <path>', 'Root of the React Native project', DEFAULT_PROJECT_ROOT)
.option(
'--remoteExpoBuildScript <scriptName>',
'Run Sherlo in remote Expo mode, using the script from package.json to build the app on the Expo server. Temporary files will be auto-deleted.'
)
.option(
'--remoteExpo',
'Run Sherlo in remote Expo mode, waiting for the builds to complete on the Expo servers'
'Run Sherlo in remote Expo mode, waiting for you to manually build the app on the Expo server. Temporary files will not be auto-deleted.'
)
.option(
'--async',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ function validateConfigDevices(config: InvalidatedConfig): void {
const { devices } = config;

if (!devices || !Array.isArray(devices) || devices.length === 0) {
throw new Error(getConfigErrorMessage('devices must be a non-empty array', docsLink.devices));
throw new Error(getConfigErrorMessage('`devices` must be a non-empty array', docsLink.devices));
}

for (let i = 0; i < devices.length; i++) {
Expand All @@ -17,7 +17,7 @@ function validateConfigDevices(config: InvalidatedConfig): void {
if (!id || typeof id !== 'string' || !osVersion || typeof osVersion !== 'string') {
throw new Error(
getConfigErrorMessage(
'each device must have defined "id" and "osVersion" as strings',
'each device must have defined `id` and `osVersion` as strings',
docsLink.devices
)
);
Expand All @@ -40,7 +40,7 @@ function validateConfigDevices(config: InvalidatedConfig): void {

if (!osLanguage) {
throw new Error(
getConfigErrorMessage('device osLanguage must be defined', docsLink.configDevices)
getConfigErrorMessage('device `osLanguage` must be defined', docsLink.configDevices)
);
}

Expand All @@ -64,7 +64,7 @@ function validateConfigDevices(config: InvalidatedConfig): void {

if (!osTheme) {
throw new Error(
getConfigErrorMessage('device osTheme must be defined', docsLink.configDevices)
getConfigErrorMessage('device `osTheme` must be defined', docsLink.configDevices)
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ const fileType: { [platformName in Platform]: readonly string[] } = {
function validateConfigPlatformPath(path: string | undefined, platform: Platform): void {
if (!path || typeof path !== 'string') {
throw new Error(
getConfigErrorMessage(`${platform} must be a defined string`, learnMoreLink[platform])
getConfigErrorMessage(`\`${platform}\` must be a defined string`, learnMoreLink[platform])
);
}

if (!fs.existsSync(path) || !hasValidExtension({ path, platform })) {
throw new Error(
getConfigErrorMessage(
`${platform} path must point to an ${formatValidFileTypes(platform)} file`,
`\`${platform}\` path must point to an ${formatValidFileTypes(platform)} file`,
learnMoreLink[platform]
)
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ function validateConfigToken<T extends InvalidatedConfig>(
const { token } = config;

if (!token || typeof token !== 'string') {
throw new Error(getConfigErrorMessage('token must be a defined string', docsLink.configToken));
throw new Error(
getConfigErrorMessage('`token` must be a defined string', docsLink.configToken)
);
}

const { apiToken, projectIndex, teamId } = getTokenParts(token);
Expand All @@ -20,7 +22,7 @@ function validateConfigToken<T extends InvalidatedConfig>(
!Number.isInteger(projectIndex) ||
projectIndex < 1
) {
throw new Error(getConfigErrorMessage('token is not valid', docsLink.configToken));
throw new Error(getConfigErrorMessage('`token` is not valid', docsLink.configToken));
}
}

Expand Down
3 changes: 1 addition & 2 deletions packages/cli/src/commands/main/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@ async function main(githubActionParameters?: Parameters<typeof getArguments>[0])
return syncMode(args);
}

case 'remoteExpo':
case 'asyncInit': {
return asyncInitMode(args, args.mode === 'remoteExpo');
return asyncInitMode(args);
}

case 'asyncUpload': {
Expand Down
Loading

0 comments on commit 4faeff7

Please sign in to comment.