beachball
Advanced tools
Comparing version 2.33.0 to 2.33.1
@@ -16,2 +16,3 @@ "use strict"; | ||
async function publish(options) { | ||
console.log('\nPreparing to publish'); | ||
const { path: cwd, branch, registry, tag } = options; | ||
@@ -28,3 +29,3 @@ // First, validate that we have changes to publish | ||
const currentHash = workspace_tools_1.getCurrentHash(cwd); | ||
console.log(`Publishing with the following configuration: | ||
console.log(`\nPublishing with the following configuration: | ||
@@ -55,9 +56,9 @@ registry: ${registry} | ||
const publishBranch = 'publish_' + String(new Date().getTime()); | ||
console.log(`creating temporary publish branch ${publishBranch}`); | ||
console.log(`Creating temporary publish branch ${publishBranch}`); | ||
workspace_tools_1.gitFailFast(['checkout', '-b', publishBranch], { cwd }); | ||
if (options.bump) { | ||
console.log('Bumping version for npm publish'); | ||
} | ||
console.log(`\nGathering info ${options.bump ? 'to bump versions' : 'about versions and changes'}`); | ||
const bumpInfo = gatherBumpInfo_1.gatherBumpInfo(options, oldPackageInfos); | ||
if (options.new) { | ||
// Publish newly created packages even if they don't have change files | ||
// (this is unlikely unless the packages were pushed without a PR that runs "beachball check") | ||
bumpInfo.newPackages = new Set(await getNewPackages_1.getNewPackages(bumpInfo, options)); | ||
@@ -68,3 +69,5 @@ } | ||
if (options.publish) { | ||
console.log('\nBumping versions and publishing to npm'); | ||
await publishToRegistry_1.publishToRegistry(bumpInfo, options); | ||
console.log(); | ||
} | ||
@@ -77,2 +80,3 @@ else { | ||
if (options.bump && branch && options.push) { | ||
// this does its own section logging | ||
await bumpAndPush_1.bumpAndPush(bumpInfo, publishBranch, options); | ||
@@ -85,2 +89,3 @@ } | ||
// Clean up: switch back to current branch, delete publish branch | ||
console.log('\nCleaning up'); | ||
const revParseSuccessful = currentBranch || currentHash; | ||
@@ -87,0 +92,0 @@ if (currentBranch && currentBranch !== 'HEAD') { |
@@ -8,2 +8,3 @@ "use strict"; | ||
const execa_1 = __importDefault(require("execa")); | ||
const env_1 = require("../env"); | ||
/** | ||
@@ -54,9 +55,5 @@ * Run a git command asynchronously. If `verbose` is true, log the command before starting, and display | ||
function getGitEnv(verbose) { | ||
verbose = verbose || !!process.env.GIT_DEBUG; | ||
const isJest = !!process.env.JEST_WORKER_ID; | ||
const maxBuffer = process.env.GIT_MAX_BUFFER && parseInt(process.env.GIT_MAX_BUFFER, 10); | ||
return { | ||
shouldLog: verbose ? (isJest ? 'end' : 'live') : false, | ||
// isVerbose: verbose || !!process.env.GIT_DEBUG, | ||
maxBuffer: maxBuffer || 500 * 1024 * 1024, | ||
shouldLog: verbose || env_1.env.workspaceToolsGitDebug ? (env_1.env.isJest ? 'end' : 'live') : false, | ||
maxBuffer: env_1.env.workspaceToolsGitMaxBuffer || 500 * 1024 * 1024, | ||
}; | ||
@@ -63,0 +60,0 @@ } |
@@ -9,2 +9,3 @@ "use strict"; | ||
const workspace_tools_1 = require("workspace-tools"); | ||
const env_1 = require("../env"); | ||
let cachedCliOptions; | ||
@@ -14,3 +15,3 @@ function getCliOptions(argv) { | ||
if (argv === process.argv) { | ||
if (process.env.BEACHBALL_DISABLE_CACHE || !cachedCliOptions) { | ||
if (env_1.env.beachballDisableCache || !cachedCliOptions) { | ||
cachedCliOptions = getCliOptionsUncached(process.argv); | ||
@@ -17,0 +18,0 @@ } |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getDefaultOptions = void 0; | ||
const env_1 = require("../env"); | ||
function getDefaultOptions() { | ||
@@ -18,3 +19,3 @@ return { | ||
tag: '', | ||
yes: !!(process.env.CI || process.env.TF_BUILD), | ||
yes: env_1.env.isCI, | ||
access: 'restricted', | ||
@@ -21,0 +22,0 @@ changehint: 'Run "beachball change" to create a change file', |
@@ -12,2 +12,3 @@ "use strict"; | ||
const path_1 = __importDefault(require("path")); | ||
const env_1 = require("../env"); | ||
/** | ||
@@ -20,3 +21,3 @@ * Gets all package level options (default + root options + package options + cli options) | ||
// Don't use options from process.argv or the beachball repo in tests | ||
const cliOptions = process.env.NODE_ENV !== 'test' && getCliOptions_1.getCliOptions(process.argv); | ||
const cliOptions = !env_1.env.isJest && getCliOptions_1.getCliOptions(process.argv); | ||
const repoOptions = cliOptions && getRepoOptions_1.getRepoOptions(cliOptions); | ||
@@ -23,0 +24,0 @@ return { |
@@ -6,6 +6,7 @@ "use strict"; | ||
const workspace_tools_1 = require("workspace-tools"); | ||
const env_1 = require("../env"); | ||
let cachedRepoOptions = new Map(); | ||
function getRepoOptions(cliOptions) { | ||
const { configPath, path: cwd, branch } = cliOptions; | ||
if (!process.env.BEACHBALL_DISABLE_CACHE && cachedRepoOptions.has(cliOptions)) { | ||
if (!env_1.env.beachballDisableCache && cachedRepoOptions.has(cliOptions)) { | ||
return cachedRepoOptions.get(cliOptions); | ||
@@ -12,0 +13,0 @@ } |
import { PackageInfo } from '../types/PackageInfo'; | ||
import { NpmOptions } from '../types/NpmOptions'; | ||
export declare function _clearPackageVersionsCache(): Promise<void>; | ||
export declare function listPackageVersionsByTag(packageInfos: PackageInfo[], tag: string | undefined, options: NpmOptions): Promise<{ | ||
[pkg: string]: string; | ||
[pkg: string]: string | undefined; | ||
}>; | ||
@@ -6,0 +7,0 @@ export declare function listPackageVersions(packageList: string[], options: NpmOptions): Promise<{ |
@@ -6,10 +6,15 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.listPackageVersions = exports.listPackageVersionsByTag = void 0; | ||
exports.listPackageVersions = exports.listPackageVersionsByTag = exports._clearPackageVersionsCache = void 0; | ||
const npm_1 = require("./npm"); | ||
const p_limit_1 = __importDefault(require("p-limit")); | ||
const packageVersionsCache = {}; | ||
const NPM_CONCURRENCY = 5; | ||
const env_1 = require("../env"); | ||
let packageVersionsCache = {}; | ||
const NPM_CONCURRENCY = env_1.env.isJest ? 2 : 5; | ||
async function _clearPackageVersionsCache() { | ||
packageVersionsCache = {}; | ||
} | ||
exports._clearPackageVersionsCache = _clearPackageVersionsCache; | ||
async function getNpmPackageInfo(packageName, options) { | ||
const { registry, token, authType, timeout } = options; | ||
if (process.env.BEACHBALL_DISABLE_CACHE || !packageVersionsCache[packageName]) { | ||
if (env_1.env.beachballDisableCache || !packageVersionsCache[packageName]) { | ||
const args = ['show', '--registry', registry, '--json', packageName, ...npm_1.getNpmAuthArgs(registry, token, authType)]; | ||
@@ -33,3 +38,3 @@ const showResult = await npm_1.npmAsync(args, { timeout }); | ||
const npmTag = tag || pkg.combinedOptions.tag || pkg.combinedOptions.defaultNpmTag; | ||
versions[pkg.name] = info['dist-tags'] && info['dist-tags'][npmTag] ? info['dist-tags'][npmTag] : undefined; | ||
versions[pkg.name] = (npmTag && info['dist-tags']?.[npmTag]) || undefined; | ||
}))); | ||
@@ -44,3 +49,3 @@ return versions; | ||
const info = await getNpmPackageInfo(pkg, options); | ||
versions[pkg] = info && info.versions ? info.versions : []; | ||
versions[pkg] = info?.versions || []; | ||
}))); | ||
@@ -47,0 +52,0 @@ return versions; |
import { BumpInfo } from '../types/BumpInfo'; | ||
import { NpmOptions } from '../types/NpmOptions'; | ||
export declare function getNewPackages(bumpInfo: BumpInfo, options: NpmOptions): Promise<string[]>; | ||
export declare function getNewPackages(bumpInfo: Pick<BumpInfo, 'modifiedPackages' | 'packageInfos'>, options: NpmOptions): Promise<string[]>; | ||
//# sourceMappingURL=getNewPackages.d.ts.map |
@@ -7,14 +7,10 @@ "use strict"; | ||
const { modifiedPackages, packageInfos } = bumpInfo; | ||
const newPackages = Object.keys(packageInfos).filter(pkg => !modifiedPackages.has(pkg)); | ||
const newPackages = Object.keys(packageInfos).filter(pkg => !modifiedPackages.has(pkg) && !packageInfos[pkg].private); | ||
const publishedVersions = await listPackageVersions_1.listPackageVersions(newPackages, options); | ||
return newPackages.filter(pkg => { | ||
const packageInfo = packageInfos[pkg]; | ||
// Ignore private packages or change type "none" packages | ||
if (packageInfo.private) { | ||
return false; | ||
} | ||
if (!publishedVersions[pkg] || publishedVersions[pkg].length === 0) { | ||
if (!publishedVersions[pkg]?.length) { | ||
console.log(`New package detected: ${pkg}`); | ||
return true; | ||
} | ||
return false; | ||
}); | ||
@@ -21,0 +17,0 @@ } |
@@ -17,2 +17,3 @@ "use strict"; | ||
const performPublishOverrides_1 = require("./performPublishOverrides"); | ||
const format_1 = require("../logging/format"); | ||
async function publishToRegistry(originalBumpInfo, options) { | ||
@@ -24,6 +25,5 @@ const bumpInfo = lodash_1.default.cloneDeep(originalBumpInfo); | ||
} | ||
const succeededPackages = new Set(); | ||
let invalid = false; | ||
if (!(await validatePackageVersions_1.validatePackageVersions(bumpInfo, options))) { | ||
displayManualRecovery_1.displayManualRecovery(bumpInfo, succeededPackages); | ||
displayManualRecovery_1.displayManualRecovery(bumpInfo); | ||
invalid = true; | ||
@@ -35,13 +35,21 @@ } | ||
if (invalid) { | ||
console.error('No packages have been published'); | ||
console.error('No packages were published due to validation errors (see above for details).'); | ||
process.exit(1); | ||
} | ||
// get the packages to publish, reducing the set by packages that don't need publishing | ||
const packagesToPublish = toposortPackages_1.toposortPackages([...modifiedPackages, ...newPackages], packageInfos).filter(pkg => { | ||
const sortedPackages = toposortPackages_1.toposortPackages([...modifiedPackages, ...newPackages], packageInfos); | ||
const packagesToPublish = []; | ||
const skippedPackages = []; | ||
for (const pkg of sortedPackages) { | ||
const { publish, reasonToSkip } = shouldPublishPackage_1.shouldPublishPackage(bumpInfo, pkg); | ||
if (!publish) { | ||
console.log(`Skipping publish - ${reasonToSkip}`); | ||
if (publish) { | ||
packagesToPublish.push(pkg); | ||
} | ||
return publish; | ||
}); | ||
else { | ||
skippedPackages.push(reasonToSkip); // this includes the package name | ||
} | ||
} | ||
if (skippedPackages.length) { | ||
console.log(`\nSkipping publishing the following packages:\n${format_1.formatList(skippedPackages)}`); | ||
} | ||
// performing publishConfig and workspace version overrides requires this procedure to ONLY be run right before npm publish, but NOT in the git push | ||
@@ -54,18 +62,12 @@ performPublishOverrides_1.performPublishOverrides(packagesToPublish, bumpInfo.packageInfos); | ||
const packageInfo = bumpInfo.packageInfos[pkg]; | ||
const maybeAwait = prepublishHook(path_1.default.dirname(packageInfo.packageJsonPath), packageInfo.name, packageInfo.version); | ||
if (maybeAwait instanceof Promise) { | ||
await maybeAwait; | ||
} | ||
await prepublishHook(path_1.default.dirname(packageInfo.packageJsonPath), packageInfo.name, packageInfo.version); | ||
} | ||
} | ||
// finally pass through doing the actual npm publish command | ||
let hasAuthError = false; | ||
const succeededPackages = new Set(); | ||
for (const pkg of packagesToPublish) { | ||
if (hasAuthError) { | ||
console.log(`Skipping attempt to publish ${pkg} due to previous auth error`); | ||
continue; | ||
} | ||
const packageInfo = bumpInfo.packageInfos[pkg]; | ||
console.log(`Publishing - ${packageInfo.name}@${packageInfo.version} with tag ${packageInfo.combinedOptions.tag}.`); | ||
console.log(`\nPublishing - ${pkg}@${packageInfo.version} with tag ${packageInfo.combinedOptions.tag}.`); | ||
let result; | ||
let hasAuthError = false; | ||
let retries = 0; | ||
@@ -72,0 +74,0 @@ do { |
@@ -10,3 +10,3 @@ "use strict"; | ||
publish: false, | ||
reasonToSkip: `package ${pkgName} has change type as none`, | ||
reasonToSkip: `${pkgName} has change type none`, | ||
}; | ||
@@ -17,3 +17,3 @@ } | ||
publish: false, | ||
reasonToSkip: `package ${pkgName} is private`, | ||
reasonToSkip: `${pkgName} is private`, | ||
}; | ||
@@ -24,3 +24,3 @@ } | ||
publish: false, | ||
reasonToSkip: `package ${pkgName} is out-of-scope`, | ||
reasonToSkip: `${pkgName} is out-of-scope`, | ||
}; | ||
@@ -27,0 +27,0 @@ } |
@@ -9,3 +9,2 @@ "use strict"; | ||
function validatePackageDependencies(bumpInfo) { | ||
let hasErrors = false; | ||
const { modifiedPackages, newPackages, packageInfos } = bumpInfo; | ||
@@ -21,25 +20,18 @@ const packagesToValidate = [...modifiedPackages, ...newPackages]; | ||
} | ||
const packageInfo = packageInfos[pkg]; | ||
if (packageInfo.dependencies) { | ||
for (const dep of Object.keys(packageInfo.dependencies)) { | ||
if (!allDeps[dep]) { | ||
allDeps[dep] = []; | ||
} | ||
allDeps[dep].push(pkg); | ||
} | ||
for (const dep of Object.keys(packageInfos[pkg].dependencies || {})) { | ||
allDeps[dep] ?? (allDeps[dep] = []); | ||
allDeps[dep].push(pkg); | ||
} | ||
} | ||
console.log(`Validating no private package among package dependencies`); | ||
for (const [dep, usedBy] of Object.entries(allDeps)) { | ||
if (packageInfos[dep] && packageInfos[dep].private === true) { | ||
console.error(`\nERROR: Private package ${dep} should not be a dependency of published package(s) ${usedBy.join(', ')}.`); | ||
hasErrors = true; | ||
} | ||
const errorDeps = Object.keys(allDeps).filter(dep => packageInfos[dep]?.private); | ||
if (errorDeps.length) { | ||
console.error(`ERROR: Found private packages among published package dependencies:\n` + | ||
errorDeps.map(dep => `- ${dep}: used by ${allDeps[dep].join(', ')}`).join('\n')); | ||
return false; | ||
} | ||
if (!hasErrors) { | ||
console.log(' OK!\n'); | ||
} | ||
return !hasErrors; | ||
console.log(' OK!\n'); | ||
return true; | ||
} | ||
exports.validatePackageDependencies = validatePackageDependencies; | ||
//# sourceMappingURL=validatePackageDependencies.js.map |
import { BumpInfo } from '../types/BumpInfo'; | ||
import { NpmOptions } from '../types/NpmOptions'; | ||
/** | ||
* Validate a package being published is not already published. | ||
* Validate each package version being published doesn't already exist in the registry. | ||
*/ | ||
export declare function validatePackageVersions(bumpInfo: BumpInfo, options: NpmOptions): Promise<boolean>; | ||
//# sourceMappingURL=validatePackageVersions.d.ts.map |
@@ -6,8 +6,9 @@ "use strict"; | ||
const shouldPublishPackage_1 = require("./shouldPublishPackage"); | ||
const format_1 = require("../logging/format"); | ||
/** | ||
* Validate a package being published is not already published. | ||
* Validate each package version being published doesn't already exist in the registry. | ||
*/ | ||
async function validatePackageVersions(bumpInfo, options) { | ||
let hasErrors = false; | ||
const packages = [...bumpInfo.modifiedPackages].filter(pkg => { | ||
console.log('\nValidating new package versions...'); | ||
const packagesToValidate = [...bumpInfo.modifiedPackages].filter(pkg => { | ||
const { publish, reasonToSkip } = shouldPublishPackage_1.shouldPublishPackage(bumpInfo, pkg); | ||
@@ -20,17 +21,26 @@ if (!publish) { | ||
}); | ||
const publishedVersions = await listPackageVersions_1.listPackageVersions(packages, options); | ||
for (const pkg of packages) { | ||
const publishedVersions = await listPackageVersions_1.listPackageVersions(packagesToValidate, options); | ||
const okVersions = []; | ||
const errorVersions = []; | ||
for (const pkg of packagesToValidate) { | ||
const packageInfo = bumpInfo.packageInfos[pkg]; | ||
console.log(`Validating package version - ${packageInfo.name}@${packageInfo.version}`); | ||
const versionSpec = `${packageInfo.name}@${packageInfo.version}`; | ||
if (publishedVersions[pkg].includes(packageInfo.version)) { | ||
console.error(`\nERROR: Attempting to bump to a version that already exists in the registry: ${packageInfo.name}@${packageInfo.version}`); | ||
hasErrors = true; | ||
errorVersions.push(versionSpec); | ||
} | ||
else { | ||
console.log(' OK!\n'); | ||
okVersions.push(versionSpec); | ||
} | ||
} | ||
return !hasErrors; | ||
if (okVersions.length) { | ||
console.log(`\nPackage versions are OK to publish:\n${format_1.formatList(okVersions)}`); | ||
} | ||
if (errorVersions.length) { | ||
console.error(`\nERROR: Attempting to publish package versions that already exist in the registry:\n` + | ||
format_1.formatList(errorVersions)); | ||
return false; | ||
} | ||
return true; | ||
} | ||
exports.validatePackageVersions = validatePackageVersions; | ||
//# sourceMappingURL=validatePackageVersions.js.map |
@@ -20,2 +20,10 @@ import { AuthType } from './Auth'; | ||
keepChangeFiles?: boolean; | ||
/** | ||
* For publish: If true, publish all newly added packages in addition to modified packages. | ||
* New packages *with change files* will always be published regardless of this option. | ||
* | ||
* (This has limited use unless you pushed new packages directly to the main branch, or | ||
* your PR build doesn't run `beachball check`. Otherwise, `beachball check` will require | ||
* change files to be created for the missing packages.) | ||
*/ | ||
new: boolean; | ||
@@ -22,0 +30,0 @@ package?: string | string[]; |
{ | ||
"name": "beachball", | ||
"version": "2.33.0", | ||
"version": "2.33.1", | ||
"description": "The Sunniest Semantic Version Bumper", | ||
@@ -5,0 +5,0 @@ "repository": { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 5 instances in 1 package
340430
320
4252
9