From 3fcfd80f176c5656cb6136540de82cbb092cc548 Mon Sep 17 00:00:00 2001 From: Michael Zhen <112977307+zhenmichael@users.noreply.github.com> Date: Thu, 5 Dec 2024 17:59:06 +0000 Subject: [PATCH 01/13] base command and base package command using build project context --- build-tools/feeds/internal-build.txt | 1 + build-tools/feeds/internal-test.txt | 1 + build-tools/feeds/public.txt | 1 + build-tools/packages/build-cli/package.json | 1 + .../src/BasePackageCommandWithContext.ts | 187 ++++++++++++++++++ .../src/library/commands/baseCommand.ts | 27 +++ .../build-cli/src/library/commands/index.ts | 1 + .../packages/build-cli/src/library/index.ts | 1 + .../build-infrastructure/package.json | 1 - build-tools/pnpm-lock.yaml | 3 + 10 files changed, 223 insertions(+), 1 deletion(-) create mode 100644 build-tools/packages/build-cli/src/BasePackageCommandWithContext.ts create mode 100644 build-tools/packages/build-cli/src/library/commands/baseCommand.ts diff --git a/build-tools/feeds/internal-build.txt b/build-tools/feeds/internal-build.txt index 9fa47d57fd55..596a9b73d47a 100644 --- a/build-tools/feeds/internal-build.txt +++ b/build-tools/feeds/internal-build.txt @@ -1,4 +1,5 @@ @fluid-tools/version-tools @fluidframework/bundle-size-tools @fluidframework/build-tools +@fluid-tools/build-infrastructure @fluid-tools/build-cli \ No newline at end of file diff --git a/build-tools/feeds/internal-test.txt b/build-tools/feeds/internal-test.txt index 9fa47d57fd55..596a9b73d47a 100644 --- a/build-tools/feeds/internal-test.txt +++ b/build-tools/feeds/internal-test.txt @@ -1,4 +1,5 @@ @fluid-tools/version-tools @fluidframework/bundle-size-tools @fluidframework/build-tools +@fluid-tools/build-infrastructure @fluid-tools/build-cli \ No newline at end of file diff --git a/build-tools/feeds/public.txt b/build-tools/feeds/public.txt index 9fa47d57fd55..596a9b73d47a 100644 --- a/build-tools/feeds/public.txt +++ b/build-tools/feeds/public.txt @@ -1,4 +1,5 @@ @fluid-tools/version-tools @fluidframework/bundle-size-tools @fluidframework/build-tools +@fluid-tools/build-infrastructure @fluid-tools/build-cli \ No newline at end of file diff --git a/build-tools/packages/build-cli/package.json b/build-tools/packages/build-cli/package.json index a45ca1d8daa3..841d512f90ba 100644 --- a/build-tools/packages/build-cli/package.json +++ b/build-tools/packages/build-cli/package.json @@ -82,6 +82,7 @@ "@andrewbranch/untar.js": "^1.0.3", "@fluid-tools/version-tools": "workspace:~", "@fluidframework/build-tools": "workspace:~", + "@fluid-tools/build-infrastructure": "workspace:~", "@fluidframework/bundle-size-tools": "workspace:~", "@inquirer/prompts": "^7.0.1", "@microsoft/api-extractor": "^7.47.11", diff --git a/build-tools/packages/build-cli/src/BasePackageCommandWithContext.ts b/build-tools/packages/build-cli/src/BasePackageCommandWithContext.ts new file mode 100644 index 000000000000..8988e11bfd80 --- /dev/null +++ b/build-tools/packages/build-cli/src/BasePackageCommandWithContext.ts @@ -0,0 +1,187 @@ +/*! + * Copyright (c) Microsoft Corporation and contributors. All rights reserved. + * Licensed under the MIT License. + */ + +import { strict as assert } from "node:assert"; +import { Package } from "@fluidframework/build-tools"; +import { Flags, ux, type Command } from "@oclif/core"; +import async from "async"; +import { + PackageFilterOptions, + PackageKind, + PackageSelectionCriteria, + PackageWithKind, + parsePackageFilterFlags, + parsePackageSelectionFlags, + selectAndFilterPackages, +} from "./filter.js"; +import { type PackageSelectionDefault, filterFlags, selectionFlags } from "./flags.js"; +import { BaseCommandWithBuildProject } from "./library/commands/baseCommand.js"; + +/** + * Commands that run operations per project. + */ +export abstract class PackageCommandWithBuildProject< + T extends typeof Command & { flags: typeof PackageCommandWithBuildProject.flags }, +> extends BaseCommandWithBuildProject { + static readonly flags = { + concurrency: Flags.integer({ + description: "The number of tasks to execute concurrently.", + default: 25, + }), + ...selectionFlags, + ...filterFlags, + ...BaseCommandWithBuildProject.flags, + }; + + /** + * The default to use as selection criteria when none is explicitly provided by the user. This enables commands + * without flags to operate on a collection of packages by default that make sense based on the command. + */ + protected abstract get defaultSelection(): PackageSelectionDefault; + protected abstract set defaultSelection(value: PackageSelectionDefault); + + protected filterOptions: PackageFilterOptions | undefined; + protected selectionOptions: PackageSelectionCriteria | undefined; + + /** + * An array of packages selected based on the selection criteria. + * + * @remarks + * + * Note that these packages are not necessarily the ones that are acted on. Packages are selected, then that list is + * further narrowed by filtering criteria, so this array may contain packages that are not acted on. + */ + protected selectedPackages: PackageWithKind[] | undefined; + + /** + * The list of packages after all filters are applied to the selected packages. + */ + protected filteredPackages: PackageWithKind[] | undefined; + + /** + * Called for each package that is selected/filtered based on the filter flags passed in to the command. + * + * @param pkg - The package being processed. + * @param kind - The kind of the package. + * @typeparam TPkg - Type of the package-like object being processed. + */ + protected abstract processPackage( + pkg: TPkg, + kind: PackageKind, + ): Promise; + + protected parseFlags(): void { + this.selectionOptions = parsePackageSelectionFlags(this.flags, this.defaultSelection); + this.filterOptions = parsePackageFilterFlags(this.flags); + } + + protected async selectAndFilterPackages(): Promise { + if (this.selectionOptions === undefined) { + throw new Error(`No packages selected.`); + } + + const ctx = await this.getContext(); + const { selected, filtered } = await selectAndFilterPackages( + ctx, + this.selectionOptions, + this.filterOptions, + ); + + [this.selectedPackages, this.filteredPackages] = [selected, filtered]; + } + + public async run(): Promise { + this.parseFlags(); + + assert(this.selectionOptions !== undefined, "selectionOptions is undefined"); + assert(this.filterOptions !== undefined, "filterOptions is undefined"); + + await this.selectAndFilterPackages(); + + assert(this.selectedPackages !== undefined, "selectedPackages is undefined"); + assert(this.filteredPackages !== undefined, "filteredPackages is undefined"); + + this.info( + `Filtered ${this.selectedPackages.length} packages to ${listNames( + this.filteredPackages.map((pkg) => pkg.directory), + )}`, + ); + + const errors = await this.processPackages(this.filteredPackages); + if (errors.length > 0) { + this.errorLog(`Completed with ${errors.length} errors.`); + for (const error of errors) { + this.errorLog(error); + } + this.exit(1); + } + + return undefined; + } + + /** + * Runs the processPackage method on each package in the provided array. + * + * @returns An array of error strings. If the array is not empty, at least one of the calls to processPackage failed. + */ + protected async processPackages(packages: PackageWithKind[]): Promise { + let started = 0; + let finished = 0; + let succeeded = 0; + const errors: string[] = []; + + // In verbose mode, we output a log line per package. In non-verbose mode, we want to display an activity + // spinner, so we only start the spinner if verbose is false. + const { verbose } = this.flags; + + function updateStatus(): void { + if (!verbose) { + ux.action.start( + "Processing Packages...", + `${finished}/${packages.length}: ${started - finished} pending. Errors: ${ + finished - succeeded + }`, + { + stdout: true, + }, + ); + } + } + + try { + await async.mapLimit(packages, this.flags.concurrency, async (pkg: PackageWithKind) => { + started += 1; + updateStatus(); + try { + await this.processPackage(pkg, pkg.kind); + succeeded += 1; + } catch (error: unknown) { + const errorString = `Error updating ${pkg.name}: '${error}'\nStack: ${ + (error as Error).stack + }`; + errors.push(errorString); + this.verbose(errorString); + } finally { + finished += 1; + updateStatus(); + } + }); + } finally { + // Stop the spinner if needed. + if (!verbose) { + ux.action.stop(`Done. ${packages.length} Packages. ${finished - succeeded} Errors`); + } + } + return errors; + } +} + +function listNames(strings: string[] | undefined): string { + return strings === undefined + ? "" + : strings.length > 10 + ? `${strings.length}` + : `${strings.length} (${strings.join(", ")})`; +} diff --git a/build-tools/packages/build-cli/src/library/commands/baseCommand.ts b/build-tools/packages/build-cli/src/library/commands/baseCommand.ts new file mode 100644 index 000000000000..9c9f6a7dd5ba --- /dev/null +++ b/build-tools/packages/build-cli/src/library/commands/baseCommand.ts @@ -0,0 +1,27 @@ +/*! + * Copyright (c) Microsoft Corporation and contributors. All rights reserved. + * Licensed under the MIT License. + */ + +import { + IBuildProject, + findGitRootSync, + loadBuildProject, +} from "@fluid-tools/build-infrastructure"; +import { BaseCommand } from "./base.js"; +import type { Command } from "@oclif/core"; + +export abstract class BaseCommandWithBuildProject< + T extends typeof Command +> extends BaseCommand { + private _buildProject: IBuildProject | undefined; + + public getBuildProject(repoRoot?: string): IBuildProject { + if (this._buildProject === undefined) { + const root = repoRoot ?? findGitRootSync(); + this._buildProject = loadBuildProject(root); + } + + return this._buildProject; + } +} diff --git a/build-tools/packages/build-cli/src/library/commands/index.ts b/build-tools/packages/build-cli/src/library/commands/index.ts index 4aad95205d76..c6a58d8c7d91 100644 --- a/build-tools/packages/build-cli/src/library/commands/index.ts +++ b/build-tools/packages/build-cli/src/library/commands/index.ts @@ -4,6 +4,7 @@ */ export { BaseCommand } from "./base.js"; +export { BaseCommandWithBuildProject } from "./baseCommand.js"; export { unscopedPackageNameString } from "./constants.js"; export { GenerateEntrypointsCommand, diff --git a/build-tools/packages/build-cli/src/library/index.ts b/build-tools/packages/build-cli/src/library/index.ts index 77592bfcae30..7e14fd29020b 100644 --- a/build-tools/packages/build-cli/src/library/index.ts +++ b/build-tools/packages/build-cli/src/library/index.ts @@ -29,6 +29,7 @@ export { export { unscopedPackageNameString, BaseCommand, + BaseCommandWithBuildProject, GenerateEntrypointsCommand, } from "./commands/index.js"; export { Context, VersionDetails, isMonoRepoKind, MonoRepoKind } from "./context.js"; diff --git a/build-tools/packages/build-infrastructure/package.json b/build-tools/packages/build-infrastructure/package.json index 981100a48c55..82f4d5b125a1 100644 --- a/build-tools/packages/build-infrastructure/package.json +++ b/build-tools/packages/build-infrastructure/package.json @@ -1,7 +1,6 @@ { "name": "@fluid-tools/build-infrastructure", "version": "0.52.0", - "private": true, "description": "Fluid build infrastructure", "homepage": "https://fluidframework.com", "repository": { diff --git a/build-tools/pnpm-lock.yaml b/build-tools/pnpm-lock.yaml index 7d05d5e82a50..9c3d340e889b 100644 --- a/build-tools/pnpm-lock.yaml +++ b/build-tools/pnpm-lock.yaml @@ -91,6 +91,9 @@ importers: '@andrewbranch/untar.js': specifier: ^1.0.3 version: 1.0.3 + '@fluid-tools/build-infrastructure': + specifier: workspace:~ + version: link:../build-infrastructure '@fluid-tools/version-tools': specifier: workspace:~ version: link:../version-tools From b4cc2ac558b8242f75a9115c0caf21090e8dc0b5 Mon Sep 17 00:00:00 2001 From: Michael Zhen <112977307+zhenmichael@users.noreply.github.com> Date: Mon, 9 Dec 2024 17:42:33 +0000 Subject: [PATCH 02/13] move classes to one file --- .../build-cli/src/BasePackageCommand.ts | 158 ++++++++++++++- .../src/BasePackageCommandWithContext.ts | 187 ------------------ .../build-cli/src/library/commands/base.ts | 20 ++ .../src/library/commands/baseCommand.ts | 27 --- .../build-cli/src/library/commands/index.ts | 2 +- 5 files changed, 178 insertions(+), 216 deletions(-) delete mode 100644 build-tools/packages/build-cli/src/BasePackageCommandWithContext.ts delete mode 100644 build-tools/packages/build-cli/src/library/commands/baseCommand.ts diff --git a/build-tools/packages/build-cli/src/BasePackageCommand.ts b/build-tools/packages/build-cli/src/BasePackageCommand.ts index b0e6286f7a3d..606b8308a0a8 100644 --- a/build-tools/packages/build-cli/src/BasePackageCommand.ts +++ b/build-tools/packages/build-cli/src/BasePackageCommand.ts @@ -17,7 +17,7 @@ import { selectAndFilterPackages, } from "./filter.js"; import { type PackageSelectionDefault, filterFlags, selectionFlags } from "./flags.js"; -import { BaseCommand } from "./library/index.js"; +import { BaseCommand, BaseCommandWithBuildProject } from "./library/index.js"; /** * Commands that run operations per project. @@ -178,6 +178,162 @@ export abstract class PackageCommand< } } +export abstract class PackageCommandWithBuildProject< + T extends typeof Command & { flags: typeof PackageCommandWithBuildProject.flags }, +> extends BaseCommandWithBuildProject { + static readonly flags = { + concurrency: Flags.integer({ + description: "The number of tasks to execute concurrently.", + default: 25, + }), + ...selectionFlags, + ...filterFlags, + ...BaseCommandWithBuildProject.flags, + }; + + /** + * The default to use as selection criteria when none is explicitly provided by the user. This enables commands + * without flags to operate on a collection of packages by default that make sense based on the command. + */ + protected abstract get defaultSelection(): PackageSelectionDefault; + protected abstract set defaultSelection(value: PackageSelectionDefault); + + protected filterOptions: PackageFilterOptions | undefined; + protected selectionOptions: PackageSelectionCriteria | undefined; + + /** + * An array of packages selected based on the selection criteria. + * + * @remarks + * + * Note that these packages are not necessarily the ones that are acted on. Packages are selected, then that list is + * further narrowed by filtering criteria, so this array may contain packages that are not acted on. + */ + protected selectedPackages: PackageWithKind[] | undefined; + + /** + * The list of packages after all filters are applied to the selected packages. + */ + protected filteredPackages: PackageWithKind[] | undefined; + + /** + * Called for each package that is selected/filtered based on the filter flags passed in to the command. + * + * @param pkg - The package being processed. + * @param kind - The kind of the package. + * @typeparam TPkg - Type of the package-like object being processed. + */ + protected abstract processPackage( + pkg: TPkg, + kind: PackageKind, + ): Promise; + + protected parseFlags(): void { + this.selectionOptions = parsePackageSelectionFlags(this.flags, this.defaultSelection); + this.filterOptions = parsePackageFilterFlags(this.flags); + } + + protected async selectAndFilterPackages(): Promise { + if (this.selectionOptions === undefined) { + throw new Error(`No packages selected.`); + } + + const ctx = await this.getContext(); + const { selected, filtered } = await selectAndFilterPackages( + ctx, + this.selectionOptions, + this.filterOptions, + ); + + [this.selectedPackages, this.filteredPackages] = [selected, filtered]; + } + + public async run(): Promise { + this.parseFlags(); + + assert(this.selectionOptions !== undefined, "selectionOptions is undefined"); + assert(this.filterOptions !== undefined, "filterOptions is undefined"); + + await this.selectAndFilterPackages(); + + assert(this.selectedPackages !== undefined, "selectedPackages is undefined"); + assert(this.filteredPackages !== undefined, "filteredPackages is undefined"); + + this.info( + `Filtered ${this.selectedPackages.length} packages to ${listNames( + this.filteredPackages.map((pkg) => pkg.directory), + )}`, + ); + + const errors = await this.processPackages(this.filteredPackages); + if (errors.length > 0) { + this.errorLog(`Completed with ${errors.length} errors.`); + for (const error of errors) { + this.errorLog(error); + } + this.exit(1); + } + + return undefined; + } + + /** + * Runs the processPackage method on each package in the provided array. + * + * @returns An array of error strings. If the array is not empty, at least one of the calls to processPackage failed. + */ + protected async processPackages(packages: PackageWithKind[]): Promise { + let started = 0; + let finished = 0; + let succeeded = 0; + const errors: string[] = []; + + // In verbose mode, we output a log line per package. In non-verbose mode, we want to display an activity + // spinner, so we only start the spinner if verbose is false. + const { verbose } = this.flags; + + function updateStatus(): void { + if (!verbose) { + ux.action.start( + "Processing Packages...", + `${finished}/${packages.length}: ${started - finished} pending. Errors: ${ + finished - succeeded + }`, + { + stdout: true, + }, + ); + } + } + + try { + await async.mapLimit(packages, this.flags.concurrency, async (pkg: PackageWithKind) => { + started += 1; + updateStatus(); + try { + await this.processPackage(pkg, pkg.kind); + succeeded += 1; + } catch (error: unknown) { + const errorString = `Error updating ${pkg.name}: '${error}'\nStack: ${ + (error as Error).stack + }`; + errors.push(errorString); + this.verbose(errorString); + } finally { + finished += 1; + updateStatus(); + } + }); + } finally { + // Stop the spinner if needed. + if (!verbose) { + ux.action.stop(`Done. ${packages.length} Packages. ${finished - succeeded} Errors`); + } + } + return errors; + } +} + function listNames(strings: string[] | undefined): string { return strings === undefined ? "" diff --git a/build-tools/packages/build-cli/src/BasePackageCommandWithContext.ts b/build-tools/packages/build-cli/src/BasePackageCommandWithContext.ts deleted file mode 100644 index 8988e11bfd80..000000000000 --- a/build-tools/packages/build-cli/src/BasePackageCommandWithContext.ts +++ /dev/null @@ -1,187 +0,0 @@ -/*! - * Copyright (c) Microsoft Corporation and contributors. All rights reserved. - * Licensed under the MIT License. - */ - -import { strict as assert } from "node:assert"; -import { Package } from "@fluidframework/build-tools"; -import { Flags, ux, type Command } from "@oclif/core"; -import async from "async"; -import { - PackageFilterOptions, - PackageKind, - PackageSelectionCriteria, - PackageWithKind, - parsePackageFilterFlags, - parsePackageSelectionFlags, - selectAndFilterPackages, -} from "./filter.js"; -import { type PackageSelectionDefault, filterFlags, selectionFlags } from "./flags.js"; -import { BaseCommandWithBuildProject } from "./library/commands/baseCommand.js"; - -/** - * Commands that run operations per project. - */ -export abstract class PackageCommandWithBuildProject< - T extends typeof Command & { flags: typeof PackageCommandWithBuildProject.flags }, -> extends BaseCommandWithBuildProject { - static readonly flags = { - concurrency: Flags.integer({ - description: "The number of tasks to execute concurrently.", - default: 25, - }), - ...selectionFlags, - ...filterFlags, - ...BaseCommandWithBuildProject.flags, - }; - - /** - * The default to use as selection criteria when none is explicitly provided by the user. This enables commands - * without flags to operate on a collection of packages by default that make sense based on the command. - */ - protected abstract get defaultSelection(): PackageSelectionDefault; - protected abstract set defaultSelection(value: PackageSelectionDefault); - - protected filterOptions: PackageFilterOptions | undefined; - protected selectionOptions: PackageSelectionCriteria | undefined; - - /** - * An array of packages selected based on the selection criteria. - * - * @remarks - * - * Note that these packages are not necessarily the ones that are acted on. Packages are selected, then that list is - * further narrowed by filtering criteria, so this array may contain packages that are not acted on. - */ - protected selectedPackages: PackageWithKind[] | undefined; - - /** - * The list of packages after all filters are applied to the selected packages. - */ - protected filteredPackages: PackageWithKind[] | undefined; - - /** - * Called for each package that is selected/filtered based on the filter flags passed in to the command. - * - * @param pkg - The package being processed. - * @param kind - The kind of the package. - * @typeparam TPkg - Type of the package-like object being processed. - */ - protected abstract processPackage( - pkg: TPkg, - kind: PackageKind, - ): Promise; - - protected parseFlags(): void { - this.selectionOptions = parsePackageSelectionFlags(this.flags, this.defaultSelection); - this.filterOptions = parsePackageFilterFlags(this.flags); - } - - protected async selectAndFilterPackages(): Promise { - if (this.selectionOptions === undefined) { - throw new Error(`No packages selected.`); - } - - const ctx = await this.getContext(); - const { selected, filtered } = await selectAndFilterPackages( - ctx, - this.selectionOptions, - this.filterOptions, - ); - - [this.selectedPackages, this.filteredPackages] = [selected, filtered]; - } - - public async run(): Promise { - this.parseFlags(); - - assert(this.selectionOptions !== undefined, "selectionOptions is undefined"); - assert(this.filterOptions !== undefined, "filterOptions is undefined"); - - await this.selectAndFilterPackages(); - - assert(this.selectedPackages !== undefined, "selectedPackages is undefined"); - assert(this.filteredPackages !== undefined, "filteredPackages is undefined"); - - this.info( - `Filtered ${this.selectedPackages.length} packages to ${listNames( - this.filteredPackages.map((pkg) => pkg.directory), - )}`, - ); - - const errors = await this.processPackages(this.filteredPackages); - if (errors.length > 0) { - this.errorLog(`Completed with ${errors.length} errors.`); - for (const error of errors) { - this.errorLog(error); - } - this.exit(1); - } - - return undefined; - } - - /** - * Runs the processPackage method on each package in the provided array. - * - * @returns An array of error strings. If the array is not empty, at least one of the calls to processPackage failed. - */ - protected async processPackages(packages: PackageWithKind[]): Promise { - let started = 0; - let finished = 0; - let succeeded = 0; - const errors: string[] = []; - - // In verbose mode, we output a log line per package. In non-verbose mode, we want to display an activity - // spinner, so we only start the spinner if verbose is false. - const { verbose } = this.flags; - - function updateStatus(): void { - if (!verbose) { - ux.action.start( - "Processing Packages...", - `${finished}/${packages.length}: ${started - finished} pending. Errors: ${ - finished - succeeded - }`, - { - stdout: true, - }, - ); - } - } - - try { - await async.mapLimit(packages, this.flags.concurrency, async (pkg: PackageWithKind) => { - started += 1; - updateStatus(); - try { - await this.processPackage(pkg, pkg.kind); - succeeded += 1; - } catch (error: unknown) { - const errorString = `Error updating ${pkg.name}: '${error}'\nStack: ${ - (error as Error).stack - }`; - errors.push(errorString); - this.verbose(errorString); - } finally { - finished += 1; - updateStatus(); - } - }); - } finally { - // Stop the spinner if needed. - if (!verbose) { - ux.action.stop(`Done. ${packages.length} Packages. ${finished - succeeded} Errors`); - } - } - return errors; - } -} - -function listNames(strings: string[] | undefined): string { - return strings === undefined - ? "" - : strings.length > 10 - ? `${strings.length}` - : `${strings.length} (${strings.join(", ")})`; -} diff --git a/build-tools/packages/build-cli/src/library/commands/base.ts b/build-tools/packages/build-cli/src/library/commands/base.ts index 90ec32f9aacf..69a797518100 100644 --- a/build-tools/packages/build-cli/src/library/commands/base.ts +++ b/build-tools/packages/build-cli/src/library/commands/base.ts @@ -8,6 +8,11 @@ import { Command, Flags, Interfaces } from "@oclif/core"; import type { PrettyPrintableError } from "@oclif/core/errors"; import chalk from "picocolors"; +import { + IBuildProject, + findGitRootSync, + loadBuildProject, +} from "@fluid-tools/build-infrastructure"; import { GitRepo, getResolvedFluidRoot } from "@fluidframework/build-tools"; import { CommandLogger } from "../../logging.js"; import { Context } from "../context.js"; @@ -284,3 +289,18 @@ export abstract class BaseCommand } } } + +export abstract class BaseCommandWithBuildProject< + T extends typeof Command, +> extends BaseCommand { + private _buildProject: IBuildProject | undefined; + + public getBuildProject(repoRoot?: string): IBuildProject { + if (this._buildProject === undefined) { + const root = repoRoot ?? findGitRootSync(); + this._buildProject = loadBuildProject(root); + } + + return this._buildProject; + } +} diff --git a/build-tools/packages/build-cli/src/library/commands/baseCommand.ts b/build-tools/packages/build-cli/src/library/commands/baseCommand.ts deleted file mode 100644 index 9c9f6a7dd5ba..000000000000 --- a/build-tools/packages/build-cli/src/library/commands/baseCommand.ts +++ /dev/null @@ -1,27 +0,0 @@ -/*! - * Copyright (c) Microsoft Corporation and contributors. All rights reserved. - * Licensed under the MIT License. - */ - -import { - IBuildProject, - findGitRootSync, - loadBuildProject, -} from "@fluid-tools/build-infrastructure"; -import { BaseCommand } from "./base.js"; -import type { Command } from "@oclif/core"; - -export abstract class BaseCommandWithBuildProject< - T extends typeof Command -> extends BaseCommand { - private _buildProject: IBuildProject | undefined; - - public getBuildProject(repoRoot?: string): IBuildProject { - if (this._buildProject === undefined) { - const root = repoRoot ?? findGitRootSync(); - this._buildProject = loadBuildProject(root); - } - - return this._buildProject; - } -} diff --git a/build-tools/packages/build-cli/src/library/commands/index.ts b/build-tools/packages/build-cli/src/library/commands/index.ts index c6a58d8c7d91..1e3fa035519e 100644 --- a/build-tools/packages/build-cli/src/library/commands/index.ts +++ b/build-tools/packages/build-cli/src/library/commands/index.ts @@ -4,7 +4,7 @@ */ export { BaseCommand } from "./base.js"; -export { BaseCommandWithBuildProject } from "./baseCommand.js"; +export { BaseCommandWithBuildProject } from "./base.js"; export { unscopedPackageNameString } from "./constants.js"; export { GenerateEntrypointsCommand, From e895f524cdab64ec04a04a109171a7928bc5ecb5 Mon Sep 17 00:00:00 2001 From: Michael Zhen <112977307+zhenmichael@users.noreply.github.com> Date: Tue, 10 Dec 2024 15:19:32 +0000 Subject: [PATCH 03/13] remove base package command implementation, update basecommand --- .../build-cli/src/BasePackageCommand.ts | 156 ------------------ .../commands/vnext/check/latestVersions.ts | 0 .../build-cli/src/library/commands/base.ts | 9 +- 3 files changed, 6 insertions(+), 159 deletions(-) create mode 100644 build-tools/packages/build-cli/src/commands/vnext/check/latestVersions.ts diff --git a/build-tools/packages/build-cli/src/BasePackageCommand.ts b/build-tools/packages/build-cli/src/BasePackageCommand.ts index 606b8308a0a8..00e229cf386a 100644 --- a/build-tools/packages/build-cli/src/BasePackageCommand.ts +++ b/build-tools/packages/build-cli/src/BasePackageCommand.ts @@ -178,162 +178,6 @@ export abstract class PackageCommand< } } -export abstract class PackageCommandWithBuildProject< - T extends typeof Command & { flags: typeof PackageCommandWithBuildProject.flags }, -> extends BaseCommandWithBuildProject { - static readonly flags = { - concurrency: Flags.integer({ - description: "The number of tasks to execute concurrently.", - default: 25, - }), - ...selectionFlags, - ...filterFlags, - ...BaseCommandWithBuildProject.flags, - }; - - /** - * The default to use as selection criteria when none is explicitly provided by the user. This enables commands - * without flags to operate on a collection of packages by default that make sense based on the command. - */ - protected abstract get defaultSelection(): PackageSelectionDefault; - protected abstract set defaultSelection(value: PackageSelectionDefault); - - protected filterOptions: PackageFilterOptions | undefined; - protected selectionOptions: PackageSelectionCriteria | undefined; - - /** - * An array of packages selected based on the selection criteria. - * - * @remarks - * - * Note that these packages are not necessarily the ones that are acted on. Packages are selected, then that list is - * further narrowed by filtering criteria, so this array may contain packages that are not acted on. - */ - protected selectedPackages: PackageWithKind[] | undefined; - - /** - * The list of packages after all filters are applied to the selected packages. - */ - protected filteredPackages: PackageWithKind[] | undefined; - - /** - * Called for each package that is selected/filtered based on the filter flags passed in to the command. - * - * @param pkg - The package being processed. - * @param kind - The kind of the package. - * @typeparam TPkg - Type of the package-like object being processed. - */ - protected abstract processPackage( - pkg: TPkg, - kind: PackageKind, - ): Promise; - - protected parseFlags(): void { - this.selectionOptions = parsePackageSelectionFlags(this.flags, this.defaultSelection); - this.filterOptions = parsePackageFilterFlags(this.flags); - } - - protected async selectAndFilterPackages(): Promise { - if (this.selectionOptions === undefined) { - throw new Error(`No packages selected.`); - } - - const ctx = await this.getContext(); - const { selected, filtered } = await selectAndFilterPackages( - ctx, - this.selectionOptions, - this.filterOptions, - ); - - [this.selectedPackages, this.filteredPackages] = [selected, filtered]; - } - - public async run(): Promise { - this.parseFlags(); - - assert(this.selectionOptions !== undefined, "selectionOptions is undefined"); - assert(this.filterOptions !== undefined, "filterOptions is undefined"); - - await this.selectAndFilterPackages(); - - assert(this.selectedPackages !== undefined, "selectedPackages is undefined"); - assert(this.filteredPackages !== undefined, "filteredPackages is undefined"); - - this.info( - `Filtered ${this.selectedPackages.length} packages to ${listNames( - this.filteredPackages.map((pkg) => pkg.directory), - )}`, - ); - - const errors = await this.processPackages(this.filteredPackages); - if (errors.length > 0) { - this.errorLog(`Completed with ${errors.length} errors.`); - for (const error of errors) { - this.errorLog(error); - } - this.exit(1); - } - - return undefined; - } - - /** - * Runs the processPackage method on each package in the provided array. - * - * @returns An array of error strings. If the array is not empty, at least one of the calls to processPackage failed. - */ - protected async processPackages(packages: PackageWithKind[]): Promise { - let started = 0; - let finished = 0; - let succeeded = 0; - const errors: string[] = []; - - // In verbose mode, we output a log line per package. In non-verbose mode, we want to display an activity - // spinner, so we only start the spinner if verbose is false. - const { verbose } = this.flags; - - function updateStatus(): void { - if (!verbose) { - ux.action.start( - "Processing Packages...", - `${finished}/${packages.length}: ${started - finished} pending. Errors: ${ - finished - succeeded - }`, - { - stdout: true, - }, - ); - } - } - - try { - await async.mapLimit(packages, this.flags.concurrency, async (pkg: PackageWithKind) => { - started += 1; - updateStatus(); - try { - await this.processPackage(pkg, pkg.kind); - succeeded += 1; - } catch (error: unknown) { - const errorString = `Error updating ${pkg.name}: '${error}'\nStack: ${ - (error as Error).stack - }`; - errors.push(errorString); - this.verbose(errorString); - } finally { - finished += 1; - updateStatus(); - } - }); - } finally { - // Stop the spinner if needed. - if (!verbose) { - ux.action.stop(`Done. ${packages.length} Packages. ${finished - succeeded} Errors`); - } - } - return errors; - } -} - function listNames(strings: string[] | undefined): string { return strings === undefined ? "" diff --git a/build-tools/packages/build-cli/src/commands/vnext/check/latestVersions.ts b/build-tools/packages/build-cli/src/commands/vnext/check/latestVersions.ts new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/build-tools/packages/build-cli/src/library/commands/base.ts b/build-tools/packages/build-cli/src/library/commands/base.ts index 41068597a597..1e8aeed645da 100644 --- a/build-tools/packages/build-cli/src/library/commands/base.ts +++ b/build-tools/packages/build-cli/src/library/commands/base.ts @@ -11,7 +11,6 @@ import chalk from "picocolors"; import { IBuildProject, - findGitRootSync, loadBuildProject, } from "@fluid-tools/build-infrastructure"; import { CommandLogger } from "../../logging.js"; @@ -293,9 +292,13 @@ export abstract class BaseCommandWithBuildProject< > extends BaseCommand { private _buildProject: IBuildProject | undefined; - public getBuildProject(repoRoot?: string): IBuildProject { + public getContext(): never { + throw new Error("getContext method should only be called in BaseCommand instances"); + } + + public getBuildProject(searchPath?: string): IBuildProject { if (this._buildProject === undefined) { - const root = repoRoot ?? findGitRootSync(); + const root = searchPath ?? process.cwd(); this._buildProject = loadBuildProject(root); } From e11e7b12319c4686d668dd084fa4444190cc3fcc Mon Sep 17 00:00:00 2001 From: Michael Zhen <112977307+zhenmichael@users.noreply.github.com> Date: Tue, 10 Dec 2024 17:10:45 +0000 Subject: [PATCH 04/13] initial check latestVersions implementation --- build-tools/packages/build-cli/README.md | 1 + build-tools/packages/build-cli/docs/vnext.md | 33 ++++++ build-tools/packages/build-cli/package.json | 2 +- .../build-cli/src/BasePackageCommand.ts | 2 +- .../commands/vnext/check/latestVersions.ts | 100 ++++++++++++++++++ .../build-cli/src/library/commands/base.ts | 14 +-- .../packages/build-cli/src/library/git.ts | 39 +++++++ .../packages/build-cli/src/library/index.ts | 2 +- 8 files changed, 184 insertions(+), 9 deletions(-) create mode 100644 build-tools/packages/build-cli/docs/vnext.md diff --git a/build-tools/packages/build-cli/README.md b/build-tools/packages/build-cli/README.md index d7f6bdc69b9a..9c81814184a0 100644 --- a/build-tools/packages/build-cli/README.md +++ b/build-tools/packages/build-cli/README.md @@ -51,6 +51,7 @@ USAGE * [`flub run`](docs/run.md) - Generate a report from input bundle stats collected through the collect bundleStats command. * [`flub transform`](docs/transform.md) - Transform commands are used to transform code, docs, etc. into alternative forms. * [`flub typetests`](docs/typetests.md) - Updates configuration for type tests in package.json files. If the previous version changes after running preparation, then npm install must be run before building. +* [`flub vnext`](docs/vnext.md) - Determines if an input version matches a latest minor release version. Intended to be used in the Fluid Framework CI pipeline only. diff --git a/build-tools/packages/build-cli/docs/vnext.md b/build-tools/packages/build-cli/docs/vnext.md new file mode 100644 index 000000000000..04971b03a1ef --- /dev/null +++ b/build-tools/packages/build-cli/docs/vnext.md @@ -0,0 +1,33 @@ +`flub vnext` +============ + +Determines if an input version matches a latest minor release version. Intended to be used in the Fluid Framework CI pipeline only. + +* [`flub vnext check latestVersions VERSION PACKAGE_OR_RELEASE_GROUP`](#flub-vnext-check-latestversions-version-package_or_release_group) + +## `flub vnext check latestVersions VERSION PACKAGE_OR_RELEASE_GROUP` + +Determines if an input version matches a latest minor release version. Intended to be used in the Fluid Framework CI pipeline only. + +``` +USAGE + $ flub vnext check latestVersions VERSION PACKAGE_OR_RELEASE_GROUP [-v | --quiet] + +ARGUMENTS + VERSION The version to check. When running in CI, this value corresponds to the pipeline trigger + branch. + PACKAGE_OR_RELEASE_GROUP The name of a package or a release group. + +LOGGING FLAGS + -v, --verbose Enable verbose logging. + --quiet Disable all logging. + +DESCRIPTION + Determines if an input version matches a latest minor release version. Intended to be used in the Fluid Framework CI + pipeline only. + + This command is used in CI to determine if a pipeline was triggered by a release branch with the latest minor version + of a major version. +``` + +_See code: [src/commands/vnext/check/latestVersions.ts](https://github.com/microsoft/FluidFramework/blob/main/build-tools/packages/build-cli/src/commands/vnext/check/latestVersions.ts)_ diff --git a/build-tools/packages/build-cli/package.json b/build-tools/packages/build-cli/package.json index 841d512f90ba..e219bcb0f0e6 100644 --- a/build-tools/packages/build-cli/package.json +++ b/build-tools/packages/build-cli/package.json @@ -80,9 +80,9 @@ }, "dependencies": { "@andrewbranch/untar.js": "^1.0.3", + "@fluid-tools/build-infrastructure": "workspace:~", "@fluid-tools/version-tools": "workspace:~", "@fluidframework/build-tools": "workspace:~", - "@fluid-tools/build-infrastructure": "workspace:~", "@fluidframework/bundle-size-tools": "workspace:~", "@inquirer/prompts": "^7.0.1", "@microsoft/api-extractor": "^7.47.11", diff --git a/build-tools/packages/build-cli/src/BasePackageCommand.ts b/build-tools/packages/build-cli/src/BasePackageCommand.ts index 00e229cf386a..b0e6286f7a3d 100644 --- a/build-tools/packages/build-cli/src/BasePackageCommand.ts +++ b/build-tools/packages/build-cli/src/BasePackageCommand.ts @@ -17,7 +17,7 @@ import { selectAndFilterPackages, } from "./filter.js"; import { type PackageSelectionDefault, filterFlags, selectionFlags } from "./flags.js"; -import { BaseCommand, BaseCommandWithBuildProject } from "./library/index.js"; +import { BaseCommand } from "./library/index.js"; /** * Commands that run operations per project. diff --git a/build-tools/packages/build-cli/src/commands/vnext/check/latestVersions.ts b/build-tools/packages/build-cli/src/commands/vnext/check/latestVersions.ts index e69de29bb2d1..3410e0977bce 100644 --- a/build-tools/packages/build-cli/src/commands/vnext/check/latestVersions.ts +++ b/build-tools/packages/build-cli/src/commands/vnext/check/latestVersions.ts @@ -0,0 +1,100 @@ +/*! + * Copyright (c) Microsoft Corporation and contributors. All rights reserved. + * Licensed under the MIT License. + */ + +import { WorkspaceName } from "@fluid-tools/build-infrastructure"; +import { isInternalVersionScheme } from "@fluid-tools/version-tools"; +import * as semver from "semver"; +import { packageOrReleaseGroupArg, semverArg } from "../../../args.js"; +import { + BaseCommandWithBuildProject, + getAllPackageVersions, + sortVersions, +} from "../../../library/index.js"; + +type MajorVersion = number; + +export default class LatestVersionsCommand extends BaseCommandWithBuildProject< + typeof LatestVersionsCommand +> { + static readonly summary = + "Determines if an input version matches a latest minor release version. Intended to be used in the Fluid Framework CI pipeline only."; + + static readonly description = + "This command is used in CI to determine if a pipeline was triggered by a release branch with the latest minor version of a major version."; + + static readonly args = { + version: semverArg({ + required: true, + description: + "The version to check. When running in CI, this value corresponds to the pipeline trigger branch.", + }), + package_or_release_group: packageOrReleaseGroupArg({ required: true }), + } as const; + + public async run(): Promise { + const { args } = this; + const repo = this.getBuildProject(); + const rgOrPackage = repo.workspaces.get(args.package_or_release_group as WorkspaceName); + + const versionInput = this.args.version; + + if (rgOrPackage === undefined) { + this.error(`Package not found: ${args.package_or_release_group}`); + } + + const git = await repo.getGitRepository(); + const versions = await getAllPackageVersions(rgOrPackage.name, git); + + if (!versions) { + this.error(`No versions found for ${rgOrPackage.name}`); + } + + // Filter out pre-release versions + const stableVersions = versions.filter((v) => { + return !isInternalVersionScheme(v.version); + }); + + // Sort the semver versions ordered from highest to lowest + const sortedByVersion = sortVersions(stableVersions, "version"); + + const inputMajorVersion: MajorVersion = semver.major(versionInput.version); + + for (const v of sortedByVersion) { + const majorVersion: MajorVersion = semver.major(v.version); + + // Since sortedByVersion is sorted, the first encountered version is the highest one + if (majorVersion === inputMajorVersion) { + if (v.version === versionInput.version) { + // Check if the input version is the latest version for the major version + this.log( + `Version ${versionInput.version} is the latest version for major version ${majorVersion}`, + ); + this.log(`##vso[task.setvariable variable=shouldDeploy;isoutput=true]true`); + this.log( + `##vso[task.setvariable variable=majorVersion;isoutput=true]${majorVersion}`, + ); + return; + } + + // If versions do not match on first major version encounter, then the input version is not the latest + this.log( + `##[warning]skipping deployment stage. input version ${versionInput.version} does not match the latest version ${v.version}`, + ); + this.log(`##vso[task.setvariable variable=shouldDeploy;isoutput=true]false`); + this.log(`##vso[task.setvariable variable=majorVersion;isoutput=true]${majorVersion}`); + return; + } + } + + // Error if no major version corresponds to input version + this.log( + `##[warning]No major version found corresponding to input version ${versionInput.version}`, + ); + this.log(`##vso[task.setvariable variable=shouldDeploy;isoutput=true]false`); + this.log( + `##vso[task.setvariable variable=majorVersion;isoutput=true]${inputMajorVersion}`, + ); + } +} diff --git a/build-tools/packages/build-cli/src/library/commands/base.ts b/build-tools/packages/build-cli/src/library/commands/base.ts index 1e8aeed645da..bf1992130805 100644 --- a/build-tools/packages/build-cli/src/library/commands/base.ts +++ b/build-tools/packages/build-cli/src/library/commands/base.ts @@ -9,10 +9,7 @@ import { Command, Flags, Interfaces } from "@oclif/core"; import type { PrettyPrintableError } from "@oclif/core/errors"; import chalk from "picocolors"; -import { - IBuildProject, - loadBuildProject, -} from "@fluid-tools/build-infrastructure"; +import { IBuildProject, loadBuildProject } from "@fluid-tools/build-infrastructure"; import { CommandLogger } from "../../logging.js"; import { Context } from "../context.js"; import { indentString } from "../text.js"; @@ -292,9 +289,14 @@ export abstract class BaseCommandWithBuildProject< > extends BaseCommand { private _buildProject: IBuildProject | undefined; + /** + * This method is deprecated and should only be called in BaseCommand instances. + * + * @deprecated This method should only be called in BaseCommand instances. + */ public getContext(): never { - throw new Error("getContext method should only be called in BaseCommand instances"); - } + throw new Error("getContext method should only be called in BaseCommand instances"); + } public getBuildProject(searchPath?: string): IBuildProject { if (this._buildProject === undefined) { diff --git a/build-tools/packages/build-cli/src/library/git.ts b/build-tools/packages/build-cli/src/library/git.ts index 3c6f3f5b6e7a..cdcd2480f3d8 100644 --- a/build-tools/packages/build-cli/src/library/git.ts +++ b/build-tools/packages/build-cli/src/library/git.ts @@ -43,6 +43,45 @@ function getVersionFromTag(tag: string): string | undefined { return ver.version; } +export async function getAllPackageVersions( + releaseGroupOrPackage: string, + git: Readonly, +): Promise { + const prefix = PackageName.getUnscopedName(releaseGroupOrPackage); + + const tags = await git.tags(["--list", `${prefix}_v*`]); + + const versions = new Map(); + + for (const tag of tags.all) { + const ver = getVersionFromTag(tag); + if (ver !== undefined && ver !== "" && ver !== null) { + // eslint-disable-next-line no-await-in-loop + const rawDate = await git.show([ + // Suppress the diff output + "-s", + // ISO 8601 format + "--format=%cI", + // the git ref - a tag in this case + tag, + ]); + const date = parseISO(rawDate.trim()); + versions.set(ver, date); + } + } + + if (versions.size === 0) { + return undefined; + } + + const toReturn: VersionDetails[] = []; + for (const [version, date] of versions) { + toReturn.push({ version, date }); + } + + return toReturn; +} + /** * A type of string used to denote a GitHub repo by owner and repo name. */ diff --git a/build-tools/packages/build-cli/src/library/index.ts b/build-tools/packages/build-cli/src/library/index.ts index 7e14fd29020b..acf69d7dcbc9 100644 --- a/build-tools/packages/build-cli/src/library/index.ts +++ b/build-tools/packages/build-cli/src/library/index.ts @@ -33,7 +33,7 @@ export { GenerateEntrypointsCommand, } from "./commands/index.js"; export { Context, VersionDetails, isMonoRepoKind, MonoRepoKind } from "./context.js"; -export { Repository } from "./git.js"; +export { Repository, getAllPackageVersions } from "./git.js"; export { ensureDevDependencyExists, filterVersionsOlderThan, From c5924e9d50f0fcde982a5be5c2c973e09f57ec2e Mon Sep 17 00:00:00 2001 From: Michael Zhen <112977307+zhenmichael@users.noreply.github.com> Date: Wed, 11 Dec 2024 20:23:38 +0000 Subject: [PATCH 05/13] update args, doc strings --- build-tools/packages/build-cli/docs/vnext.md | 11 ++++---- build-tools/packages/build-cli/src/args.ts | 27 +++++++++++++++++++ .../commands/vnext/check/latestVersions.ts | 23 ++++++++-------- .../build-cli/src/library/commands/base.ts | 6 +++++ .../packages/build-cli/src/library/git.ts | 14 +++++++--- .../packages/build-cli/src/library/index.ts | 2 +- 6 files changed, 61 insertions(+), 22 deletions(-) diff --git a/build-tools/packages/build-cli/docs/vnext.md b/build-tools/packages/build-cli/docs/vnext.md index 04971b03a1ef..351ae0a636d8 100644 --- a/build-tools/packages/build-cli/docs/vnext.md +++ b/build-tools/packages/build-cli/docs/vnext.md @@ -3,20 +3,19 @@ Determines if an input version matches a latest minor release version. Intended to be used in the Fluid Framework CI pipeline only. -* [`flub vnext check latestVersions VERSION PACKAGE_OR_RELEASE_GROUP`](#flub-vnext-check-latestversions-version-package_or_release_group) +* [`flub vnext check latestVersions VERSION RELEASE_GROUP`](#flub-vnext-check-latestversions-version-release_group) -## `flub vnext check latestVersions VERSION PACKAGE_OR_RELEASE_GROUP` +## `flub vnext check latestVersions VERSION RELEASE_GROUP` Determines if an input version matches a latest minor release version. Intended to be used in the Fluid Framework CI pipeline only. ``` USAGE - $ flub vnext check latestVersions VERSION PACKAGE_OR_RELEASE_GROUP [-v | --quiet] + $ flub vnext check latestVersions VERSION RELEASE_GROUP [-v | --quiet] ARGUMENTS - VERSION The version to check. When running in CI, this value corresponds to the pipeline trigger - branch. - PACKAGE_OR_RELEASE_GROUP The name of a package or a release group. + VERSION The version to check. When running in CI, this value corresponds to the pipeline trigger branch. + RELEASE_GROUP The name of a release group. LOGGING FLAGS -v, --verbose Enable verbose logging. diff --git a/build-tools/packages/build-cli/src/args.ts b/build-tools/packages/build-cli/src/args.ts index 70510512dce0..4efc2ad900f9 100644 --- a/build-tools/packages/build-cli/src/args.ts +++ b/build-tools/packages/build-cli/src/args.ts @@ -3,6 +3,11 @@ * Licensed under the MIT License. */ +import type { + IBuildProject, + IReleaseGroup, + ReleaseGroupName, +} from "@fluid-tools/build-infrastructure"; import { MonoRepo, Package } from "@fluidframework/build-tools"; import { Args } from "@oclif/core"; import { PackageName } from "@rushstack/node-core-library"; @@ -39,6 +44,28 @@ export const findPackageOrReleaseGroup = ( ); }; +/** + * Creates a CLI argument for release group names. It's a factory function so that commands can override the + * properties more easily when using the argument. + */ +export const releaseGroupArg = Args.custom({ + name: "release_group", + required: true, + description: "The name of a release group.", +}); + +/** + * Takes a package or release group name and searches the build project for it. + * Release groups are checked first, then independent packages by scoped name, then by unscoped name. + */ +export const findReleaseGroup = ( + name: string, + buildProject: IBuildProject, +): IReleaseGroup | undefined => { + return buildProject.releaseGroups.get(name as ReleaseGroupName); + // ?? buildProject.packages.get(name as PkgName) +}; + /** * Creates a CLI argument for semver versions. It's a factory function so that commands can override the properties more * easily when using the argument. diff --git a/build-tools/packages/build-cli/src/commands/vnext/check/latestVersions.ts b/build-tools/packages/build-cli/src/commands/vnext/check/latestVersions.ts index 3410e0977bce..dffcfb2f69da 100644 --- a/build-tools/packages/build-cli/src/commands/vnext/check/latestVersions.ts +++ b/build-tools/packages/build-cli/src/commands/vnext/check/latestVersions.ts @@ -3,13 +3,12 @@ * Licensed under the MIT License. */ -import { WorkspaceName } from "@fluid-tools/build-infrastructure"; import { isInternalVersionScheme } from "@fluid-tools/version-tools"; import * as semver from "semver"; -import { packageOrReleaseGroupArg, semverArg } from "../../../args.js"; +import { findReleaseGroup, releaseGroupArg, semverArg } from "../../../args.js"; import { BaseCommandWithBuildProject, - getAllPackageVersions, + getVersionsFromTags, sortVersions, } from "../../../library/index.js"; @@ -30,25 +29,25 @@ export default class LatestVersionsCommand extends BaseCommandWithBuildProject< description: "The version to check. When running in CI, this value corresponds to the pipeline trigger branch.", }), - package_or_release_group: packageOrReleaseGroupArg({ required: true }), + release_group: releaseGroupArg({ required: true }), } as const; public async run(): Promise { const { args } = this; - const repo = this.getBuildProject(); - const rgOrPackage = repo.workspaces.get(args.package_or_release_group as WorkspaceName); + const buildProject = this.getBuildProject(); + const releaseGroup = findReleaseGroup(args.release_group, buildProject); - const versionInput = this.args.version; + const versionInput = args.version; - if (rgOrPackage === undefined) { - this.error(`Package not found: ${args.package_or_release_group}`); + if (releaseGroup === undefined) { + this.error(`Package not found: ${args.release_group}`); } - const git = await repo.getGitRepository(); - const versions = await getAllPackageVersions(rgOrPackage.name, git); + const git = await buildProject.getGitRepository(); + const versions = await getVersionsFromTags(releaseGroup, git); if (!versions) { - this.error(`No versions found for ${rgOrPackage.name}`); + this.error(`No versions found for ${releaseGroup.name}`); } // Filter out pre-release versions diff --git a/build-tools/packages/build-cli/src/library/commands/base.ts b/build-tools/packages/build-cli/src/library/commands/base.ts index bf1992130805..7aefa5dac7fa 100644 --- a/build-tools/packages/build-cli/src/library/commands/base.ts +++ b/build-tools/packages/build-cli/src/library/commands/base.ts @@ -298,6 +298,12 @@ export abstract class BaseCommandWithBuildProject< throw new Error("getContext method should only be called in BaseCommand instances"); } + /** + * Gets the build project for the current command. The build project is loaded from the closest build root to searchPath. + * + * @param searchPath - The path to search for the build project. + * @returns The build project. + */ public getBuildProject(searchPath?: string): IBuildProject { if (this._buildProject === undefined) { const root = searchPath ?? process.cwd(); diff --git a/build-tools/packages/build-cli/src/library/git.ts b/build-tools/packages/build-cli/src/library/git.ts index cdcd2480f3d8..89ba6a063f01 100644 --- a/build-tools/packages/build-cli/src/library/git.ts +++ b/build-tools/packages/build-cli/src/library/git.ts @@ -12,6 +12,7 @@ import * as semver from "semver"; import { SimpleGit, SimpleGitOptions, simpleGit } from "simple-git"; import type { SetRequired } from "type-fest"; +import type { IReleaseGroup } from "@fluid-tools/build-infrastructure"; import { parseISO } from "date-fns"; import { CommandLogger } from "../logging.js"; import { ReleaseGroup } from "../releaseGroups.js"; @@ -43,11 +44,18 @@ function getVersionFromTag(tag: string): string | undefined { return ver.version; } -export async function getAllPackageVersions( - releaseGroupOrPackage: string, +/** + * Get all the versions for a release group. This function only considers the tags in the repo. + * + * @param git - The git repository. + * @param releaseGroup - The release group to get versions for. + * @returns List of version details, or undefined if one could not be found. + */ +export async function getVersionsFromTags( + releaseGroup: IReleaseGroup, git: Readonly, ): Promise { - const prefix = PackageName.getUnscopedName(releaseGroupOrPackage); + const prefix = PackageName.getUnscopedName(releaseGroup.name); const tags = await git.tags(["--list", `${prefix}_v*`]); diff --git a/build-tools/packages/build-cli/src/library/index.ts b/build-tools/packages/build-cli/src/library/index.ts index acf69d7dcbc9..63ea6d560c5d 100644 --- a/build-tools/packages/build-cli/src/library/index.ts +++ b/build-tools/packages/build-cli/src/library/index.ts @@ -33,7 +33,7 @@ export { GenerateEntrypointsCommand, } from "./commands/index.js"; export { Context, VersionDetails, isMonoRepoKind, MonoRepoKind } from "./context.js"; -export { Repository, getAllPackageVersions } from "./git.js"; +export { Repository, getVersionsFromTags } from "./git.js"; export { ensureDevDependencyExists, filterVersionsOlderThan, From 028bd0a6a8365ce1d5fd51531316937a62949e7c Mon Sep 17 00:00:00 2001 From: Michael Zhen <112977307+zhenmichael@users.noreply.github.com> Date: Wed, 11 Dec 2024 20:58:56 +0000 Subject: [PATCH 06/13] update findReleaseGroup to only return release group --- build-tools/packages/build-cli/src/args.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/build-tools/packages/build-cli/src/args.ts b/build-tools/packages/build-cli/src/args.ts index 4efc2ad900f9..f9c380167aa8 100644 --- a/build-tools/packages/build-cli/src/args.ts +++ b/build-tools/packages/build-cli/src/args.ts @@ -55,15 +55,13 @@ export const releaseGroupArg = Args.custom({ }); /** - * Takes a package or release group name and searches the build project for it. - * Release groups are checked first, then independent packages by scoped name, then by unscoped name. + * Takes a release group name and searches the build project for it. */ export const findReleaseGroup = ( name: string, buildProject: IBuildProject, ): IReleaseGroup | undefined => { return buildProject.releaseGroups.get(name as ReleaseGroupName); - // ?? buildProject.packages.get(name as PkgName) }; /** From a0baf64b1db46ac50d4332d3b70007f1d77fd6b2 Mon Sep 17 00:00:00 2001 From: Michael Zhen <112977307+zhenmichael@users.noreply.github.com> Date: Mon, 16 Dec 2024 19:16:18 +0000 Subject: [PATCH 07/13] separate get tags and get versions from tags --- build-tools/packages/build-cli/README.md | 2 +- build-tools/packages/build-cli/docs/vnext.md | 2 +- build-tools/packages/build-cli/package.json | 3 ++ build-tools/packages/build-cli/src/args.ts | 15 ------ .../commands/vnext/check/latestVersions.ts | 26 +++++----- .../packages/build-cli/src/library/git.ts | 48 ++++++++----------- .../api-report/version-tools.api.md | 3 ++ .../packages/version-tools/src/index.ts | 2 +- .../packages/version-tools/src/versions.ts | 2 +- 9 files changed, 41 insertions(+), 62 deletions(-) diff --git a/build-tools/packages/build-cli/README.md b/build-tools/packages/build-cli/README.md index 9c81814184a0..3c97520d086e 100644 --- a/build-tools/packages/build-cli/README.md +++ b/build-tools/packages/build-cli/README.md @@ -51,7 +51,7 @@ USAGE * [`flub run`](docs/run.md) - Generate a report from input bundle stats collected through the collect bundleStats command. * [`flub transform`](docs/transform.md) - Transform commands are used to transform code, docs, etc. into alternative forms. * [`flub typetests`](docs/typetests.md) - Updates configuration for type tests in package.json files. If the previous version changes after running preparation, then npm install must be run before building. -* [`flub vnext`](docs/vnext.md) - Determines if an input version matches a latest minor release version. Intended to be used in the Fluid Framework CI pipeline only. +* [`flub vnext`](docs/vnext.md) - Vnext commands are new implementations of standard flub commands using new infrastructure. diff --git a/build-tools/packages/build-cli/docs/vnext.md b/build-tools/packages/build-cli/docs/vnext.md index 351ae0a636d8..d78e800f52f4 100644 --- a/build-tools/packages/build-cli/docs/vnext.md +++ b/build-tools/packages/build-cli/docs/vnext.md @@ -1,7 +1,7 @@ `flub vnext` ============ -Determines if an input version matches a latest minor release version. Intended to be used in the Fluid Framework CI pipeline only. +Vnext commands are new implementations of standard flub commands using new infrastructure. * [`flub vnext check latestVersions VERSION RELEASE_GROUP`](#flub-vnext-check-latestversions-version-release_group) diff --git a/build-tools/packages/build-cli/package.json b/build-tools/packages/build-cli/package.json index e219bcb0f0e6..5baff5171373 100644 --- a/build-tools/packages/build-cli/package.json +++ b/build-tools/packages/build-cli/package.json @@ -247,6 +247,9 @@ }, "report": { "description": "Report analysis about the codebase, like code coverage and bundle size measurements." + }, + "vnext": { + "description": "Vnext commands are new implementations of standard flub commands using new infrastructure." } } } diff --git a/build-tools/packages/build-cli/src/args.ts b/build-tools/packages/build-cli/src/args.ts index f9c380167aa8..baa9d373e37d 100644 --- a/build-tools/packages/build-cli/src/args.ts +++ b/build-tools/packages/build-cli/src/args.ts @@ -3,11 +3,6 @@ * Licensed under the MIT License. */ -import type { - IBuildProject, - IReleaseGroup, - ReleaseGroupName, -} from "@fluid-tools/build-infrastructure"; import { MonoRepo, Package } from "@fluidframework/build-tools"; import { Args } from "@oclif/core"; import { PackageName } from "@rushstack/node-core-library"; @@ -54,16 +49,6 @@ export const releaseGroupArg = Args.custom({ description: "The name of a release group.", }); -/** - * Takes a release group name and searches the build project for it. - */ -export const findReleaseGroup = ( - name: string, - buildProject: IBuildProject, -): IReleaseGroup | undefined => { - return buildProject.releaseGroups.get(name as ReleaseGroupName); -}; - /** * Creates a CLI argument for semver versions. It's a factory function so that commands can override the properties more * easily when using the argument. diff --git a/build-tools/packages/build-cli/src/commands/vnext/check/latestVersions.ts b/build-tools/packages/build-cli/src/commands/vnext/check/latestVersions.ts index dffcfb2f69da..6cc587fabfd4 100644 --- a/build-tools/packages/build-cli/src/commands/vnext/check/latestVersions.ts +++ b/build-tools/packages/build-cli/src/commands/vnext/check/latestVersions.ts @@ -3,14 +3,11 @@ * Licensed under the MIT License. */ +import type { ReleaseGroupName } from "@fluid-tools/build-infrastructure"; import { isInternalVersionScheme } from "@fluid-tools/version-tools"; import * as semver from "semver"; -import { findReleaseGroup, releaseGroupArg, semverArg } from "../../../args.js"; -import { - BaseCommandWithBuildProject, - getVersionsFromTags, - sortVersions, -} from "../../../library/index.js"; +import { releaseGroupArg, semverArg } from "../../../args.js"; +import { BaseCommandWithBuildProject, getVersionsFromTags } from "../../../library/index.js"; type MajorVersion = number; @@ -35,14 +32,15 @@ export default class LatestVersionsCommand extends BaseCommandWithBuildProject< public async run(): Promise { const { args } = this; const buildProject = this.getBuildProject(); - const releaseGroup = findReleaseGroup(args.release_group, buildProject); - - const versionInput = args.version; + const releaseGroup = buildProject.releaseGroups.get( + args.release_group as ReleaseGroupName, + ); if (releaseGroup === undefined) { this.error(`Package not found: ${args.release_group}`); } + const versionInput = args.version; const git = await buildProject.getGitRepository(); const versions = await getVersionsFromTags(releaseGroup, git); @@ -52,20 +50,20 @@ export default class LatestVersionsCommand extends BaseCommandWithBuildProject< // Filter out pre-release versions const stableVersions = versions.filter((v) => { - return !isInternalVersionScheme(v.version); + return !isInternalVersionScheme(v); }); // Sort the semver versions ordered from highest to lowest - const sortedByVersion = sortVersions(stableVersions, "version"); + const sortedByVersion = stableVersions.sort((a, b) => semver.rcompare(a, b)); const inputMajorVersion: MajorVersion = semver.major(versionInput.version); for (const v of sortedByVersion) { - const majorVersion: MajorVersion = semver.major(v.version); + const majorVersion: MajorVersion = semver.major(v); // Since sortedByVersion is sorted, the first encountered version is the highest one if (majorVersion === inputMajorVersion) { - if (v.version === versionInput.version) { + if (v === versionInput.version) { // Check if the input version is the latest version for the major version this.log( `Version ${versionInput.version} is the latest version for major version ${majorVersion}`, @@ -79,7 +77,7 @@ export default class LatestVersionsCommand extends BaseCommandWithBuildProject< // If versions do not match on first major version encounter, then the input version is not the latest this.log( - `##[warning]skipping deployment stage. input version ${versionInput.version} does not match the latest version ${v.version}`, + `##[warning]skipping deployment stage. input version ${versionInput.version} does not match the latest version ${v}`, ); this.log(`##vso[task.setvariable variable=shouldDeploy;isoutput=true]false`); this.log(`##vso[task.setvariable variable=majorVersion;isoutput=true]${majorVersion}`); diff --git a/build-tools/packages/build-cli/src/library/git.ts b/build-tools/packages/build-cli/src/library/git.ts index 89ba6a063f01..45c9d22215da 100644 --- a/build-tools/packages/build-cli/src/library/git.ts +++ b/build-tools/packages/build-cli/src/library/git.ts @@ -13,6 +13,7 @@ import { SimpleGit, SimpleGitOptions, simpleGit } from "simple-git"; import type { SetRequired } from "type-fest"; import type { IReleaseGroup } from "@fluid-tools/build-infrastructure"; +import { getVersionsFromStrings } from "@fluid-tools/version-tools"; import { parseISO } from "date-fns"; import { CommandLogger } from "../logging.js"; import { ReleaseGroup } from "../releaseGroups.js"; @@ -44,6 +45,19 @@ function getVersionFromTag(tag: string): string | undefined { return ver.version; } +/** + * Get all version tags for a given prefix. + * + * @param git - The git repository. + * @param prefix - prefix to search for. + * @returns List of version tags. + */ +async function getVersionTags(git: SimpleGit, prefix: string): Promise { + const raw_tags = git.tags(["--list", `${prefix}_v*`]); + const tags = await raw_tags; + return tags.all; +} + /** * Get all the versions for a release group. This function only considers the tags in the repo. * @@ -54,40 +68,16 @@ function getVersionFromTag(tag: string): string | undefined { export async function getVersionsFromTags( releaseGroup: IReleaseGroup, git: Readonly, -): Promise { - const prefix = PackageName.getUnscopedName(releaseGroup.name); - - const tags = await git.tags(["--list", `${prefix}_v*`]); - - const versions = new Map(); - - for (const tag of tags.all) { - const ver = getVersionFromTag(tag); - if (ver !== undefined && ver !== "" && ver !== null) { - // eslint-disable-next-line no-await-in-loop - const rawDate = await git.show([ - // Suppress the diff output - "-s", - // ISO 8601 format - "--format=%cI", - // the git ref - a tag in this case - tag, - ]); - const date = parseISO(rawDate.trim()); - versions.set(ver, date); - } - } +): Promise { + const tags = await getVersionTags(git, releaseGroup.name); - if (versions.size === 0) { + if (tags.length === 0) { return undefined; } - const toReturn: VersionDetails[] = []; - for (const [version, date] of versions) { - toReturn.push({ version, date }); - } + const versions = getVersionsFromStrings(releaseGroup.name, tags); - return toReturn; + return versions; } /** diff --git a/build-tools/packages/version-tools/api-report/version-tools.api.md b/build-tools/packages/version-tools/api-report/version-tools.api.md index 268cdd6f2014..2b08f192a6fc 100644 --- a/build-tools/packages/version-tools/api-report/version-tools.api.md +++ b/build-tools/packages/version-tools/api-report/version-tools.api.md @@ -54,6 +54,9 @@ export function getSimpleVersion(fileVersion: string, argBuildNum: string, argRe // @public export function getVersionRange(version: semver.SemVer | string, maxAutomaticBump: "minor" | "patch" | "~" | "^"): string; +// @public +export function getVersionsFromStrings(prefix: TagPrefix, tags: string[]): string[]; + // @public export type InterdependencyRange = WorkspaceRange | RangeOperator | RangeOperatorWithVersion | semver.SemVer; diff --git a/build-tools/packages/version-tools/src/index.ts b/build-tools/packages/version-tools/src/index.ts index 35fdc0fbb3fb..54a81e4aaa3f 100644 --- a/build-tools/packages/version-tools/src/index.ts +++ b/build-tools/packages/version-tools/src/index.ts @@ -41,5 +41,5 @@ export { VersionScheme, } from "./schemes"; export { bumpRange, detectBumpType, isPrereleaseVersion, getPreviousVersions } from "./semver"; -export { getIsLatest, getSimpleVersion } from "./versions"; +export { getIsLatest, getSimpleVersion, getVersionsFromStrings } from "./versions"; export { fromVirtualPatchScheme, toVirtualPatchScheme } from "./virtualPatchScheme"; diff --git a/build-tools/packages/version-tools/src/versions.ts b/build-tools/packages/version-tools/src/versions.ts index 58a8bf22f919..e95179ac2afd 100644 --- a/build-tools/packages/version-tools/src/versions.ts +++ b/build-tools/packages/version-tools/src/versions.ts @@ -182,7 +182,7 @@ function getVersions(prefix: TagPrefix): string[] { * @param tags - An array of tags as strings. * @returns An array of versions extracted from the provided tags. */ -function getVersionsFromStrings(prefix: TagPrefix, tags: string[]): string[] { +export function getVersionsFromStrings(prefix: TagPrefix, tags: string[]): string[] { const versions = tags .filter((v) => v.startsWith(`${prefix}_v`)) .map((tag) => tag.slice(`${prefix}_v`.length)); From 0cf9df86dea0468bb67bedaac7bc29d5fb46ff0f Mon Sep 17 00:00:00 2001 From: Michael Zhen <112977307+zhenmichael@users.noreply.github.com> Date: Mon, 16 Dec 2024 20:57:17 +0000 Subject: [PATCH 08/13] getVersionsFromStrings tests --- build-tools/packages/build-cli/README.md | 1 - .../packages/build-cli/docs/publish.md | 25 ++++++++++++ .../version-tools/src/test/versions.test.ts | 40 ++++++++++++++++++- 3 files changed, 64 insertions(+), 2 deletions(-) diff --git a/build-tools/packages/build-cli/README.md b/build-tools/packages/build-cli/README.md index 3c97520d086e..dd5511f3b9dd 100644 --- a/build-tools/packages/build-cli/README.md +++ b/build-tools/packages/build-cli/README.md @@ -48,7 +48,6 @@ USAGE * [`flub release`](docs/release.md) - Release commands are used to manage the Fluid release process. * [`flub rename-types`](docs/rename-types.md) - Renames type declaration files from .d.ts to .d.mts. * [`flub report`](docs/report.md) - Report analysis about the codebase, like code coverage and bundle size measurements. -* [`flub run`](docs/run.md) - Generate a report from input bundle stats collected through the collect bundleStats command. * [`flub transform`](docs/transform.md) - Transform commands are used to transform code, docs, etc. into alternative forms. * [`flub typetests`](docs/typetests.md) - Updates configuration for type tests in package.json files. If the previous version changes after running preparation, then npm install must be run before building. * [`flub vnext`](docs/vnext.md) - Vnext commands are new implementations of standard flub commands using new infrastructure. diff --git a/build-tools/packages/build-cli/docs/publish.md b/build-tools/packages/build-cli/docs/publish.md index 5b4ae41c14fb..6e421c55a668 100644 --- a/build-tools/packages/build-cli/docs/publish.md +++ b/build-tools/packages/build-cli/docs/publish.md @@ -3,8 +3,33 @@ Publish commands are used to publish packages to an npm registry. +* [`flub publish bundleStats`](#flub-publish-bundlestats) * [`flub publish tarballs`](#flub-publish-tarballs) +## `flub publish bundleStats` + +Generate a report from input bundle stats collected through the collect bundleStats command. + +``` +USAGE + $ flub publish bundleStats [-v | --quiet] [--dangerfile ] + +FLAGS + --dangerfile= Path to dangerfile + +LOGGING FLAGS + -v, --verbose Enable verbose logging. + --quiet Disable all logging. + +DESCRIPTION + Generate a report from input bundle stats collected through the collect bundleStats command. + +ALIASES + $ flub run bundleStats +``` + +_See code: [src/commands/publish/bundleStats.ts](https://github.com/microsoft/FluidFramework/blob/main/build-tools/packages/build-cli/src/commands/publish/bundleStats.ts)_ + ## `flub publish tarballs` Publishes tarballs to the package registry unless the version is already published. diff --git a/build-tools/packages/version-tools/src/test/versions.test.ts b/build-tools/packages/version-tools/src/test/versions.test.ts index 832e31e985be..81503755d2a1 100644 --- a/build-tools/packages/version-tools/src/test/versions.test.ts +++ b/build-tools/packages/version-tools/src/test/versions.test.ts @@ -7,7 +7,7 @@ import { assert, expect } from "chai"; import * as semver from "semver"; import { getVersionRange } from "../internalVersionScheme"; -import { getIsLatest, getSimpleVersion } from "../versions"; +import { getIsLatest, getSimpleVersion, getVersionsFromStrings } from "../versions"; // Deliberately not sorted here; highest version is 0.59.3000 const test_tags = [ @@ -159,3 +159,41 @@ describe("getIsLatest", () => { assert.isFalse(getIsLatest("client", "1.2.3", post1_tags, true)); }); }); + +describe("getVersionsFromStrings", () => { + it("should return sorted versions for given prefix", () => { + const expected = [ + "0.59.1000", + "0.59.1001", + "0.59.1001-62246", + "0.59.2000", + "0.59.2000-63294", + "0.59.2001", + "0.59.2002", + "0.59.3000", + "0.59.3000-66610", + "0.59.3000-67119", + ]; + const result = getVersionsFromStrings("client", test_tags); + expect(result).to.deep.equal(expected); + }); + + it("should filter out versions with different prefix", () => { + const tags = [ + "client_v0.59.1001", + "server_v0.59.2000", + "client_v0.59.3000", + "server_v0.59.1000", + "client_v0.59.2001", + ]; + const expected = ["0.59.1001", "0.59.2001", "0.59.3000"]; + const result = getVersionsFromStrings("client", tags); + expect(result).to.deep.equal(expected); + }); + + it("should return an empty array if no tags match the prefix", () => { + const tags = ["server_v0.59.1001", "server_v0.59.2000", "server_v0.59.3000"]; + const result = getVersionsFromStrings("client", tags); + expect(result).to.deep.equal([]); + }); +}); From 9fbef30c997a7de5f08d753038fd00000c6bf78e Mon Sep 17 00:00:00 2001 From: Michael Zhen <112977307+zhenmichael@users.noreply.github.com> Date: Tue, 17 Dec 2024 00:45:45 +0000 Subject: [PATCH 09/13] update filter tests --- build-tools/packages/build-cli/README.md | 1 + .../packages/build-cli/docs/publish.md | 25 ------------------- .../build-cli/src/test/filter.test.ts | 2 ++ 3 files changed, 3 insertions(+), 25 deletions(-) diff --git a/build-tools/packages/build-cli/README.md b/build-tools/packages/build-cli/README.md index dd5511f3b9dd..3c97520d086e 100644 --- a/build-tools/packages/build-cli/README.md +++ b/build-tools/packages/build-cli/README.md @@ -48,6 +48,7 @@ USAGE * [`flub release`](docs/release.md) - Release commands are used to manage the Fluid release process. * [`flub rename-types`](docs/rename-types.md) - Renames type declaration files from .d.ts to .d.mts. * [`flub report`](docs/report.md) - Report analysis about the codebase, like code coverage and bundle size measurements. +* [`flub run`](docs/run.md) - Generate a report from input bundle stats collected through the collect bundleStats command. * [`flub transform`](docs/transform.md) - Transform commands are used to transform code, docs, etc. into alternative forms. * [`flub typetests`](docs/typetests.md) - Updates configuration for type tests in package.json files. If the previous version changes after running preparation, then npm install must be run before building. * [`flub vnext`](docs/vnext.md) - Vnext commands are new implementations of standard flub commands using new infrastructure. diff --git a/build-tools/packages/build-cli/docs/publish.md b/build-tools/packages/build-cli/docs/publish.md index 6e421c55a668..5b4ae41c14fb 100644 --- a/build-tools/packages/build-cli/docs/publish.md +++ b/build-tools/packages/build-cli/docs/publish.md @@ -3,33 +3,8 @@ Publish commands are used to publish packages to an npm registry. -* [`flub publish bundleStats`](#flub-publish-bundlestats) * [`flub publish tarballs`](#flub-publish-tarballs) -## `flub publish bundleStats` - -Generate a report from input bundle stats collected through the collect bundleStats command. - -``` -USAGE - $ flub publish bundleStats [-v | --quiet] [--dangerfile ] - -FLAGS - --dangerfile= Path to dangerfile - -LOGGING FLAGS - -v, --verbose Enable verbose logging. - --quiet Disable all logging. - -DESCRIPTION - Generate a report from input bundle stats collected through the collect bundleStats command. - -ALIASES - $ flub run bundleStats -``` - -_See code: [src/commands/publish/bundleStats.ts](https://github.com/microsoft/FluidFramework/blob/main/build-tools/packages/build-cli/src/commands/publish/bundleStats.ts)_ - ## `flub publish tarballs` Publishes tarballs to the package registry unless the version is already published. diff --git a/build-tools/packages/build-cli/src/test/filter.test.ts b/build-tools/packages/build-cli/src/test/filter.test.ts index 63c22aa0e8ad..6997d3bf9535 100644 --- a/build-tools/packages/build-cli/src/test/filter.test.ts +++ b/build-tools/packages/build-cli/src/test/filter.test.ts @@ -86,6 +86,7 @@ describe("filterPackages", () => { const names = actual.map((p) => p.name); expect(names).to.be.equalTo([ "@fluid-tools/build-cli", + "@fluid-tools/build-infrastructure", "@fluidframework/build-tools", "@fluidframework/bundle-size-tools", "@fluid-tools/version-tools", @@ -311,6 +312,7 @@ describe("selectAndFilterPackages", () => { expect(names).to.be.equalTo([ "@fluid-tools/build-cli", + "@fluid-tools/build-infrastructure", "@fluidframework/build-tools", "@fluidframework/bundle-size-tools", "@fluid-tools/version-tools", From 11bba9b9aac5d699c155653129da5754feff4b11 Mon Sep 17 00:00:00 2001 From: Michael Zhen <112977307+zhenmichael@users.noreply.github.com> Date: Tue, 17 Dec 2024 16:39:33 +0000 Subject: [PATCH 10/13] fix version test --- .../version-tools/src/test/versions.test.ts | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/build-tools/packages/version-tools/src/test/versions.test.ts b/build-tools/packages/version-tools/src/test/versions.test.ts index 81503755d2a1..fad1feac8281 100644 --- a/build-tools/packages/version-tools/src/test/versions.test.ts +++ b/build-tools/packages/version-tools/src/test/versions.test.ts @@ -162,19 +162,31 @@ describe("getIsLatest", () => { describe("getVersionsFromStrings", () => { it("should return sorted versions for given prefix", () => { + const tags = [ + "client_v0.59.1001-62246", + "client_v0.59.2000-63294", + "client_v0.59.2002", + "client_v0.59.1000", + "client_v0.59.3000-67119", + "client_v0.59.3000", + "client_v0.59.2001", + "client_v0.59.3000-66610", + "client_v0.59.2000", + "client_v0.59.1001", + ]; const expected = [ "0.59.1000", - "0.59.1001", "0.59.1001-62246", - "0.59.2000", + "0.59.1001", "0.59.2000-63294", + "0.59.2000", "0.59.2001", "0.59.2002", - "0.59.3000", "0.59.3000-66610", "0.59.3000-67119", + "0.59.3000", ]; - const result = getVersionsFromStrings("client", test_tags); + const result = getVersionsFromStrings("client", tags); expect(result).to.deep.equal(expected); }); From 5a78811c92cbb854dddc091c1eea130179506e9f Mon Sep 17 00:00:00 2001 From: Michael Zhen <112977307+zhenmichael@users.noreply.github.com> Date: Mon, 23 Dec 2024 20:32:44 +0000 Subject: [PATCH 11/13] test data package --- build-tools/packages/build-cli/package.json | 1 + .../test-data/data/spaces/_package.json | 5 + .../test-data/data/tabs/_package.json | 5 + .../data/testRepo/.changeset/README.md | 11 + .../.changeset/bump-main-group-minor.md | 5 + .../data/testRepo/.changeset/config.json | 34 + .../data/testRepo/fluidBuild.config.cjs | 61 ++ .../test-data/data/testRepo/package.json | 20 + .../packages/group2/pkg-d/package.json | 16 + .../packages/group2/pkg-e/package.json | 14 + .../packages/group3/pkg-f/package.json | 17 + .../packages/group3/pkg-f/src/index.mjs | 1 + .../packages/group3/pkg-g/package.json | 13 + .../data/testRepo/packages/pkg-a/package.json | 17 + .../data/testRepo/packages/pkg-b/package.json | 16 + .../data/testRepo/packages/pkg-c/package.json | 17 + .../testRepo/packages/shared/package.json | 16 + .../test-data/data/testRepo/pnpm-lock.yaml | 763 ++++++++++++++++++ .../data/testRepo/pnpm-workspace.yaml | 2 + .../data/testRepo/second/package.json | 16 + .../second/packages/other-pkg-a/package.json | 16 + .../second/packages/other-pkg-b/package.json | 13 + .../data/testRepo/second/pnpm-lock.yaml | 21 + .../data/testRepo/second/pnpm-workspace.yaml | 2 + build-tools/packages/test-data/dirname.cts | 14 + build-tools/packages/test-data/index.ts | 20 + build-tools/packages/test-data/package.json | 19 + build-tools/pnpm-lock.yaml | 23 +- 28 files changed, 1171 insertions(+), 7 deletions(-) create mode 100644 build-tools/packages/test-data/data/spaces/_package.json create mode 100644 build-tools/packages/test-data/data/tabs/_package.json create mode 100644 build-tools/packages/test-data/data/testRepo/.changeset/README.md create mode 100644 build-tools/packages/test-data/data/testRepo/.changeset/bump-main-group-minor.md create mode 100644 build-tools/packages/test-data/data/testRepo/.changeset/config.json create mode 100644 build-tools/packages/test-data/data/testRepo/fluidBuild.config.cjs create mode 100644 build-tools/packages/test-data/data/testRepo/package.json create mode 100644 build-tools/packages/test-data/data/testRepo/packages/group2/pkg-d/package.json create mode 100644 build-tools/packages/test-data/data/testRepo/packages/group2/pkg-e/package.json create mode 100644 build-tools/packages/test-data/data/testRepo/packages/group3/pkg-f/package.json create mode 100644 build-tools/packages/test-data/data/testRepo/packages/group3/pkg-f/src/index.mjs create mode 100644 build-tools/packages/test-data/data/testRepo/packages/group3/pkg-g/package.json create mode 100644 build-tools/packages/test-data/data/testRepo/packages/pkg-a/package.json create mode 100644 build-tools/packages/test-data/data/testRepo/packages/pkg-b/package.json create mode 100644 build-tools/packages/test-data/data/testRepo/packages/pkg-c/package.json create mode 100644 build-tools/packages/test-data/data/testRepo/packages/shared/package.json create mode 100644 build-tools/packages/test-data/data/testRepo/pnpm-lock.yaml create mode 100644 build-tools/packages/test-data/data/testRepo/pnpm-workspace.yaml create mode 100644 build-tools/packages/test-data/data/testRepo/second/package.json create mode 100644 build-tools/packages/test-data/data/testRepo/second/packages/other-pkg-a/package.json create mode 100644 build-tools/packages/test-data/data/testRepo/second/packages/other-pkg-b/package.json create mode 100644 build-tools/packages/test-data/data/testRepo/second/pnpm-lock.yaml create mode 100644 build-tools/packages/test-data/data/testRepo/second/pnpm-workspace.yaml create mode 100644 build-tools/packages/test-data/dirname.cts create mode 100644 build-tools/packages/test-data/index.ts create mode 100644 build-tools/packages/test-data/package.json diff --git a/build-tools/packages/build-cli/package.json b/build-tools/packages/build-cli/package.json index 5baff5171373..b73224735a60 100644 --- a/build-tools/packages/build-cli/package.json +++ b/build-tools/packages/build-cli/package.json @@ -137,6 +137,7 @@ "sort-package-json": "1.57.0", "strip-ansi": "^6.0.1", "table": "^6.8.2", + "@fluid-tools/test-data": "workspace:~", "ts-morph": "^22.0.0", "type-fest": "^2.19.0", "unist-util-visit": "^5.0.0", diff --git a/build-tools/packages/test-data/data/spaces/_package.json b/build-tools/packages/test-data/data/spaces/_package.json new file mode 100644 index 000000000000..330848bba227 --- /dev/null +++ b/build-tools/packages/test-data/data/spaces/_package.json @@ -0,0 +1,5 @@ +{ + "name": "spaces-package", + "version": "1.0.0", + "private": true +} diff --git a/build-tools/packages/test-data/data/tabs/_package.json b/build-tools/packages/test-data/data/tabs/_package.json new file mode 100644 index 000000000000..3c275cecbfc4 --- /dev/null +++ b/build-tools/packages/test-data/data/tabs/_package.json @@ -0,0 +1,5 @@ +{ + "name": "tabs-package", + "version": "1.0.0", + "private": true +} diff --git a/build-tools/packages/test-data/data/testRepo/.changeset/README.md b/build-tools/packages/test-data/data/testRepo/.changeset/README.md new file mode 100644 index 000000000000..7de5f780575d --- /dev/null +++ b/build-tools/packages/test-data/data/testRepo/.changeset/README.md @@ -0,0 +1,11 @@ +# Changesets + +This folder contains changesets, which are markdown files that hold two key bits of information: + +1. a version type (following semver), and +2. change information to be added to a changelog. You can find the full documentation for it + [in the changesets section of our wiki](https://github.com/microsoft/FluidFramework/wiki/Changesets) or in [the official changesets documentation.](https://github.com/changesets/changesets) + +There is also a list of [frequently asked questions](https://github.com/microsoft/FluidFramework/wiki/Changesets-FAQ) in +the wiki. + diff --git a/build-tools/packages/test-data/data/testRepo/.changeset/bump-main-group-minor.md b/build-tools/packages/test-data/data/testRepo/.changeset/bump-main-group-minor.md new file mode 100644 index 000000000000..b71fbb4c343e --- /dev/null +++ b/build-tools/packages/test-data/data/testRepo/.changeset/bump-main-group-minor.md @@ -0,0 +1,5 @@ +--- +"pkg-a": minor +--- + +An example changeset. diff --git a/build-tools/packages/test-data/data/testRepo/.changeset/config.json b/build-tools/packages/test-data/data/testRepo/.changeset/config.json new file mode 100644 index 000000000000..9012ad8fd105 --- /dev/null +++ b/build-tools/packages/test-data/data/testRepo/.changeset/config.json @@ -0,0 +1,34 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@2.3.0/schema.json", + "access": "public", + "baseBranch": "main", + "changelog": [ + "@fluid-private/changelog-generator-wrapper", + { + "repoBaseUrl": "https://github.com/microsoft/FluidFramework", + "issueTemplate": " ([#$issue]($repoBaseUrl/pull/$issue))", + "commitTemplate": " [$abbrevHash]($repoBaseUrl/commit/$hash)" + } + ], + "commit": false, + "fixed": [ + [ + "pkg-a", + "pkg-b", + "@private/pkg-c", + "@shared/shared" + ], + [ + "@group2/pkg-d", + "@group2/pkg-e" + ], + [ + "@group3/pkg-f", + "@group3/pkg-g" + ] + ], + "ignore": [], + "linked": [], + "updateInternalDependencies": "minor", + "bumpVersionsWithWorkspaceProtocolOnly": true +} diff --git a/build-tools/packages/test-data/data/testRepo/fluidBuild.config.cjs b/build-tools/packages/test-data/data/testRepo/fluidBuild.config.cjs new file mode 100644 index 000000000000..924efddc73f4 --- /dev/null +++ b/build-tools/packages/test-data/data/testRepo/fluidBuild.config.cjs @@ -0,0 +1,61 @@ +/*! + * Copyright (c) Microsoft Corporation and contributors. All rights reserved. + * Licensed under the MIT License. + */ + +// Enable TypeScript type-checking for this file. +// See https://www.typescriptlang.org/docs/handbook/intro-to-js-ts.html#ts-check +// @ts-check + +/** + * @type {import("@fluid-tools/build-infrastructure").IBuildProjectLayout & import("@fluid-tools/build-cli").FlubConfig} + */ +const config = { + version: 1, + buildProject: { + workspaces: { + main: { + directory: ".", + releaseGroups: { + main: { + include: ["pkg-a", "pkg-b", "@shared", "@private"], + rootPackageName: "main-release-group-root", + }, + group2: { + include: ["@group2"], + }, + group3: { + include: ["@group3"], + }, + }, + }, + second: { + directory: "./second", + releaseGroups: { + "second-release-group": { + include: ["*"], + rootPackageName: "second-release-group-root", + }, + }, + }, + }, + }, + + // The configuration used by the `flub generate changeset-config` command. + changesetConfig: { + changelog: [ + "@fluid-private/changelog-generator-wrapper", + { + repoBaseUrl: "https://github.com/microsoft/FluidFramework", + issueTemplate: " ([#$issue]($repoBaseUrl/pull/$issue))", + commitTemplate: " [$abbrevHash]($repoBaseUrl/commit/$hash)", + }, + ], + commit: false, + access: "public", + baseBranch: "main", + updateInternalDependencies: "patch", + }, +}; + +module.exports = config; diff --git a/build-tools/packages/test-data/data/testRepo/package.json b/build-tools/packages/test-data/data/testRepo/package.json new file mode 100644 index 000000000000..6208179e8a51 --- /dev/null +++ b/build-tools/packages/test-data/data/testRepo/package.json @@ -0,0 +1,20 @@ +{ + "name": "main-release-group-root", + "version": "1.0.0", + "description": "Test package", + "homepage": "https://fluidframework.com", + "repository": { + "type": "git", + "url": "https://github.com/microsoft/FluidFramework.git", + "directory": "build-tools/packages/build-infrastructure/src/test/data/testRepo" + }, + "license": "MIT", + "author": "Microsoft and contributors", + "dependencies": { + "@fluid-private/changelog-generator-wrapper": "link:../../../../../../../packages/tools/changelog-generator-wrapper", + "@fluid-tools/build-infrastructure": "link:../../../../../build-infrastructure" + }, + "devDependencies": { + "@changesets/cli": "^2.27.9" + } +} diff --git a/build-tools/packages/test-data/data/testRepo/packages/group2/pkg-d/package.json b/build-tools/packages/test-data/data/testRepo/packages/group2/pkg-d/package.json new file mode 100644 index 000000000000..83999191f9cf --- /dev/null +++ b/build-tools/packages/test-data/data/testRepo/packages/group2/pkg-d/package.json @@ -0,0 +1,16 @@ +{ + "name": "@group2/pkg-d", + "version": "1.0.0", + "description": "Test package", + "homepage": "https://fluidframework.com", + "repository": { + "type": "git", + "url": "https://github.com/microsoft/FluidFramework.git", + "directory": "build-tools/packages/build-infrastructure/src/test/data/testRepo/packages/group2/pkg-d" + }, + "license": "MIT", + "author": "Microsoft and contributors", + "dependencies": { + "@group2/pkg-e": "workspace:~" + } +} diff --git a/build-tools/packages/test-data/data/testRepo/packages/group2/pkg-e/package.json b/build-tools/packages/test-data/data/testRepo/packages/group2/pkg-e/package.json new file mode 100644 index 000000000000..2142f92283b4 --- /dev/null +++ b/build-tools/packages/test-data/data/testRepo/packages/group2/pkg-e/package.json @@ -0,0 +1,14 @@ +{ + "name": "@group2/pkg-e", + "version": "1.0.0", + "description": "Test package", + "homepage": "https://fluidframework.com", + "repository": { + "type": "git", + "url": "https://github.com/microsoft/FluidFramework.git", + "directory": "build-tools/packages/build-infrastructure/src/test/data/testRepo/packages/group2/pkg-e" + }, + "license": "MIT", + "author": "Microsoft and contributors", + "dependencies": {} +} diff --git a/build-tools/packages/test-data/data/testRepo/packages/group3/pkg-f/package.json b/build-tools/packages/test-data/data/testRepo/packages/group3/pkg-f/package.json new file mode 100644 index 000000000000..2b2bffa838e6 --- /dev/null +++ b/build-tools/packages/test-data/data/testRepo/packages/group3/pkg-f/package.json @@ -0,0 +1,17 @@ +{ + "name": "@group3/pkg-f", + "version": "1.0.0", + "description": "Test package", + "homepage": "https://fluidframework.com", + "repository": { + "type": "git", + "url": "https://github.com/microsoft/FluidFramework.git", + "directory": "build-tools/packages/build-infrastructure/src/test/data/testRepo/packages/group3/pkg-f" + }, + "license": "MIT", + "author": "Microsoft and contributors", + "dependencies": { + "@group2/pkg-e": "workspace:~", + "@group3/pkg-g": "workspace:~" + } +} diff --git a/build-tools/packages/test-data/data/testRepo/packages/group3/pkg-f/src/index.mjs b/build-tools/packages/test-data/data/testRepo/packages/group3/pkg-f/src/index.mjs new file mode 100644 index 000000000000..bf55e2ddd240 --- /dev/null +++ b/build-tools/packages/test-data/data/testRepo/packages/group3/pkg-f/src/index.mjs @@ -0,0 +1 @@ +export const FOO = 1; diff --git a/build-tools/packages/test-data/data/testRepo/packages/group3/pkg-g/package.json b/build-tools/packages/test-data/data/testRepo/packages/group3/pkg-g/package.json new file mode 100644 index 000000000000..dbc99a71e290 --- /dev/null +++ b/build-tools/packages/test-data/data/testRepo/packages/group3/pkg-g/package.json @@ -0,0 +1,13 @@ +{ + "name": "@group3/pkg-g", + "version": "1.0.0", + "description": "Test package", + "homepage": "https://fluidframework.com", + "repository": { + "type": "git", + "url": "https://github.com/microsoft/FluidFramework.git", + "directory": "build-tools/packages/build-infrastructure/src/test/data/testRepo/packages/group3/pkg-g" + }, + "license": "MIT", + "author": "Microsoft and contributors" +} diff --git a/build-tools/packages/test-data/data/testRepo/packages/pkg-a/package.json b/build-tools/packages/test-data/data/testRepo/packages/pkg-a/package.json new file mode 100644 index 000000000000..7d6104adc4c0 --- /dev/null +++ b/build-tools/packages/test-data/data/testRepo/packages/pkg-a/package.json @@ -0,0 +1,17 @@ +{ + "name": "pkg-a", + "version": "1.0.0", + "description": "Test package", + "homepage": "https://fluidframework.com", + "repository": { + "type": "git", + "url": "https://github.com/microsoft/FluidFramework.git", + "directory": "build-tools/packages/build-infrastructure/src/test/data/testRepo/packages/pkg-a" + }, + "license": "MIT", + "author": "Microsoft and contributors", + "dependencies": { + "@shared/shared": "workspace:~", + "pkg-b": "workspace:~" + } +} diff --git a/build-tools/packages/test-data/data/testRepo/packages/pkg-b/package.json b/build-tools/packages/test-data/data/testRepo/packages/pkg-b/package.json new file mode 100644 index 000000000000..b4977d923789 --- /dev/null +++ b/build-tools/packages/test-data/data/testRepo/packages/pkg-b/package.json @@ -0,0 +1,16 @@ +{ + "name": "pkg-b", + "version": "1.0.0", + "description": "Test package", + "homepage": "https://fluidframework.com", + "repository": { + "type": "git", + "url": "https://github.com/microsoft/FluidFramework.git", + "directory": "build-tools/packages/build-infrastructure/src/test/data/testRepo/packages/pkg-b" + }, + "license": "MIT", + "author": "Microsoft and contributors", + "dependencies": { + "pkg-b": "workspace:~" + } +} diff --git a/build-tools/packages/test-data/data/testRepo/packages/pkg-c/package.json b/build-tools/packages/test-data/data/testRepo/packages/pkg-c/package.json new file mode 100644 index 000000000000..1904ea768980 --- /dev/null +++ b/build-tools/packages/test-data/data/testRepo/packages/pkg-c/package.json @@ -0,0 +1,17 @@ +{ + "name": "@private/pkg-c", + "version": "1.0.0", + "private": true, + "description": "Test package", + "homepage": "https://fluidframework.com", + "repository": { + "type": "git", + "url": "https://github.com/microsoft/FluidFramework.git", + "directory": "build-tools/packages/build-infrastructure/src/test/data/testRepo/packages/pkg-c" + }, + "license": "MIT", + "author": "Microsoft and contributors", + "dependencies": { + "pkg-b": "workspace:~" + } +} diff --git a/build-tools/packages/test-data/data/testRepo/packages/shared/package.json b/build-tools/packages/test-data/data/testRepo/packages/shared/package.json new file mode 100644 index 000000000000..f011813d0148 --- /dev/null +++ b/build-tools/packages/test-data/data/testRepo/packages/shared/package.json @@ -0,0 +1,16 @@ +{ + "name": "@shared/shared", + "version": "1.0.0", + "description": "Test package", + "homepage": "https://fluidframework.com", + "repository": { + "type": "git", + "url": "https://github.com/microsoft/FluidFramework.git", + "directory": "build-tools/packages/build-infrastructure/src/test/data/testRepo/packages/shared" + }, + "license": "MIT", + "author": "Microsoft and contributors", + "dependencies": { + "@group2/pkg-d": "1.0.0" + } +} diff --git a/build-tools/packages/test-data/data/testRepo/pnpm-lock.yaml b/build-tools/packages/test-data/data/testRepo/pnpm-lock.yaml new file mode 100644 index 000000000000..3cbd1990b2f9 --- /dev/null +++ b/build-tools/packages/test-data/data/testRepo/pnpm-lock.yaml @@ -0,0 +1,763 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@fluid-private/changelog-generator-wrapper': + specifier: link:../../../../../../../packages/tools/changelog-generator-wrapper + version: link:../../../../../../../packages/tools/changelog-generator-wrapper + '@fluid-tools/build-infrastructure': + specifier: link:../../../../../build-infrastructure + version: link:../../../.. + devDependencies: + '@changesets/cli': + specifier: ^2.27.9 + version: 2.27.9 + + packages/group2/pkg-d: + dependencies: + '@group2/pkg-e': + specifier: workspace:~ + version: link:../pkg-e + + packages/group2/pkg-e: {} + + packages/group3/pkg-f: + dependencies: + '@group2/pkg-e': + specifier: workspace:~ + version: link:../../group2/pkg-e + '@group3/pkg-g': + specifier: workspace:~ + version: link:../pkg-g + + packages/group3/pkg-g: {} + + packages/pkg-a: + dependencies: + '@shared/shared': + specifier: workspace:~ + version: link:../shared + pkg-b: + specifier: workspace:~ + version: link:../pkg-b + + packages/pkg-b: + dependencies: + pkg-b: + specifier: workspace:~ + version: 'link:' + + packages/pkg-c: + dependencies: + pkg-b: + specifier: workspace:~ + version: link:../pkg-b + + packages/shared: + dependencies: + '@group2/pkg-d': + specifier: 1.0.0 + version: link:../group2/pkg-d + +packages: + + /@babel/runtime@7.25.7: + resolution: {integrity: sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.14.1 + dev: true + + /@changesets/apply-release-plan@7.0.5: + resolution: {integrity: sha512-1cWCk+ZshEkSVEZrm2fSj1Gz8sYvxgUL4Q78+1ZZqeqfuevPTPk033/yUZ3df8BKMohkqqHfzj0HOOrG0KtXTw==} + dependencies: + '@changesets/config': 3.0.3 + '@changesets/get-version-range-type': 0.4.0 + '@changesets/git': 3.0.1 + '@changesets/should-skip-package': 0.1.1 + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + detect-indent: 6.1.0 + fs-extra: 7.0.1 + lodash.startcase: 4.4.0 + outdent: 0.5.0 + prettier: 2.8.8 + resolve-from: 5.0.0 + semver: 7.6.3 + dev: true + + /@changesets/assemble-release-plan@6.0.4: + resolution: {integrity: sha512-nqICnvmrwWj4w2x0fOhVj2QEGdlUuwVAwESrUo5HLzWMI1rE5SWfsr9ln+rDqWB6RQ2ZyaMZHUcU7/IRaUJS+Q==} + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.2 + '@changesets/should-skip-package': 0.1.1 + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + semver: 7.6.3 + dev: true + + /@changesets/changelog-git@0.2.0: + resolution: {integrity: sha512-bHOx97iFI4OClIT35Lok3sJAwM31VbUM++gnMBV16fdbtBhgYu4dxsphBF/0AZZsyAHMrnM0yFcj5gZM1py6uQ==} + dependencies: + '@changesets/types': 6.0.0 + dev: true + + /@changesets/cli@2.27.9: + resolution: {integrity: sha512-q42a/ZbDnxPpCb5Wkm6tMVIxgeI9C/bexntzTeCFBrQEdpisQqk8kCHllYZMDjYtEc1ZzumbMJAG8H0Z4rdvjg==} + hasBin: true + dependencies: + '@changesets/apply-release-plan': 7.0.5 + '@changesets/assemble-release-plan': 6.0.4 + '@changesets/changelog-git': 0.2.0 + '@changesets/config': 3.0.3 + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.2 + '@changesets/get-release-plan': 4.0.4 + '@changesets/git': 3.0.1 + '@changesets/logger': 0.1.1 + '@changesets/pre': 2.0.1 + '@changesets/read': 0.6.1 + '@changesets/should-skip-package': 0.1.1 + '@changesets/types': 6.0.0 + '@changesets/write': 0.3.2 + '@manypkg/get-packages': 1.1.3 + ansi-colors: 4.1.3 + ci-info: 3.9.0 + enquirer: 2.4.1 + external-editor: 3.1.0 + fs-extra: 7.0.1 + mri: 1.2.0 + p-limit: 2.3.0 + package-manager-detector: 0.2.1 + picocolors: 1.1.0 + resolve-from: 5.0.0 + semver: 7.6.3 + spawndamnit: 2.0.0 + term-size: 2.2.1 + dev: true + + /@changesets/config@3.0.3: + resolution: {integrity: sha512-vqgQZMyIcuIpw9nqFIpTSNyc/wgm/Lu1zKN5vECy74u95Qx/Wa9g27HdgO4NkVAaq+BGA8wUc/qvbvVNs93n6A==} + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.2 + '@changesets/logger': 0.1.1 + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + micromatch: 4.0.8 + dev: true + + /@changesets/errors@0.2.0: + resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==} + dependencies: + extendable-error: 0.1.7 + dev: true + + /@changesets/get-dependents-graph@2.1.2: + resolution: {integrity: sha512-sgcHRkiBY9i4zWYBwlVyAjEM9sAzs4wYVwJUdnbDLnVG3QwAaia1Mk5P8M7kraTOZN+vBET7n8KyB0YXCbFRLQ==} + dependencies: + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + picocolors: 1.1.0 + semver: 7.6.3 + dev: true + + /@changesets/get-release-plan@4.0.4: + resolution: {integrity: sha512-SicG/S67JmPTrdcc9Vpu0wSQt7IiuN0dc8iR5VScnnTVPfIaLvKmEGRvIaF0kcn8u5ZqLbormZNTO77bCEvyWw==} + dependencies: + '@changesets/assemble-release-plan': 6.0.4 + '@changesets/config': 3.0.3 + '@changesets/pre': 2.0.1 + '@changesets/read': 0.6.1 + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + dev: true + + /@changesets/get-version-range-type@0.4.0: + resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==} + dev: true + + /@changesets/git@3.0.1: + resolution: {integrity: sha512-pdgHcYBLCPcLd82aRcuO0kxCDbw/yISlOtkmwmE8Odo1L6hSiZrBOsRl84eYG7DRCab/iHnOkWqExqc4wxk2LQ==} + dependencies: + '@changesets/errors': 0.2.0 + '@manypkg/get-packages': 1.1.3 + is-subdir: 1.2.0 + micromatch: 4.0.8 + spawndamnit: 2.0.0 + dev: true + + /@changesets/logger@0.1.1: + resolution: {integrity: sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==} + dependencies: + picocolors: 1.1.0 + dev: true + + /@changesets/parse@0.4.0: + resolution: {integrity: sha512-TS/9KG2CdGXS27S+QxbZXgr8uPsP4yNJYb4BC2/NeFUj80Rni3TeD2qwWmabymxmrLo7JEsytXH1FbpKTbvivw==} + dependencies: + '@changesets/types': 6.0.0 + js-yaml: 3.14.1 + dev: true + + /@changesets/pre@2.0.1: + resolution: {integrity: sha512-vvBJ/If4jKM4tPz9JdY2kGOgWmCowUYOi5Ycv8dyLnEE8FgpYYUo1mgJZxcdtGGP3aG8rAQulGLyyXGSLkIMTQ==} + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + dev: true + + /@changesets/read@0.6.1: + resolution: {integrity: sha512-jYMbyXQk3nwP25nRzQQGa1nKLY0KfoOV7VLgwucI0bUO8t8ZLCr6LZmgjXsiKuRDc+5A6doKPr9w2d+FEJ55zQ==} + dependencies: + '@changesets/git': 3.0.1 + '@changesets/logger': 0.1.1 + '@changesets/parse': 0.4.0 + '@changesets/types': 6.0.0 + fs-extra: 7.0.1 + p-filter: 2.1.0 + picocolors: 1.1.0 + dev: true + + /@changesets/should-skip-package@0.1.1: + resolution: {integrity: sha512-H9LjLbF6mMHLtJIc/eHR9Na+MifJ3VxtgP/Y+XLn4BF7tDTEN1HNYtH6QMcjP1uxp9sjaFYmW8xqloaCi/ckTg==} + dependencies: + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + dev: true + + /@changesets/types@4.1.0: + resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} + dev: true + + /@changesets/types@6.0.0: + resolution: {integrity: sha512-b1UkfNulgKoWfqyHtzKS5fOZYSJO+77adgL7DLRDr+/7jhChN+QcHnbjiQVOz/U+Ts3PGNySq7diAItzDgugfQ==} + dev: true + + /@changesets/write@0.3.2: + resolution: {integrity: sha512-kDxDrPNpUgsjDbWBvUo27PzKX4gqeKOlhibaOXDJA6kuBisGqNHv/HwGJrAu8U/dSf8ZEFIeHIPtvSlZI1kULw==} + dependencies: + '@changesets/types': 6.0.0 + fs-extra: 7.0.1 + human-id: 1.0.2 + prettier: 2.8.8 + dev: true + + /@manypkg/find-root@1.1.0: + resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} + dependencies: + '@babel/runtime': 7.25.7 + '@types/node': 12.20.55 + find-up: 4.1.0 + fs-extra: 8.1.0 + dev: true + + /@manypkg/get-packages@1.1.3: + resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} + dependencies: + '@babel/runtime': 7.25.7 + '@changesets/types': 4.1.0 + '@manypkg/find-root': 1.1.0 + fs-extra: 8.1.0 + globby: 11.1.0 + read-yaml-file: 1.1.0 + dev: true + + /@nodelib/fs.scandir@2.1.5: + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + dev: true + + /@nodelib/fs.stat@2.0.5: + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + dev: true + + /@nodelib/fs.walk@1.2.8: + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.17.1 + dev: true + + /@types/node@12.20.55: + resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + dev: true + + /ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} + dev: true + + /ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + dev: true + + /argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + dependencies: + sprintf-js: 1.0.3 + dev: true + + /array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + dev: true + + /better-path-resolve@1.0.0: + resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} + engines: {node: '>=4'} + dependencies: + is-windows: 1.0.2 + dev: true + + /braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.1.1 + dev: true + + /chardet@0.7.0: + resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + dev: true + + /ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} + engines: {node: '>=8'} + dev: true + + /cross-spawn@5.1.0: + resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==} + dependencies: + lru-cache: 4.1.5 + shebang-command: 1.2.0 + which: 1.3.1 + dev: true + + /detect-indent@6.1.0: + resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} + engines: {node: '>=8'} + dev: true + + /dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + dependencies: + path-type: 4.0.0 + dev: true + + /enquirer@2.4.1: + resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} + engines: {node: '>=8.6'} + dependencies: + ansi-colors: 4.1.3 + strip-ansi: 6.0.1 + dev: true + + /esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /extendable-error@0.1.7: + resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} + dev: true + + /external-editor@3.1.0: + resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} + engines: {node: '>=4'} + dependencies: + chardet: 0.7.0 + iconv-lite: 0.4.24 + tmp: 0.0.33 + dev: true + + /fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + engines: {node: '>=8.6.0'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + dev: true + + /fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + dependencies: + reusify: 1.0.4 + dev: true + + /fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 + dev: true + + /find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + dev: true + + /fs-extra@7.0.1: + resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} + engines: {node: '>=6 <7 || >=8'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + dev: true + + /fs-extra@8.1.0: + resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} + engines: {node: '>=6 <7 || >=8'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + dev: true + + /glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + dependencies: + is-glob: 4.0.3 + dev: true + + /globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.2 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 + dev: true + + /graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + dev: true + + /human-id@1.0.2: + resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==} + dev: true + + /iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + dependencies: + safer-buffer: 2.1.2 + dev: true + + /ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + dev: true + + /is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + dev: true + + /is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + dev: true + + /is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + dev: true + + /is-subdir@1.2.0: + resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} + engines: {node: '>=4'} + dependencies: + better-path-resolve: 1.0.0 + dev: true + + /is-windows@1.0.2: + resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} + engines: {node: '>=0.10.0'} + dev: true + + /isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + dev: true + + /js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + dev: true + + /jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + optionalDependencies: + graceful-fs: 4.2.11 + dev: true + + /locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + dependencies: + p-locate: 4.1.0 + dev: true + + /lodash.startcase@4.4.0: + resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} + dev: true + + /lru-cache@4.1.5: + resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==} + dependencies: + pseudomap: 1.0.2 + yallist: 2.1.2 + dev: true + + /merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + dev: true + + /micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + dev: true + + /mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + dev: true + + /os-tmpdir@1.0.2: + resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} + engines: {node: '>=0.10.0'} + dev: true + + /outdent@0.5.0: + resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} + dev: true + + /p-filter@2.1.0: + resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} + engines: {node: '>=8'} + dependencies: + p-map: 2.1.0 + dev: true + + /p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + dependencies: + p-try: 2.2.0 + dev: true + + /p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + dependencies: + p-limit: 2.3.0 + dev: true + + /p-map@2.1.0: + resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} + engines: {node: '>=6'} + dev: true + + /p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + dev: true + + /package-manager-detector@0.2.1: + resolution: {integrity: sha512-/hVW2fZvAdEas+wyKh0SnlZ2mx0NIa1+j11YaQkogEJkcMErbwchHCuo8z7lEtajZJQZ6rgZNVTWMVVd71Bjng==} + dev: true + + /path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + dev: true + + /path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + dev: true + + /picocolors@1.1.0: + resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==} + dev: true + + /picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + dev: true + + /pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} + dev: true + + /prettier@2.8.8: + resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} + engines: {node: '>=10.13.0'} + hasBin: true + dev: true + + /pseudomap@1.0.2: + resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} + dev: true + + /queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + dev: true + + /read-yaml-file@1.1.0: + resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} + engines: {node: '>=6'} + dependencies: + graceful-fs: 4.2.11 + js-yaml: 3.14.1 + pify: 4.0.1 + strip-bom: 3.0.0 + dev: true + + /regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + dev: true + + /resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + dev: true + + /reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + dev: true + + /run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + dependencies: + queue-microtask: 1.2.3 + dev: true + + /safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + dev: true + + /semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + engines: {node: '>=10'} + hasBin: true + dev: true + + /shebang-command@1.2.0: + resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} + engines: {node: '>=0.10.0'} + dependencies: + shebang-regex: 1.0.0 + dev: true + + /shebang-regex@1.0.0: + resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} + engines: {node: '>=0.10.0'} + dev: true + + /signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + dev: true + + /slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + dev: true + + /spawndamnit@2.0.0: + resolution: {integrity: sha512-j4JKEcncSjFlqIwU5L/rp2N5SIPsdxaRsIv678+TZxZ0SRDJTm8JrxJMjE/XuiEZNEir3S8l0Fa3Ke339WI4qA==} + dependencies: + cross-spawn: 5.1.0 + signal-exit: 3.0.7 + dev: true + + /sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + dev: true + + /strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.1 + dev: true + + /strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + dev: true + + /term-size@2.2.1: + resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} + engines: {node: '>=8'} + dev: true + + /tmp@0.0.33: + resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} + engines: {node: '>=0.6.0'} + dependencies: + os-tmpdir: 1.0.2 + dev: true + + /to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + dependencies: + is-number: 7.0.0 + dev: true + + /universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + dev: true + + /which@1.3.1: + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true + dependencies: + isexe: 2.0.0 + dev: true + + /yallist@2.1.2: + resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==} + dev: true diff --git a/build-tools/packages/test-data/data/testRepo/pnpm-workspace.yaml b/build-tools/packages/test-data/data/testRepo/pnpm-workspace.yaml new file mode 100644 index 000000000000..9c9be4ba8d5e --- /dev/null +++ b/build-tools/packages/test-data/data/testRepo/pnpm-workspace.yaml @@ -0,0 +1,2 @@ +packages: + - "packages/**" diff --git a/build-tools/packages/test-data/data/testRepo/second/package.json b/build-tools/packages/test-data/data/testRepo/second/package.json new file mode 100644 index 000000000000..bc836afc9b8f --- /dev/null +++ b/build-tools/packages/test-data/data/testRepo/second/package.json @@ -0,0 +1,16 @@ +{ + "name": "second-release-group-root", + "version": "2.0.0", + "description": "Test package", + "homepage": "https://fluidframework.com", + "repository": { + "type": "git", + "url": "https://github.com/microsoft/FluidFramework.git", + "directory": "build-tools/packages/build-infrastructure/src/test/data/testRepo/second" + }, + "license": "MIT", + "author": "Microsoft and contributors", + "dependencies": { + "@fluid-tools/build-infrastructure": "link:../../../../../../build-infrastructure" + } +} diff --git a/build-tools/packages/test-data/data/testRepo/second/packages/other-pkg-a/package.json b/build-tools/packages/test-data/data/testRepo/second/packages/other-pkg-a/package.json new file mode 100644 index 000000000000..098dfddf8bb2 --- /dev/null +++ b/build-tools/packages/test-data/data/testRepo/second/packages/other-pkg-a/package.json @@ -0,0 +1,16 @@ +{ + "name": "other-pkg-a", + "version": "2.0.0", + "description": "Test package", + "homepage": "https://fluidframework.com", + "repository": { + "type": "git", + "url": "https://github.com/microsoft/FluidFramework.git", + "directory": "build-tools/packages/build-infrastructure/src/test/data/testRepo/second/packages/other-pkg-a" + }, + "license": "MIT", + "author": "Microsoft and contributors", + "dependencies": { + "other-pkg-b": "workspace:~" + } +} diff --git a/build-tools/packages/test-data/data/testRepo/second/packages/other-pkg-b/package.json b/build-tools/packages/test-data/data/testRepo/second/packages/other-pkg-b/package.json new file mode 100644 index 000000000000..34d919d483b3 --- /dev/null +++ b/build-tools/packages/test-data/data/testRepo/second/packages/other-pkg-b/package.json @@ -0,0 +1,13 @@ +{ + "name": "other-pkg-b", + "version": "2.0.0", + "description": "Test package", + "homepage": "https://fluidframework.com", + "repository": { + "type": "git", + "url": "https://github.com/microsoft/FluidFramework.git", + "directory": "build-tools/packages/build-infrastructure/src/test/data/testRepo/second/packages/other-pkg-b" + }, + "license": "MIT", + "author": "Microsoft and contributors" +} diff --git a/build-tools/packages/test-data/data/testRepo/second/pnpm-lock.yaml b/build-tools/packages/test-data/data/testRepo/second/pnpm-lock.yaml new file mode 100644 index 000000000000..ba83dc5e001d --- /dev/null +++ b/build-tools/packages/test-data/data/testRepo/second/pnpm-lock.yaml @@ -0,0 +1,21 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@fluid-tools/build-infrastructure': + specifier: link:../../../../../../build-infrastructure + version: link:../../../../.. + + packages/other-pkg-a: + dependencies: + other-pkg-b: + specifier: workspace:~ + version: link:../other-pkg-b + + packages/other-pkg-b: {} diff --git a/build-tools/packages/test-data/data/testRepo/second/pnpm-workspace.yaml b/build-tools/packages/test-data/data/testRepo/second/pnpm-workspace.yaml new file mode 100644 index 000000000000..dee51e928d8a --- /dev/null +++ b/build-tools/packages/test-data/data/testRepo/second/pnpm-workspace.yaml @@ -0,0 +1,2 @@ +packages: + - "packages/*" diff --git a/build-tools/packages/test-data/dirname.cts b/build-tools/packages/test-data/dirname.cts new file mode 100644 index 000000000000..e9ce6931d4db --- /dev/null +++ b/build-tools/packages/test-data/dirname.cts @@ -0,0 +1,14 @@ +/*! + * Copyright (c) Microsoft Corporation and contributors. All rights reserved. + * Licensed under the MIT License. + */ + +// Problem: +// - `__dirname` is not defined in ESM +// - `import.meta.url` is not defined in CJS +// Solution: +// - Export '__dirname' from a .cjs file in the same directory. +// +// Note that *.cjs files are always CommonJS, but can be imported from ESM. +// eslint-disable-next-line unicorn/prefer-module -- this is used for ESM/CJS interop +export const _dirname = __dirname; diff --git a/build-tools/packages/test-data/index.ts b/build-tools/packages/test-data/index.ts new file mode 100644 index 000000000000..c178af3d82bd --- /dev/null +++ b/build-tools/packages/test-data/index.ts @@ -0,0 +1,20 @@ +/*! + * Copyright (c) Microsoft Corporation and contributors. All rights reserved. + * Licensed under the MIT License. + */ + +import path from "node:path"; + +import { _dirname } from "./dirname.cjs"; + +export const packageRootPath = path.resolve(_dirname, "../.."); + +/** + * Absolute path to the test data. It's rooted two directories up because the tests get executed from lib/. + */ +export const testDataPath = path.resolve(_dirname, packageRootPath, "src/test/data"); + +/** + * Absolute path to the test repo. + */ +export const testRepoRoot = path.join(testDataPath, "testRepo"); diff --git a/build-tools/packages/test-data/package.json b/build-tools/packages/test-data/package.json new file mode 100644 index 000000000000..6e37c3d552ba --- /dev/null +++ b/build-tools/packages/test-data/package.json @@ -0,0 +1,19 @@ +{ + "name": "@fluid-tools/test-data", + "version": "1.0.0", + "description": "Fluid build tools test data", + "homepage": "https://fluidframework.com", + "repository": { + "type": "git", + "url": "https://github.com/microsoft/FluidFramework.git", + "directory": "build-tools/packages/test-data" + }, + "license": "MIT", + "author": "Microsoft and contributors", + "types": "index.d.ts", + "private": true, + "main": "index.js", + "devDependencies": { + "@types/node": "^22.10.2" + } +} diff --git a/build-tools/pnpm-lock.yaml b/build-tools/pnpm-lock.yaml index 9c3d340e889b..45637a3b7443 100644 --- a/build-tools/pnpm-lock.yaml +++ b/build-tools/pnpm-lock.yaml @@ -94,6 +94,9 @@ importers: '@fluid-tools/build-infrastructure': specifier: workspace:~ version: link:../build-infrastructure + '@fluid-tools/test-data': + specifier: workspace:~ + version: link:../test-data '@fluid-tools/version-tools': specifier: workspace:~ version: link:../version-tools @@ -717,6 +720,12 @@ importers: specifier: ^4.4.1 version: 4.4.1 + packages/test-data: + devDependencies: + '@types/node': + specifier: ^22.10.2 + version: 22.10.2 + packages/version-tools: dependencies: '@oclif/core': @@ -1828,7 +1837,7 @@ packages: '@inquirer/figures': 1.0.7 '@inquirer/type': 2.0.0 '@types/mute-stream': 0.0.4 - '@types/node': 22.8.0 + '@types/node': 22.10.2 '@types/wrap-ansi': 3.0.0 ansi-escapes: 4.3.2 cli-width: 4.1.0 @@ -3133,7 +3142,7 @@ packages: /@types/mute-stream@0.0.4: resolution: {integrity: sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==} dependencies: - '@types/node': 18.19.60 + '@types/node': 22.10.2 /@types/node@18.19.60: resolution: {integrity: sha512-cYRj7igVqgxhlHFdBHHpU2SNw3+dN2x0VTZJtLYk6y/ieuGN4XiBgtDjYVktM/yk2y/8pKMileNc6IoEzEJnUw==} @@ -3144,10 +3153,10 @@ packages: resolution: {integrity: sha512-4tT2UrL5LBqDwoed9wZ6N3umC4Yhz3W3FloMmiiG4JwmUJWpie0c7lcnUNd4gtMKuDEO4wRVS8B6Xa0uMRsMKg==} dev: true - /@types/node@22.8.0: - resolution: {integrity: sha512-84rafSBHC/z1i1E3p0cJwKA+CfYDNSXX9WSZBRopjIzLET8oNt6ht2tei4C7izwDeEiLLfdeSVBv1egOH916hg==} + /@types/node@22.10.2: + resolution: {integrity: sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==} dependencies: - undici-types: 6.19.8 + undici-types: 6.20.0 /@types/normalize-package-data@2.4.1: resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} @@ -12249,8 +12258,8 @@ packages: /undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - /undici-types@6.19.8: - resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + /undici-types@6.20.0: + resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} /unicorn-magic@0.1.0: resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} From 2e52c4a9353470fadd6a7fbb64c11525b3ad6983 Mon Sep 17 00:00:00 2001 From: Michael Zhen <112977307+zhenmichael@users.noreply.github.com> Date: Mon, 23 Dec 2024 20:43:26 +0000 Subject: [PATCH 12/13] update types/node version in test data package --- build-tools/packages/test-data/package.json | 2 +- build-tools/pnpm-lock.yaml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build-tools/packages/test-data/package.json b/build-tools/packages/test-data/package.json index 6e37c3d552ba..de1af5c5c278 100644 --- a/build-tools/packages/test-data/package.json +++ b/build-tools/packages/test-data/package.json @@ -14,6 +14,6 @@ "private": true, "main": "index.js", "devDependencies": { - "@types/node": "^22.10.2" + "@types/node": "^18.19.59" } } diff --git a/build-tools/pnpm-lock.yaml b/build-tools/pnpm-lock.yaml index 45637a3b7443..afd7576212e9 100644 --- a/build-tools/pnpm-lock.yaml +++ b/build-tools/pnpm-lock.yaml @@ -723,8 +723,8 @@ importers: packages/test-data: devDependencies: '@types/node': - specifier: ^22.10.2 - version: 22.10.2 + specifier: ^18.19.59 + version: 18.19.60 packages/version-tools: dependencies: @@ -3142,7 +3142,7 @@ packages: /@types/mute-stream@0.0.4: resolution: {integrity: sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==} dependencies: - '@types/node': 22.10.2 + '@types/node': 18.19.60 /@types/node@18.19.60: resolution: {integrity: sha512-cYRj7igVqgxhlHFdBHHpU2SNw3+dN2x0VTZJtLYk6y/ieuGN4XiBgtDjYVktM/yk2y/8pKMileNc6IoEzEJnUw==} From bc8e06ca796c62a8e89d95b7fc56714a1dbc1da2 Mon Sep 17 00:00:00 2001 From: Michael Zhen <112977307+zhenmichael@users.noreply.github.com> Date: Mon, 23 Dec 2024 20:48:07 +0000 Subject: [PATCH 13/13] add types field to build-infra package json --- build-tools/packages/build-infrastructure/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/build-tools/packages/build-infrastructure/package.json b/build-tools/packages/build-infrastructure/package.json index 82f4d5b125a1..ef0752968d97 100644 --- a/build-tools/packages/build-infrastructure/package.json +++ b/build-tools/packages/build-infrastructure/package.json @@ -24,6 +24,7 @@ } }, "main": "lib/index.js", + "types": "lib/index.d.ts", "bin": { "buildProject": "./bin/run.mjs" },