Skip to content

Commit

Permalink
Added --config option for react-release CLI command (microsoft#563)
Browse files Browse the repository at this point in the history
Added --config option for react-release CLI command
  • Loading branch information
itoys authored Mar 23, 2018
1 parent bbc9a04 commit c385ad0
Show file tree
Hide file tree
Showing 12 changed files with 1,438 additions and 219 deletions.
33 changes: 33 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Run CLI",
"type": "node",
"request": "launch",
"protocol": "inspector",
"program": "${workspaceRoot}/cli/bin/script/cli.js",
"stopOnEntry": false,
"sourceMaps": true,
"preLaunchTask": "gulp: build",
"args": [
"--info"
]
},
{
"name": "Unit Test",
"type": "node",
"request": "launch",
"protocol": "inspector",
"program": "${workspaceRoot}/node_modules/gulp/bin/gulp.js",
"stopOnEntry": false,
"sourceMaps": true,
"args": [
"test"
]
}
]
}
7 changes: 7 additions & 0 deletions cli/README-cn.md
Original file line number Diff line number Diff line change
Expand Up @@ -393,10 +393,17 @@ code-push release-react <appName> <platform>
[--development <development>]
[--disabled <disabled>]
[--entryFile <entryFile>]
[--gradleFile <gradleFile>]
[--mandatory]
[--noDuplicateReleaseError]
[--outputDir <outputDir>]
[--plistFile <plistFile>]
[--plistFilePrefix <plistFilePrefix>]
[--sourcemapOutput <sourcemapOutput>]
[--targetBinaryVersion <targetBinaryVersion>]
[--rollout <rolloutPercentage>]
[--privateKeyPath <pathToPrivateKey>]
[--config <config>]
```
`release-react`命令是React Native特有的[`发布`](#发布更新)命令,支持相同的所有参数(如:`--mandatory`,`--description`),然而通过如下额外的动作简化了发布更新过程:

Expand Down
3 changes: 2 additions & 1 deletion cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ This specifies which deployment you want to release the update to. This defaults

This provides an optional "change log" for the deployment. The value is simply round tripped to the client so that when the update is detected, your app can choose to display it to the end-user (e.g. via a "What's new?" dialog). This string accepts control characters such as `\n` and `\t` so that you can include whitespace formatting within your descriptions for improved readability.

*NOTE: This parameter can be set using either "--description" or "-des"*
*NOTE: This parameter can be set using either "--description" or "--des"*

#### Disabled parameter

Expand Down Expand Up @@ -445,6 +445,7 @@ code-push release-react <appName> <platform>
[--targetBinaryVersion <targetBinaryVersion>]
[--rollout <rolloutPercentage>]
[--privateKeyPath <pathToPrivateKey>]
[--config <config>]
```

