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
6 changes: 5 additions & 1 deletion src/builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ import {
import { unknownParsedFile } from './apitypes/unknown/unknown.parser'
import { createVersionPackage } from './components/package'
import { compareVersions } from './components/compare'
import { applyBuilderVersionInfo } from './validators'
import { buildFiles } from './components/files'
import JSZip from 'jszip'
import { calculateHistoryForDeprecatedItems } from './components/deprecated'
Expand Down Expand Up @@ -228,6 +229,7 @@ export class PackageVersionBuilder implements IPackageVersionBuilder {
versionDocumentsResolver: this.versionDocumentsResolver.bind(this),
rawDocumentResolver: this.rawDocumentResolver.bind(this),
normalizedSpecFragmentsHashCache: this.normalizedSpecFragmentsHashCache,
apiProcessorVersionValidationLevel: this.builderRunOptions.apiProcessorVersionValidationLevel,
}
}

Expand Down Expand Up @@ -760,11 +762,13 @@ export class PackageVersionBuilder implements IPackageVersionBuilder {
this.config.previousVersionPackageId || this.config.packageId,
this.builderContext(config),
)
this.comparisons = await compareVersions(
const compareResult = await compareVersions(
[previousVersion, previousVersionPackageId || packageId],
[version, packageId],
this.compareContext(this.config),
)
this.comparisons = compareResult.comparisons
applyBuilderVersionInfo(this.config, compareResult)
} else if (!previousVersion) {
this.comparisons = []
}
Expand Down
16 changes: 12 additions & 4 deletions src/components/compare/compare.operations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@
*/
import {
ApiAudienceTransition,
BuilderVersionInfo,
CompareContext,
CompareOperationsPairContext,
ComparisonDocument,
OperationChanges,
OperationsApiType,
OperationType,
VERSION_VALIDATION_LEVEL,
VersionCache,
VersionParams,
VersionsComparison,
Expand All @@ -44,26 +46,30 @@ import {
SLUG_OPTIONS_OPERATION_ID,
slugify,
} from '../../utils'
import { validateApiProcessorVersion } from '../../validators'
import { getMismatchedBuilderVersion, validateApiProcessorVersion } from '../../validators'

export async function compareVersionsOperations(
prev: VersionParams,
curr: VersionParams,
ctx: CompareContext,
): Promise<VersionsComparison> {
): Promise<VersionsComparison & BuilderVersionInfo> {
const changes: OperationChanges[] = []
const operationTypes: OperationType[] = []
const comparisonDocuments: ComparisonDocument[] = []

const { versionResolver } = ctx
const validationLevel = ctx.apiProcessorVersionValidationLevel ?? VERSION_VALIDATION_LEVEL.STRICT

// resolve both versions
const prevVersionData = prev && await versionResolver(...prev)
const currVersionData = curr && await versionResolver(...curr)

// validate api-processor version compatibility
validateApiProcessorVersion(prevVersionData, 'Can\'t build the changelog if previous version was built using an outdated api-processor.')
validateApiProcessorVersion(currVersionData, 'Can\'t build the changelog if current version was built using an outdated api-processor.')
validateApiProcessorVersion(prevVersionData, validationLevel, 'Can\'t build the changelog if previous version was built using an outdated api-processor.')
validateApiProcessorVersion(currVersionData, validationLevel, 'Can\'t build the changelog if current version was built using an outdated api-processor.')

const previousVersionBuilderVersion = getMismatchedBuilderVersion(prevVersionData)
const currentVersionBuilderVersion = getMismatchedBuilderVersion(currVersionData)

// compare operations of each type
for (const apiType of getUniqueApiTypesFromVersions(prevVersionData, currVersionData)) {
Expand Down Expand Up @@ -100,6 +106,8 @@ export async function compareVersionsOperations(
data: changes,
} : {},
comparisonInternalDocuments,
previousVersionBuilderVersion,
currentVersionBuilderVersion,
}
}

Expand Down
18 changes: 13 additions & 5 deletions src/components/compare/compare.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,24 @@
* limitations under the License.
*/

import { BuildConfigRef, CompareContext, VersionParams, VersionsComparison } from '../../types'
import { BuildConfigRef, CompareContext, CompareResult, VersionParams, VersionsComparison } from '../../types'
import { compareVersionsOperations } from './compare.operations'
import { getSplittedVersionKey } from '../../utils'

export async function compareVersions(
prev: VersionParams,
curr: VersionParams,
ctx: CompareContext,
): Promise<VersionsComparison[]> {
): Promise<CompareResult> {
const comparisons: VersionsComparison[] = await compareVersionsReferences(prev, curr, ctx)
comparisons.push(await compareVersionsOperations(prev, curr, ctx))
const { previousVersionBuilderVersion, currentVersionBuilderVersion, ...comparison } = await compareVersionsOperations(prev, curr, ctx)
comparisons.push(comparison)

return comparisons
return {
comparisons,
previousVersionBuilderVersion,
currentVersionBuilderVersion,
}
}

export async function compareVersionsReferences(
Expand Down Expand Up @@ -73,8 +78,11 @@ export async function compareVersionsReferences(
}
const prevParams: VersionParams = previous ? [previous.version, previous.refId] : null
const currParams: VersionParams = current ? [current.version, current.refId] : null
comparisons.push(await compareVersionsOperations(prevParams, currParams, ctx))
// builder version info is only relevant for the root package; ref-packages report it at their own root level
const { previousVersionBuilderVersion: _, currentVersionBuilderVersion: __, ...refComparison } = await compareVersionsOperations(prevParams, currParams, ctx)
comparisons.push(refComparison)
}

return comparisons
}

