mirror of
https://github.com/hanzoai/firebase-js-sdk.git
synced 2026-09-24 16:59:10 +00:00
192 lines
5.3 KiB
TypeScript
192 lines
5.3 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright 2020 Google LLC
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
import { exec } from 'child-process-promise';
|
|
import { createPromptModule } from 'inquirer';
|
|
import { publish, publishInCI } from './utils/publish';
|
|
import { cleanTree, hasDiff } from './utils/git';
|
|
import {
|
|
releaseType as releaseTypePrompt,
|
|
validateVersions
|
|
} from './utils/inquirer';
|
|
import { reinstallDeps, buildPackages } from './utils/yarn';
|
|
import { runTests, setupTestDeps } from './utils/tests';
|
|
import { bumpVersionForStaging } from './staging';
|
|
import { ReleaseType } from './utils/enums';
|
|
import { getAllPackages } from './utils/workspace';
|
|
const prompt = createPromptModule();
|
|
|
|
interface releaseOptions {
|
|
skipReinstall: boolean;
|
|
skipTests: boolean;
|
|
ignoreUnstaged: boolean;
|
|
releaseType?: string;
|
|
dryRun: boolean;
|
|
ci: boolean;
|
|
}
|
|
|
|
export async function runRelease({
|
|
skipReinstall,
|
|
skipTests,
|
|
ignoreUnstaged,
|
|
releaseType: inputReleaseType,
|
|
dryRun,
|
|
ci
|
|
}: releaseOptions) {
|
|
console.log('ci', ci);
|
|
try {
|
|
/**
|
|
* If there are unstaged changes, error.
|
|
* Use --ignoreUnstaged to skip, such as if release-cli is continuing from a
|
|
* checkpoint.
|
|
*/
|
|
if (!ignoreUnstaged && (await hasDiff())) {
|
|
throw new Error(
|
|
'You have unstaged changes, stash your changes before attempting to publish'
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Log the user who will be publishing the packages
|
|
*/
|
|
if (!process.env.CI) {
|
|
const { stdout: whoami } = await exec('npm whoami');
|
|
console.log(`Publishing as ${whoami}`);
|
|
}
|
|
|
|
/**
|
|
* Determine if the current release is a staging or production release
|
|
*/
|
|
const releaseType: string = await (async () => {
|
|
/**
|
|
* Capture the release type if it was passed to the CLI via args
|
|
*/
|
|
if (
|
|
inputReleaseType &&
|
|
(inputReleaseType === ReleaseType.Staging ||
|
|
inputReleaseType === ReleaseType.Production)
|
|
) {
|
|
return inputReleaseType;
|
|
}
|
|
|
|
/**
|
|
* Prompt for the release type (i.e. staging/prod)
|
|
*/
|
|
const responses = await prompt<{ [key: string]: string }>([
|
|
releaseTypePrompt
|
|
]);
|
|
return responses.releaseType;
|
|
})();
|
|
|
|
console.log(`Publishing ${inputReleaseType} release.`);
|
|
|
|
let packagesToPublish = [];
|
|
if (releaseType === ReleaseType.Staging) {
|
|
/**
|
|
* Bump versions for staging release
|
|
* NOTE: For prod, versions are bumped in a PR which should be merged before running this script
|
|
*/
|
|
const updatedPackages = await bumpVersionForStaging();
|
|
|
|
if (!ci) {
|
|
// We don't need to validate versions for prod releases because prod releases
|
|
// are validated in the version bump PR which should be merged before running this script
|
|
const { versionCheck } = await prompt([
|
|
validateVersions(updatedPackages)
|
|
]);
|
|
|
|
if (!versionCheck) {
|
|
throw new Error('Version check failed');
|
|
}
|
|
}
|
|
|
|
for (const key of updatedPackages.keys()) {
|
|
packagesToPublish.push(key);
|
|
}
|
|
} else {
|
|
/**
|
|
* For production releases, pass all packages to publishToCI().
|
|
* It will only publish if it finds the local version is newer
|
|
* than NPM's.
|
|
*/
|
|
packagesToPublish = await getAllPackages();
|
|
}
|
|
|
|
/**
|
|
* Users can pass --skipReinstall to skip the installation step
|
|
*/
|
|
if (!skipReinstall) {
|
|
/**
|
|
* Clean install dependencies
|
|
*/
|
|
console.log('\r\nVerifying Build');
|
|
await cleanTree();
|
|
await reinstallDeps();
|
|
}
|
|
|
|
/**
|
|
* build packages
|
|
*/
|
|
await buildPackages();
|
|
|
|
/**
|
|
* Users can pass --skipTests to skip the testing step
|
|
*/
|
|
if (!skipTests) {
|
|
await setupTestDeps();
|
|
await runTests();
|
|
}
|
|
|
|
/**
|
|
* Publish new versions to NPM using changeset (if manual)
|
|
* or using wombot for each package (if CI)
|
|
* It will also create tags
|
|
*/
|
|
if (ci) {
|
|
/**
|
|
* If the script is calling each individual npm command
|
|
* it can add the npm flag --dry-run, to better simulate
|
|
* everything in the publish process except publishing.
|
|
*/
|
|
if (releaseType === ReleaseType.Staging) {
|
|
await publishInCI(packagesToPublish, 'next', dryRun);
|
|
} else {
|
|
// Production.
|
|
await publishInCI(packagesToPublish, 'latest', dryRun);
|
|
}
|
|
} else {
|
|
/**
|
|
* If the script uses changeset to publish, there's no
|
|
* way to add the dry-run flag to each npm CLI command.
|
|
*/
|
|
if (!dryRun) {
|
|
// Uses changeset
|
|
await publish(releaseType);
|
|
}
|
|
}
|
|
} catch (err) {
|
|
/**
|
|
* Log any errors that happened during the process
|
|
*/
|
|
console.error(err);
|
|
/**
|
|
* Exit with an error code
|
|
*/
|
|
process.exit(1);
|
|
}
|
|
}
|