export async function publishExtensionVersionFromLocalSource()

in src/extensions/extensionsHelper.ts [384:516]


export async function publishExtensionVersionFromLocalSource(args: {
  publisherId: string;
  extensionId: string;
  rootDirectory: string;
  nonInteractive: boolean;
  force: boolean;
}): Promise<ExtensionVersion | undefined> {
  const extensionSpec = await getLocalExtensionSpec(args.rootDirectory);
  if (extensionSpec.name != args.extensionId) {
    throw new FirebaseError(
      `Extension ID '${clc.bold(
        args.extensionId
      )}' does not match the name in extension.yaml '${clc.bold(extensionSpec.name)}'.`
    );
  }

  // Substitute deepcopied spec with autopopulated params, and make sure that it passes basic extension.yaml validation.
  const subbedSpec = JSON.parse(JSON.stringify(extensionSpec));
  subbedSpec.params = substituteParams<Param[]>(
    extensionSpec.params || [],
    AUTOPOULATED_PARAM_PLACEHOLDERS
  );
  validateSpec(subbedSpec);

  let extension;
  try {
    extension = await getExtension(`${args.publisherId}/${args.extensionId}`);
  } catch (err: any) {
    // Silently fail and continue the publish flow if extension not found.
  }

  let notes: string;
  try {
    const changes = getLocalChangelog(args.rootDirectory);
    notes = changes[extensionSpec.version];
  } catch (err: any) {
    throw new FirebaseError(
      "No CHANGELOG.md file found. " +
        "Please create one and add an entry for this version. " +
        marked(
          "See https://firebase.google.com/docs/extensions/alpha/create-user-docs#writing-changelog for more details."
        )
    );
  }
  if (!notes && extension) {
    // If this is not the first version of this extension, we require release notes
    throw new FirebaseError(
      `No entry for version ${extensionSpec.version} found in CHANGELOG.md. ` +
        "Please add one so users know what has changed in this version. " +
        marked(
          "See https://firebase.google.com/docs/extensions/alpha/create-user-docs#writing-changelog for more details."
        )
    );
  }
  displayReleaseNotes(args.publisherId, args.extensionId, extensionSpec.version, notes);
  if (
    !(await confirm({
      nonInteractive: args.nonInteractive,
      force: args.force,
      default: false,
    }))
  ) {
    return;
  }

  if (
    extension &&
    extension.latestVersion &&
    semver.lt(extensionSpec.version, extension.latestVersion)
  ) {
    // publisher's version is less than current latest version.
    throw new FirebaseError(
      `The version you are trying to publish (${clc.bold(
        extensionSpec.version
      )}) is lower than the current version (${clc.bold(
        extension.latestVersion
      )}) for the extension '${clc.bold(
        `${args.publisherId}/${args.extensionId}`
      )}'. Please make sure this version is greater than the current version (${clc.bold(
        extension.latestVersion
      )}) inside of extension.yaml.\n`
    );
  } else if (
    extension &&
    extension.latestVersion &&
    semver.eq(extensionSpec.version, extension.latestVersion)
  ) {
    // publisher's version is equal to the current latest version.
    throw new FirebaseError(
      `The version you are trying to publish (${clc.bold(
        extensionSpec.version
      )}) already exists for the extension '${clc.bold(
        `${args.publisherId}/${args.extensionId}`
      )}'. Please increment the version inside of extension.yaml.\n`,
      { exit: 103 }
    );
  }

  const ref = `${args.publisherId}/${args.extensionId}@${extensionSpec.version}`;
  let packageUri: string;
  let objectPath = "";
  const uploadSpinner = ora(" Archiving and uploading extension source code");
  try {
    uploadSpinner.start();
    objectPath = await archiveAndUploadSource(args.rootDirectory, EXTENSIONS_BUCKET_NAME);
    uploadSpinner.succeed(" Uploaded extension source code");
    packageUri = storageOrigin + objectPath + "?alt=media";
  } catch (err: any) {
    uploadSpinner.fail();
    throw err;
  }
  const publishSpinner = ora(`Publishing ${clc.bold(ref)}`);
  let res;
  try {
    publishSpinner.start();
    res = await publishExtensionVersion(ref, packageUri);
    publishSpinner.succeed(` Successfully published ${clc.bold(ref)}`);
  } catch (err: any) {
    publishSpinner.fail();
    if (err.status == 404) {
      throw new FirebaseError(
        marked(
          `Couldn't find publisher ID '${clc.bold(
            args.publisherId
          )}'. Please ensure that you have registered this ID. To register as a publisher, you can check out the [Firebase documentation](https://firebase.google.com/docs/extensions/alpha/share#register_as_an_extensions_publisher) for step-by-step instructions.`
        )
      );
    }
    throw err;
  }
  await deleteUploadedSource(objectPath);
  return res;
}