5 changes: 4 additions & 1 deletion src/strategies/build.strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import { BuildConfig, BuilderStrategy, BuildResult, BuildTypeContexts, VersionCache } from '../types'
import { compareVersions } from '../components/compare'
import { applyBuilderVersionInfo } from '../validators'
import { DuplicateOperationHandler, getOperationsList, setDocument } from '../utils'
import { buildFiles } from '../components/files'
import { calculateHistoryForDeprecatedItems } from '../components/deprecated'
Expand Down Expand Up @@ -86,11 +87,13 @@ export class BuildStrategy implements BuilderStrategy {
}

if (!builderContextObject.builderRunOptions.withoutChangelog && previousVersionCache) {
buildResult.comparisons = await compareVersions(
const compareResult = await compareVersions(
[previousVersionCache.version, previousVersionPackageId || packageId],
[version, packageId],
compareContextObject,
)
buildResult.comparisons = compareResult.comparisons
applyBuilderVersionInfo(config, compareResult)
}

return buildResult
Expand Down
5 changes: 4 additions & 1 deletion src/strategies/changelog.strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import { BuildConfig, BuilderStrategy, BuildResult, BuildTypeContexts, VersionCache } from '../types'
import { compareVersions } from '../components/compare'
import { applyBuilderVersionInfo } from '../validators'
import { MESSAGE_SEVERITY } from '../consts'

export class ChangelogStrategy implements BuilderStrategy {
Expand All @@ -37,11 +38,13 @@ export class ChangelogStrategy implements BuilderStrategy {
})
}

buildResult.comparisons = await compareVersions(
const compareResult = await compareVersions(
comparisonPreviousVersion ? [comparisonPreviousVersion, previousVersionPackageId || packageId] : null,
[version, packageId],
compareContextObject,
)
buildResult.comparisons = compareResult.comparisons
applyBuilderVersionInfo(config, compareResult)

return buildResult
}
Expand Down
5 changes: 4 additions & 1 deletion src/strategies/prefix-groups-changelog.strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import { BuildConfig, BuilderStrategy, BuildResult, BuildTypeContexts } from '../types'
import { compareVersions } from '../components/compare'
import { applyBuilderVersionInfo } from '../validators'
import { validateGroupPrefix } from '../apitypes/rest/rest.utils'

