Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@microsoft/rush",
"comment": "Ensure that `rush version` and `rush publish` preserve all fields in `version-policies-json`.",
"type": "none"
}
],
"packageName": "@microsoft/rush"
}
62 changes: 44 additions & 18 deletions common/reviews/api/rush-lib.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,12 @@ export interface IGetChangedProjectsOptions {
export interface IGlobalCommand extends IRushCommand {
}

// @public
export interface IIndividualVersionJson extends IVersionPolicyJson {
// (undocumented)
lockedMajor?: number;
}

// @beta
export interface IInputsSnapshot {
getOperationOwnStateHash(project: IRushConfigurationProjectForSnapshot, operationName?: string): string;
Expand All @@ -556,6 +562,16 @@ export interface ILaunchOptions {
terminalProvider?: ITerminalProvider;
}

// @public
export interface ILockStepVersionJson extends IVersionPolicyJson {
// (undocumented)
mainProject?: string;
// (undocumented)
nextBump?: string;
// (undocumented)
version: string;
}

// @alpha
export interface ILogFilePaths {
error: string;
Expand All @@ -575,15 +591,13 @@ export interface ILogger {

// @public
export class IndividualVersionPolicy extends VersionPolicy {
// Warning: (ae-forgotten-export) The symbol "IIndividualVersionJson" needs to be exported by the entry point index.d.ts
//
// @internal
constructor(versionPolicyJson: IIndividualVersionJson);
bump(bumpType?: BumpType, identifier?: string): void;
ensure(project: IPackageJson, force?: boolean): IPackageJson | undefined;
// @internal
get _json(): IIndividualVersionJson;
readonly lockedMajor: number | undefined;
// @internal (undocumented)
readonly _json: IIndividualVersionJson;
get lockedMajor(): number | undefined;
validate(versionString: string, packageName: string): void;
}

Expand Down Expand Up @@ -922,23 +936,37 @@ export interface ITryFindRushJsonLocationOptions {
startingFolder?: string;
}

// @public
export interface IVersionPolicyJson {
// (undocumented)
definitionName: string;
// Warning: (ae-forgotten-export) The symbol "IVersionPolicyDependencyJson" needs to be exported by the entry point index.d.ts
//
// (undocumented)
dependencies?: IVersionPolicyDependencyJson;
// (undocumented)
exemptFromRushChange?: boolean;
// (undocumented)
includeEmailInChangeFile?: boolean;
// (undocumented)
policyName: string;
}

// @internal
export interface _IYarnOptionsJson extends IPackageManagerOptionsJsonBase {
ignoreEngines?: boolean;
}

// @public
export class LockStepVersionPolicy extends VersionPolicy {
// Warning: (ae-forgotten-export) The symbol "ILockStepVersionJson" needs to be exported by the entry point index.d.ts
//
// @internal
constructor(versionPolicyJson: ILockStepVersionJson);
bump(bumpType?: BumpType, identifier?: string): void;
ensure(project: IPackageJson, force?: boolean): IPackageJson | undefined;
// @internal
get _json(): ILockStepVersionJson;
readonly mainProject: string | undefined;
readonly nextBump: BumpType | undefined;
// @internal (undocumented)
readonly _json: ILockStepVersionJson;
get mainProject(): string | undefined;
get nextBump(): BumpType | undefined;
update(newVersionString: string): boolean;
validate(versionString: string, packageName: string): void;
get version(): string;
Expand Down Expand Up @@ -1603,21 +1631,19 @@ export class SubspacesConfiguration {

// @public
export abstract class VersionPolicy {
// Warning: (ae-forgotten-export) The symbol "IVersionPolicyJson" needs to be exported by the entry point index.d.ts
//
// @internal
constructor(versionPolicyJson: IVersionPolicyJson);
abstract bump(bumpType?: BumpType, identifier?: string): void;
readonly definitionName: VersionPolicyDefinitionName;
get definitionName(): VersionPolicyDefinitionName;
abstract ensure(project: IPackageJson, force?: boolean): IPackageJson | undefined;
readonly exemptFromRushChange: boolean;
readonly includeEmailInChangeFile: boolean;
get exemptFromRushChange(): boolean;
get includeEmailInChangeFile(): boolean;
get isLockstepped(): boolean;
// @internal
abstract get _json(): IVersionPolicyJson;
readonly _json: IVersionPolicyJson;
// @internal
static load(versionPolicyJson: IVersionPolicyJson): VersionPolicy | undefined;
readonly policyName: string;
get policyName(): string;
setDependenciesBeforeCommit(packageName: string, configuration: RushConfiguration): void;
setDependenciesBeforePublish(packageName: string, configuration: RushConfiguration): void;
abstract validate(versionString: string, packageName: string): void;
Expand Down
127 changes: 53 additions & 74 deletions libraries/rush-lib/src/api/VersionPolicy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@
import * as semver from 'semver';
import { type IPackageJson, Enum } from '@rushstack/node-core-library';

import {
type IVersionPolicyJson,
type ILockStepVersionJson,
type IIndividualVersionJson,
import type {
IVersionPolicyJson,
ILockStepVersionJson,
IIndividualVersionJson,
VersionFormatForCommit,
VersionFormatForPublish,
type IVersionPolicyDependencyJson
VersionFormatForPublish
} from './VersionPolicyConfiguration';
import type { PackageJsonEditor } from './PackageJsonEditor';
import type { RushConfiguration } from './RushConfiguration';
Expand Down Expand Up @@ -57,42 +56,54 @@ export enum VersionPolicyDefinitionName {
* @public
*/
export abstract class VersionPolicy {
private _versionFormatForCommit: VersionFormatForCommit;
private _versionFormatForPublish: VersionFormatForPublish;
/**
* Serialized json for the policy
*
* @internal
*/
public readonly _json: IVersionPolicyJson;

private get _versionFormatForCommit(): VersionFormatForCommit {
return this._json.dependencies?.versionFormatForCommit ?? 'original';
}

private get _versionFormatForPublish(): VersionFormatForPublish {
return this._json.dependencies?.versionFormatForPublish ?? 'original';
}

/**
* Version policy name
*/
public readonly policyName: string;
public get policyName(): string {
return this._json.policyName;
}

/**
* Version policy definition name
*/
public readonly definitionName: VersionPolicyDefinitionName;
public get definitionName(): VersionPolicyDefinitionName {
return Enum.getValueByKey(VersionPolicyDefinitionName, this._json.definitionName);
}

/**
* Determines if a version policy wants to opt out of changelog files.
*/
public readonly exemptFromRushChange: boolean;
public get exemptFromRushChange(): boolean {
return this._json.exemptFromRushChange ?? false;
}

/**
* Determines if a version policy wants to opt in to including email.
*/
public readonly includeEmailInChangeFile: boolean;
public get includeEmailInChangeFile(): boolean {
return this._json.includeEmailInChangeFile ?? false;
}

/**
* @internal
*/
public constructor(versionPolicyJson: IVersionPolicyJson) {
this.policyName = versionPolicyJson.policyName;
this.definitionName = Enum.getValueByKey(VersionPolicyDefinitionName, versionPolicyJson.definitionName);
this.exemptFromRushChange = versionPolicyJson.exemptFromRushChange || false;
this.includeEmailInChangeFile = versionPolicyJson.includeEmailInChangeFile || false;

const jsonDependencies: IVersionPolicyDependencyJson = versionPolicyJson.dependencies || {};
this._versionFormatForCommit = jsonDependencies.versionFormatForCommit || VersionFormatForCommit.original;
this._versionFormatForPublish =
jsonDependencies.versionFormatForPublish || VersionFormatForPublish.original;
this._json = versionPolicyJson;
}

/**
Expand Down Expand Up @@ -140,13 +151,6 @@ export abstract class VersionPolicy {
*/
public abstract bump(bumpType?: BumpType, identifier?: string): void;

/**
* Serialized json for the policy
*
* @internal
*/
public abstract get _json(): IVersionPolicyJson;

/**
* Validates the specified version and throws if the version does not satisfy the policy.
*
Expand All @@ -160,7 +164,7 @@ export abstract class VersionPolicy {
* to values used for publishing.
*/
public setDependenciesBeforePublish(packageName: string, configuration: RushConfiguration): void {
if (this._versionFormatForPublish === VersionFormatForPublish.exact) {
if (this._versionFormatForPublish === 'exact') {
const project: RushConfigurationProject = configuration.getProjectByName(packageName)!;

const packageJsonEditor: PackageJsonEditor = project.packageJsonEditor;
Expand All @@ -186,7 +190,7 @@ export abstract class VersionPolicy {
* to values used for checked-in source.
*/
public setDependenciesBeforeCommit(packageName: string, configuration: RushConfiguration): void {
if (this._versionFormatForCommit === VersionFormatForCommit.wildcard) {
if (this._versionFormatForCommit === 'wildcard') {
const project: RushConfigurationProject = configuration.getProjectByName(packageName)!;

const packageJsonEditor: PackageJsonEditor = project.packageJsonEditor;
Expand All @@ -211,34 +215,37 @@ export abstract class VersionPolicy {
* @public
*/
export class LockStepVersionPolicy extends VersionPolicy {
/**
* @internal
*/
public declare readonly _json: ILockStepVersionJson;
private _version: semver.SemVer;

/**
* The type of bump for next bump.
*/
// nextBump is probably not needed. It can be prerelease only.
// Other types of bumps can be passed in as a parameter to bump method, so can identifier.
public readonly nextBump: BumpType | undefined;
public get nextBump(): BumpType | undefined {
return this._json.nextBump !== undefined ? Enum.getValueByKey(BumpType, this._json.nextBump) : undefined;
}

/**
* The main project for the version policy.
*
* If the value is provided, change logs will only be generated in that project.
* If the value is not provided, change logs will be hosted in each project associated with the policy.
*/
public readonly mainProject: string | undefined;
public get mainProject(): string | undefined {
return this._json.mainProject;
}

/**
* @internal
*/
public constructor(versionPolicyJson: ILockStepVersionJson) {
super(versionPolicyJson);
this._version = new semver.SemVer(versionPolicyJson.version);
this.nextBump =
versionPolicyJson.nextBump !== undefined
? Enum.getValueByKey(BumpType, versionPolicyJson.nextBump)
: undefined;
this.mainProject = versionPolicyJson.mainProject;
}

/**
Expand All @@ -248,26 +255,6 @@ export class LockStepVersionPolicy extends VersionPolicy {
return this._version.format();
}

/**
* Serialized json for this policy
*
* @internal
*/
public get _json(): ILockStepVersionJson {
const json: ILockStepVersionJson = {
policyName: this.policyName,
definitionName: VersionPolicyDefinitionName[this.definitionName],
version: this.version
};
if (this.nextBump !== undefined) {
json.nextBump = BumpType[this.nextBump];
}
if (this.mainProject !== undefined) {
json.mainProject = this.mainProject;
}
return json;
}

/**
* Returns an updated package json that satisfies the version policy.
*
Expand Down Expand Up @@ -303,6 +290,7 @@ export class LockStepVersionPolicy extends VersionPolicy {
}

this._version.inc(this._getReleaseType(nextBump), identifier);
this._json.version = this.version;
}

/**
Expand All @@ -315,6 +303,7 @@ export class LockStepVersionPolicy extends VersionPolicy {
return false;
}
this._version = newVersion;
this._json.version = this.version;
return true;
}

Expand Down Expand Up @@ -349,32 +338,22 @@ export class LockStepVersionPolicy extends VersionPolicy {
*/
export class IndividualVersionPolicy extends VersionPolicy {
/**
* The major version that has been locked
* @internal
*/
public readonly lockedMajor: number | undefined;
public declare readonly _json: IIndividualVersionJson;

/**
* @internal
* The major version that has been locked
*/
public constructor(versionPolicyJson: IIndividualVersionJson) {
super(versionPolicyJson);
this.lockedMajor = versionPolicyJson.lockedMajor;
public get lockedMajor(): number | undefined {
return this._json.lockedMajor;
}

/**
* Serialized json for this policy
*
* @internal
*/
public get _json(): IIndividualVersionJson {
const json: IIndividualVersionJson = {
policyName: this.policyName,
definitionName: VersionPolicyDefinitionName[this.definitionName]
};
if (this.lockedMajor !== undefined) {
json.lockedMajor = this.lockedMajor;
}
return json;
public constructor(versionPolicyJson: IIndividualVersionJson) {
super(versionPolicyJson);
}

/**
Expand Down
Loading
Loading