diff --git a/build-tools/packages/build-infrastructure/api-report/build-infrastructure.api.md b/build-tools/packages/build-infrastructure/api-report/build-infrastructure.api.md index 0760471dde61..40b8c59544e3 100644 --- a/build-tools/packages/build-infrastructure/api-report/build-infrastructure.api.md +++ b/build-tools/packages/build-infrastructure/api-report/build-infrastructure.api.md @@ -6,6 +6,7 @@ import type { Opaque } from 'type-fest'; import type { PackageJson as PackageJson_2 } from 'type-fest'; +import * as semver from 'semver'; import type { SetRequired } from 'type-fest'; import { SimpleGit } from 'simple-git'; @@ -234,6 +235,9 @@ export interface Reloadable { reload(): void; } +// @public +export function setVersion(packages: IPackage[], version: semver.SemVer): Promise; + // @public export interface WorkspaceDefinition { directory: string; diff --git a/build-tools/packages/build-infrastructure/src/index.ts b/build-tools/packages/build-infrastructure/src/index.ts index a870d8379496..d76ae28fee41 100644 --- a/build-tools/packages/build-infrastructure/src/index.ts +++ b/build-tools/packages/build-infrastructure/src/index.ts @@ -50,30 +50,4 @@ export type { IPackageManager, } from "./types.js"; export { isIPackage, isIReleaseGroup } from "./types.js"; - -// export { -// filterPackages, -// type FilterablePackage, -// selectAndFilterPackages, -// type GlobString, -// AllPackagesSelectionCriteria, -// EmptySelectionCriteria, -// type PackageSelectionCriteria, -// type PackageFilterOptions, -// } from "./filter.js"; -// export { -// FluidRepo as FluidRepoBase, -// getAllDependenciesInRepo, -// loadFluidRepo, -// } from "./fluidRepo.js"; -// export { -// getFiles, -// findGitRootSync, -// getMergeBaseRemote, -// getRemote, -// getChangedSinceRef, -// } from "./git.js"; -// export { PackageBase } from "./package.js"; -// export { updatePackageJsonFile, updatePackageJsonFileAsync } from "./packageJsonUtils.js"; -// export { createPackageManager } from "./packageManagers.js"; -// export { setVersion } from "./versions.js"; +export { setVersion } from "./versions.js"; diff --git a/build-tools/packages/build-infrastructure/src/test/versions.test.ts b/build-tools/packages/build-infrastructure/src/test/versions.test.ts new file mode 100644 index 000000000000..666eb9f22f03 --- /dev/null +++ b/build-tools/packages/build-infrastructure/src/test/versions.test.ts @@ -0,0 +1,72 @@ +/*! + * Copyright (c) Microsoft Corporation and contributors. All rights reserved. + * Licensed under the MIT License. + */ + +import { strict as assert } from "node:assert"; +import path from "node:path"; + +import { expect } from "chai"; +import { afterEach, describe, it } from "mocha"; +import * as semver from "semver"; +import { simpleGit } from "simple-git"; + +import { loadFluidRepo } from "../fluidRepo.js"; +import type { ReleaseGroupName, WorkspaceName } from "../types.js"; +import { setVersion } from "../versions.js"; + +import { testDataPath, testRepoRoot } from "./init.js"; + +const repo = loadFluidRepo(path.join(testDataPath, "./testRepo")); +const main = repo.releaseGroups.get("main" as ReleaseGroupName); +assert(main !== undefined); + +const group2 = repo.releaseGroups.get("group2" as ReleaseGroupName); +assert(group2 !== undefined); + +const group3 = repo.releaseGroups.get("group3" as ReleaseGroupName); +assert(group3 !== undefined); + +const secondWorkspace = repo.workspaces.get("second" as WorkspaceName); +assert(secondWorkspace !== undefined); + +/** + * A git client rooted in the test repo. Used for resetting tests. + */ +const git = simpleGit(testRepoRoot); + +describe("setVersion", () => { + afterEach(async () => { + await git.checkout(["HEAD", "--", testRepoRoot]); + repo.reload(); + }); + + it("release group", async () => { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + await setVersion(main.packages, semver.parse("1.2.1")!); + repo.reload(); + + const allCorrect = main.packages.every((pkg) => pkg.version === "1.2.1"); + expect(main.version).to.equal("1.2.1"); + expect(allCorrect).to.be.true; + }); + + it("workspace", async () => { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + await setVersion(secondWorkspace.packages, semver.parse("2.2.1")!); + repo.reload(); + + const allCorrect = secondWorkspace.packages.every((pkg) => pkg.version === "2.2.1"); + expect(allCorrect).to.be.true; + }); + + it("repo", async () => { + const packages = [...repo.packages.values()]; + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + await setVersion(packages, semver.parse("1.2.1")!); + repo.reload(); + + const allCorrect = packages.every((pkg) => pkg.version === "1.2.1"); + expect(allCorrect).to.be.true; + }); +}); diff --git a/build-tools/packages/build-infrastructure/src/versions.ts b/build-tools/packages/build-infrastructure/src/versions.ts new file mode 100644 index 000000000000..b4519ca6da7c --- /dev/null +++ b/build-tools/packages/build-infrastructure/src/versions.ts @@ -0,0 +1,30 @@ +/*! + * Copyright (c) Microsoft Corporation and contributors. All rights reserved. + * Licensed under the MIT License. + */ + +import * as semver from "semver"; + +import { updatePackageJsonFile } from "./packageJsonUtils.js"; +import type { IPackage, PackageJson } from "./types.js"; + +/** + * Sets the version of a group of packages. + * + * Note that any loaded objects such as an IFluidRepo instance may need to be reloaded after calling this function. + * + * @param fluidRepo - The {@link IFluidRepo}. + * @param packages - An array of objects whose version should be updated. + * @param version - The version to set. + */ +export async function setVersion( + packages: IPackage[], + version: semver.SemVer, +): Promise { + const translatedVersion = version; + for (const pkg of packages) { + updatePackageJsonFile(pkg.directory, (json) => { + json.version = translatedVersion.version; + }); + } +}