export class PrefixGroupsChangelogStrategy implements BuilderStrategy {
Expand All @@ -27,11 +28,13 @@ export class PrefixGroupsChangelogStrategy implements BuilderStrategy {
validateGroupPrefix(config.currentGroup, 'currentGroup')
validateGroupPrefix(config.previousGroup, 'previousGroup')

buildResult.comparisons = await compareVersions(
const compareResult = await compareVersions(
[version, packageId],
[version, packageId],
compareContext(config),
)
buildResult.comparisons = compareResult.comparisons
applyBuilderVersionInfo(config, compareResult)

return buildResult
}
Expand Down
3 changes: 3 additions & 0 deletions src/types/external/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ export interface BuildConfig extends BuildConfigBase {
// todo since it goes straight to the info.json, remove it from every buildconfig except the one that is 'build'
validationRulesSeverity?: ValidationRulesSeverity
operationsSpecTransformation?: OperationsSpecTransformation

previousVersionBuilderVersion?: string
currentVersionBuilderVersion?: string
Comment thread
JayLim2 marked this conversation as resolved.
}

// todo rename
Expand Down
8 changes: 8 additions & 0 deletions src/types/internal/builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@ export interface IPackageVersionBuilder {

export type FileSourceMap = Record<string, Blob>

export const VERSION_VALIDATION_LEVEL = {
STRICT: 'strict',
MAJOR: 'major',
} as const

export type VersionValidationLevel = typeof VERSION_VALIDATION_LEVEL[keyof typeof VERSION_VALIDATION_LEVEL]

/**
* @param {boolean} [withChangelog=true] - Generate changelog flag.
* @param {boolean} [withBwc=true] - Check backward compatibility flag.
Expand All @@ -82,6 +89,7 @@ export type BuilderRunOptions = Partial<{
withoutBwc: boolean
withoutDeprecatedDepth: boolean
cleanCache: boolean
apiProcessorVersionValidationLevel: VersionValidationLevel
}>

export interface BuildFileResult<T = any> {
Expand Down
11 changes: 11 additions & 0 deletions src/types/internal/compare.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import {
BuilderType,
} from './apiBuilder'
import { ObjectHashCache } from '../../utils/hashes'
import { VersionValidationLevel } from './builder'
import { ApihubApiCompatibilityKind } from '../../consts'

export type ChangeKind = keyof ChangeSummary
Expand Down Expand Up @@ -126,4 +127,14 @@ export interface CompareContext {
versionDocumentsResolver: VersionDocumentsResolver
rawDocumentResolver: _RawDocumentResolver
normalizedSpecFragmentsHashCache: ObjectHashCache
apiProcessorVersionValidationLevel?: VersionValidationLevel
}

export type BuilderVersionInfo = {
previousVersionBuilderVersion?: string
currentVersionBuilderVersion?: string
}
Comment thread
JayLim2 marked this conversation as resolved.

export type CompareResult = {
comparisons: VersionsComparison[]
} & BuilderVersionInfo
3 changes: 3 additions & 0 deletions src/types/package/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,7 @@ export interface PackageConfig {

metadata?: Record<string, unknown>
format?: ExportFormat

previousVersionBuilderVersion?: string
currentVersionBuilderVersion?: string
Comment thread
JayLim2 marked this conversation as resolved.
}
48 changes: 45 additions & 3 deletions src/validators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

import { BuildConfig, VersionCache } from './types'
import { BuildConfig, BuilderVersionInfo, PackageConfig, VERSION_VALIDATION_LEVEL, VersionCache, VersionValidationLevel } from './types'
import { assert } from './utils'
import { BUILD_TYPE } from './consts'
import { version as apiProcessorVersion } from '../package.json'
Expand All @@ -30,14 +30,56 @@ export function validateConfig(config: BuildConfig): void {
}
}

export function validateApiProcessorVersion(resolvedVersion: VersionCache | null, errorPrefix?: string): void {
export function validateApiProcessorVersion(
resolvedVersion: VersionCache | null,
validationLevel: VersionValidationLevel,
errorPrefix?: string,
): void {

if (!resolvedVersion) {
return
}

if (validationLevel === VERSION_VALIDATION_LEVEL.MAJOR) {
const resolvedMajor = parseMajorVersion(resolvedVersion.apiProcessorVersion)
const currentMajor = parseMajorVersion(apiProcessorVersion)
if (resolvedMajor === null || currentMajor === null) {
return
}
if (resolvedMajor !== currentMajor) {
errorPrefix = errorPrefix ? `${errorPrefix} ` : ''
throw new Error(`${errorPrefix}Expected api-processor major version: ${currentMajor}, got ${resolvedMajor} for package ${resolvedVersion.packageId} version ${resolvedVersion.version}`)
}
return
}

if (resolvedVersion.apiProcessorVersion !== apiProcessorVersion) {
errorPrefix = errorPrefix ? `${errorPrefix} ` : ''
throw new Error(`${errorPrefix}Expected api-processor version: ${apiProcessorVersion}, got ${resolvedVersion.apiProcessorVersion} for package ${resolvedVersion.packageId} version ${resolvedVersion.version}`)
throw new Error(`${errorPrefix}Expected api-processor version: ${apiProcessorVersion}, got ${resolvedVersion.apiProcessorVersion} for package ${resolvedVersion.packageId} version ${resolvedVersion.version}`)
}
}

export function getMismatchedBuilderVersion(versionData: VersionCache | null | undefined): string | undefined {
if (!versionData?.apiProcessorVersion || versionData.apiProcessorVersion === apiProcessorVersion) {
return undefined
}
return versionData.apiProcessorVersion
}

export function applyBuilderVersionInfo(config: PackageConfig, source: BuilderVersionInfo): void {
Comment thread
b41ex marked this conversation as resolved.
if (source.previousVersionBuilderVersion) {
config.previousVersionBuilderVersion = source.previousVersionBuilderVersion
} else {
delete config.previousVersionBuilderVersion
}
if (source.currentVersionBuilderVersion) {
config.currentVersionBuilderVersion = source.currentVersionBuilderVersion
} else {
delete config.currentVersionBuilderVersion
}
}

function parseMajorVersion(version: string): number | null {
const match = version.match(/^(\d+)\./)
return match ? parseInt(match[1], 10) : null
}
17 changes: 17 additions & 0 deletions test/helpers/registry/local.ts
Original file line number Diff line number Diff line change
Expand Up @@ -711,3 +711,20 @@ export class LocalRegistry implements IRegistry {
versionCache?.operations.set(operationId, modifier(operation))
}
}

export class VersionOverrideRegistry extends LocalRegistry {
private apiProcessorVersionOverrides = new Map<string, string>()

overrideApiProcessorVersion(version: string, value: string): void {
this.apiProcessorVersionOverrides.set(version, value)
}

async versionResolver(packageId: string = '', version: string): Promise<ResolvedVersion | null> {
const result = await super.versionResolver(packageId, version)
const override = this.apiProcessorVersionOverrides.get(version)
if (result && override) {
result.apiProcessorVersion = override
}
return result
}
}
Loading
Loading