The `release-react` command is a React Native-specific version of the "vanilla" [`release`](#releasing-app-updates) command, which supports all of the same parameters (e.g. `--mandatory`, `--description`), yet simplifies the process of releasing updates by performing the following additional behavior:
Expand Down
1 change: 1 addition & 0 deletions cli/definitions/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ export interface IReleaseReactCommand extends IReleaseBaseCommand {
plistFilePrefix?: string;
sourcemapOutput?: string;
outputDir?: string;
config?: string;
}

export interface IRollbackCommand extends ICommand {
Expand Down
8 changes: 6 additions & 2 deletions cli/script/command-executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1374,7 +1374,7 @@ export var releaseReact = (command: cli.IReleaseReactCommand): Promise<void> =>
// This is needed to clear the react native bundler cache:
// https://github.com/facebook/react-native/issues/4289
.then(() => deleteFolder(`${os.tmpdir()}/react-*`))
.then(() => runReactNativeBundleCommand(bundleName, command.development || false, entryFile, outputFolder, platform, command.sourcemapOutput))
.then(() => runReactNativeBundleCommand(bundleName, command.development || false, entryFile, outputFolder, platform, command.sourcemapOutput, command.config))
.then(() => {
log(chalk.cyan("\nReleasing update contents to CodePush:\n"));
return release(releaseCommand);
Expand Down Expand Up @@ -1439,7 +1439,7 @@ function requestAccessKey(): Promise<string> {
});
}

export var runReactNativeBundleCommand = (bundleName: string, development: boolean, entryFile: string, outputFolder: string, platform: string, sourcemapOutput: string): Promise<void> => {
export var runReactNativeBundleCommand = (bundleName: string, development: boolean, entryFile: string, outputFolder: string, platform: string, sourcemapOutput: string, config: string): Promise<void> => {
let reactNativeBundleArgs: string[] = [];
let envNodeArgs: string = process.env.CODE_PUSH_NODE_ARGS;

Expand All @@ -1460,6 +1460,10 @@ export var runReactNativeBundleCommand = (bundleName: string, development: boole
reactNativeBundleArgs.push("--sourcemap-output", sourcemapOutput);
}

if (config) {
reactNativeBundleArgs.push("--config", config);
}

log(chalk.cyan("Running \"react-native bundle\" command:\n"));
var reactNativeBundleProcess = spawn("node", reactNativeBundleArgs);
log(`node ${reactNativeBundleArgs.join(" ")}`);
Expand Down
2 changes: 2 additions & 0 deletions cli/script/command-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,7 @@ var argv = yargs.usage(USAGE_PREFIX + " <command>")
.option("sourcemapOutput", { alias: "s", default: null, demand: false, description: "Path to where the sourcemap for the resulting bundle should be written. If omitted, a sourcemap will not be generated.", type: "string" })
.option("targetBinaryVersion", { alias: "t", default: null, demand: false, description: "Semver expression that specifies the binary app version(s) this release is targeting (e.g. 1.1.0, ~1.2.3). If omitted, the release will target the exact version specified in the \"Info.plist\" (iOS), \"build.gradle\" (Android) or \"Package.appxmanifest\" (Windows) files.", type: "string" })
.option("outputDir", { alias: "o", default: null, demand: false, description: "Path to where the bundle and sourcemap should be written. If omitted, a bundle and sourcemap will not be written.", type: "string" })
.option("config", { alias: "c", default: null, demand: false, description: "Path to the React Native CLI configuration file", type: "string" })
.check((argv: any, aliases: { [aliases: string]: string }): any => { return checkValidReleaseOptions(argv); });

addCommonConfiguration(yargs);
Expand Down Expand Up @@ -861,6 +862,7 @@ function createCommand(): cli.ICommand {
releaseReactCommand.privateKeyPath = argv["privateKeyPath"];
releaseReactCommand.sourcemapOutput = argv["sourcemapOutput"];
releaseReactCommand.outputDir = argv["outputDir"];
releaseReactCommand.config = argv["config"];
}
break;

Expand Down
59 changes: 49 additions & 10 deletions cli/test/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1456,7 +1456,7 @@ describe("CLI", () => {
cmdexec.execute(command)
.then(() => {
var releaseCommand: cli.IReleaseCommand = <any>command;
releaseCommand.package = path.join(os.tmpdir(), "CodePush");
releaseCommand.package = path.join(os.tmpdir(), "CodePush/CodePush");
releaseCommand.appStoreVersion = "1.2.3";

sinon.assert.calledOnce(spawn);
Expand All @@ -1465,7 +1465,7 @@ describe("CLI", () => {
assert.equal(spawnCommand, "node");
assert.equal(
spawnCommandArgs,
`${path.join("node_modules", "react-native", "local-cli", "cli.js")} bundle --assets-dest ${path.join(os.tmpdir(), "CodePush")} --bundle-output ${path.join(os.tmpdir(), "CodePush", bundleName)} --dev false --entry-file index.ios.js --platform ios`
`${path.join("node_modules", "react-native", "local-cli", "cli.js")} bundle --assets-dest ${path.join(os.tmpdir(), "CodePush/CodePush")} --bundle-output ${path.join(os.tmpdir(), "CodePush/CodePush", bundleName)} --dev false --entry-file index.ios.js --platform ios`
);
assertJsonDescribesObject(JSON.stringify(release.args[0][0], /*replacer=*/ null, /*spacing=*/ 2), releaseCommand);
done();
Expand All @@ -1492,7 +1492,7 @@ describe("CLI", () => {
cmdexec.execute(command)
.then(() => {
var releaseCommand: cli.IReleaseCommand = <any>clone(command);
var packagePath: string = path.join(os.tmpdir(), "CodePush");
var packagePath: string = path.join(os.tmpdir(), "CodePush/CodePush");
releaseCommand.package = packagePath;
releaseCommand.appStoreVersion = "1.2.3";

Expand Down Expand Up @@ -1529,7 +1529,7 @@ describe("CLI", () => {
cmdexec.execute(command)
.then(() => {
var releaseCommand: cli.IReleaseCommand = <any>clone(command);
var packagePath: string = path.join(os.tmpdir(), "CodePush");
var packagePath: string = path.join(os.tmpdir(), "CodePush/CodePush");
releaseCommand.package = packagePath;
releaseCommand.appStoreVersion = "1.0.0";

Expand Down Expand Up @@ -1566,7 +1566,7 @@ describe("CLI", () => {
cmdexec.execute(command)
.then(() => {
var releaseCommand: cli.IReleaseCommand = <any>clone(command);
var packagePath = path.join(os.tmpdir(), "CodePush");
var packagePath = path.join(os.tmpdir(), "CodePush/CodePush");
releaseCommand.package = packagePath;
releaseCommand.appStoreVersion = "1.0.0";

Expand Down Expand Up @@ -1616,7 +1616,7 @@ describe("CLI", () => {
assert.equal(spawnCommand, "node");
assert.equal(
spawnCommandArgs,
`${path.join("node_modules", "react-native", "local-cli", "cli.js")} bundle --assets-dest ${path.join(os.tmpdir(), "CodePush")} --bundle-output ${path.join(os.tmpdir(), "CodePush", bundleName)} --dev true --entry-file index.android.js --platform android --sourcemap-output index.android.js.map`
`${path.join("node_modules", "react-native", "local-cli", "cli.js")} bundle --assets-dest ${path.join(os.tmpdir(), "CodePush/CodePush")} --bundle-output ${path.join(os.tmpdir(), "CodePush/CodePush", bundleName)} --dev true --entry-file index.android.js --platform android --sourcemap-output index.android.js.map`
);
assertJsonDescribesObject(JSON.stringify(release.args[0][0], /*replacer=*/ null, /*spacing=*/ 2), releaseCommand);
done();
Expand Down Expand Up @@ -1655,7 +1655,7 @@ describe("CLI", () => {
assert.equal(spawnCommand, "node");
assert.equal(
spawnCommandArgs,
`${path.join("node_modules", "react-native", "local-cli", "cli.js")} bundle --assets-dest ${path.join(os.tmpdir(), "CodePush")} --bundle-output ${path.join(os.tmpdir(), "CodePush", bundleName)} --dev false --entry-file index.android.js --platform android --sourcemap-output index.android.js.map`
`${path.join("node_modules", "react-native", "local-cli", "cli.js")} bundle --assets-dest ${path.join(os.tmpdir(), "CodePush/CodePush")} --bundle-output ${path.join(os.tmpdir(), "CodePush/CodePush", bundleName)} --dev false --entry-file index.android.js --platform android --sourcemap-output index.android.js.map`
);
assertJsonDescribesObject(JSON.stringify(release.args[0][0], /*replacer=*/ null, /*spacing=*/ 2), releaseCommand);
done();
Expand Down Expand Up @@ -1693,7 +1693,7 @@ describe("CLI", () => {
assert.equal(spawnCommand, "node");
assert.equal(
spawnCommandArgs,
`${path.join("node_modules", "react-native", "local-cli", "cli.js")} bundle --assets-dest ${path.join(os.tmpdir(), "CodePush")} --bundle-output ${path.join(os.tmpdir(), "CodePush", bundleName)} --dev false --entry-file index.android.js --platform android --sourcemap-output index.android.js.map`
`${path.join("node_modules", "react-native", "local-cli", "cli.js")} bundle --assets-dest ${path.join(os.tmpdir(), "CodePush/CodePush")} --bundle-output ${path.join(os.tmpdir(), "CodePush/CodePush", bundleName)} --dev false --entry-file index.android.js --platform android --sourcemap-output index.android.js.map`
);
assertJsonDescribesObject(JSON.stringify(release.args[0][0], /*replacer=*/ null, /*spacing=*/ 2), releaseCommand);
done();
Expand Down Expand Up @@ -1734,12 +1734,51 @@ describe("CLI", () => {
assert.equal(spawnCommand, "node");
assert.equal(
spawnCommandArgs,
`--foo=bar --baz ${path.join("node_modules", "react-native", "local-cli", "cli.js")} bundle --assets-dest ${path.join(os.tmpdir(), "CodePush")} --bundle-output ${path.join(os.tmpdir(), "CodePush", bundleName)} --dev false --entry-file index.ios.js --platform ios`
`--foo=bar --baz ${path.join("node_modules", "react-native", "local-cli", "cli.js")} bundle --assets-dest ${path.join(os.tmpdir(), "CodePush/CodePush")} --bundle-output ${path.join(os.tmpdir(), "CodePush/CodePush", bundleName)} --dev false --entry-file index.ios.js --platform ios`
);
assertJsonDescribesObject(JSON.stringify(release.args[0][0], /*replacer=*/ null, /*spacing=*/ 2), releaseCommand);

process.env.CODE_PUSH_NODE_ARGS = _CODE_PUSH_NODE_ARGS;
_CODE_PUSH_NODE_ARGS !== undefined ? process.env.CODE_PUSH_NODE_ARGS = _CODE_PUSH_NODE_ARGS : delete process.env.CODE_PUSH_NODE_ARGS;

done();
})
.done();
});

it("release-react uses config file", (done: MochaDone): void => {
var bundleName = "bundle.js";
var command: cli.IReleaseReactCommand = {
type: cli.CommandType.releaseReact,
appName: "a",
appStoreVersion: null,
bundleName: bundleName,
deploymentName: "Staging",
description: "Test uses config file",
mandatory: false,
rollout: null,
platform: "android",
config: "/path/to/config.json"
};

ensureInTestAppDirectory();

var release: Sinon.SinonSpy = sandbox.stub(cmdexec, "release", () => { return Q(<void>null) });

cmdexec.execute(command)
.then(() => {
var releaseCommand: cli.IReleaseCommand = <any>command;
releaseCommand.package = path.join(os.tmpdir(), "CodePush");
releaseCommand.appStoreVersion = "1.2.3";

sinon.assert.calledOnce(spawn);
var spawnCommand: string = spawn.args[0][0];
var spawnCommandArgs: string = spawn.args[0][1].join(" ");
assert.equal(spawnCommand, "node");
assert.equal(
spawnCommandArgs,
`${path.join("node_modules", "react-native", "local-cli", "cli.js")} bundle --assets-dest ${path.join(os.tmpdir(), "CodePush/CodePush")} --bundle-output ${path.join(os.tmpdir(), "CodePush/CodePush", bundleName)} --dev false --entry-file index.android.js --platform android --config /path/to/config.json`
);
assertJsonDescribesObject(JSON.stringify(release.args[0][0], /*replacer=*/ null, /*spacing=*/ 2), releaseCommand);
done();
})
.done();
Expand Down
8 changes: 7 additions & 1 deletion gulp/scripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ var chmod = require("chmod");
var fs = require("fs");
var gulp = require("gulp");
var plugins = require("gulp-load-plugins")();
var sourcemaps = require('gulp-sourcemaps');
var through = require("through2");
var tsc = require("typescript");
var tsJsxLoader = require("ts-jsx-loader");
Expand Down Expand Up @@ -42,6 +43,7 @@ function scriptTask(cwd, jsx) {
var tsResult = merge([
gulp.src("{script,test,definitions}/**/*.ts", options),
gulp.src(generatedDefinitions)])
.pipe(sourcemaps.init())
.pipe(plugins.if(jsx, through.obj(tsJsxPipe)))
.pipe(plugins.typescript(tsProj, /* filterSettings=*/ undefined, {
error: fullReporter.error,
Expand All @@ -56,7 +58,11 @@ function scriptTask(cwd, jsx) {
}));

return merge([
tsResult.js.pipe(gulp.dest("bin", options)),
tsResult.js
.pipe(sourcemaps.write("./", {
sourceRoot: ".."
}))
.pipe(gulp.dest("bin", options)),
tsResult.dts.pipe(gulp.dest("bin/definitions", options))
])
.pipe(errorCatch);
Expand Down
Loading

0 comments on commit c385ad0

Please sign in to comment.