public async run()

in src/commands/codepush/release-react.ts [124:247]


  public async run(client: AppCenterClient): Promise<CommandResult> {
    if (!getReactNativeVersion()) {
      return failure(ErrorCodes.InvalidParameter, "The project in the CWD is not a React Native project.");
    }

    if (!(await isValidDeployment(client, this.app, this.specifiedDeploymentName))) {
      return failure(ErrorCodes.InvalidParameter, `Deployment "${this.specifiedDeploymentName}" does not exist.`);
    } else {
      this.deploymentName = this.specifiedDeploymentName;
    }

    const appInfo = (
      await out.progress(
        "Getting app info...",
        clientRequest<models.AppResponse>((cb) => client.appsOperations.get(this.app.ownerName, this.app.appName, cb))
      )
    ).result;
    this.os = appInfo.os.toLowerCase();
    this.platform = appInfo.platform.toLowerCase();

    this.updateContentsPath = this.outputDir || (await pfs.mkTempDir("code-push"));

    // we have to add "CodePush" root folder to make update contents file structure
    // to be compatible with React Native client SDK
    this.updateContentsPath = path.join(this.updateContentsPath, "CodePush");
    mkdirp.sync(this.updateContentsPath);

    if (!isValidOS(this.os)) {
      return failure(ErrorCodes.InvalidParameter, `OS must be "android", "ios", or "windows".`);
    }

    if (!isValidPlatform(this.platform)) {
      return failure(ErrorCodes.Exception, `Platform must be "React Native".`);
    }

    if (!this.bundleName) {
      this.bundleName = this.os === "ios" ? "main.jsbundle" : `index.${this.os}.bundle`;
    }

    if (!this.entryFile) {
      this.entryFile = `index.${this.os}.js`;
      if (fileDoesNotExistOrIsDirectory(this.entryFile)) {
        this.entryFile = "index.js";
      }

      if (fileDoesNotExistOrIsDirectory(this.entryFile)) {
        return failure(ErrorCodes.NotFound, `Entry file "index.${this.os}.js" or "index.js" does not exist.`);
      }
    } else {
      if (fileDoesNotExistOrIsDirectory(this.entryFile)) {
        return failure(ErrorCodes.NotFound, `Entry file "${this.entryFile}" does not exist.`);
      }
    }

    if (this.sourcemapOutputDir && this.sourcemapOutput) {
      out.text('\n"sourcemap-output-dir" argument will be ignored as "sourcemap-output" argument is provided.\n');
    }

    if ((this.outputDir || this.sourcemapOutputDir) && !this.sourcemapOutput) {
      const sourcemapDir = this.sourcemapOutputDir || this.updateContentsPath;
      this.sourcemapOutput = path.join(sourcemapDir, this.bundleName + ".map");
    }

    this.targetBinaryVersion = this.specifiedTargetBinaryVersion;

    if (this.targetBinaryVersion && !isValidRange(this.targetBinaryVersion)) {
      return failure(ErrorCodes.InvalidParameter, "Invalid binary version(s) for a release.");
    } else if (!this.targetBinaryVersion) {
      const versionSearchParams: VersionSearchParams = {
        os: this.os,
        plistFile: this.plistFile,
        plistFilePrefix: this.plistFilePrefix,
        gradleFile: this.gradleFile,
        buildConfigurationName: this.buildConfigurationName,
        projectFile: this.xcodeProjectFile,
      } as VersionSearchParams;
      this.targetBinaryVersion = await getReactNativeProjectAppVersion(versionSearchParams);
    }

    if (typeof this.extraBundlerOptions === "string") {
      this.extraBundlerOptions = [this.extraBundlerOptions];
    }

    if (typeof this.extraHermesFlags === "string") {
      this.extraHermesFlags = [this.extraHermesFlags];
    }

    try {
      createEmptyTmpReleaseFolder(this.updateContentsPath);
      removeReactTmpDir();
      await runReactNativeBundleCommand(
        this.bundleName,
        this.development,
        this.entryFile,
        this.updateContentsPath,
        this.os,
        this.sourcemapOutput,
        this.extraBundlerOptions
      );
      // Check if we have to run hermes to compile JS to Byte Code if Hermes is enabled in build.gradle and we're releasing an Android build
      if (this.os === "android") {
        const isHermesEnabled = await getAndroidHermesEnabled(this.gradleFile);
        if (isHermesEnabled) {
          await runHermesEmitBinaryCommand(this.bundleName, this.updateContentsPath, this.sourcemapOutput, this.extraHermesFlags);
        }
      } else if (this.os === "ios") {
        // Check if we have to run hermes to compile JS to Byte Code if Hermes is enabled in Podfile and we're releasing an iOS build
        const isHermesEnabled = await getiOSHermesEnabled(this.podFile);
        if (isHermesEnabled) {
          await runHermesEmitBinaryCommand(this.bundleName, this.updateContentsPath, this.sourcemapOutput, this.extraHermesFlags);
        }
      }
      out.text(chalk.cyan("\nReleasing update contents to CodePush:\n"));

      return await this.release(client);
    } catch (error) {
      debug(`Failed to release a CodePush update - ${inspect(error)}`);
      return failure(ErrorCodes.Exception, "Failed to release a CodePush update.");
    } finally {
      if (!this.outputDir) {
        await pfs.rmDir(this.updateContentsPath);
      }
    }
  }