diff --git a/lib/datasource/common.ts b/lib/datasource/common.ts index ef65c42243d96faa8977886adaaeaaa858c0863e..90584a8d03b5fb67ab0c5d5b8927d42eb9ad24fd 100644 --- a/lib/datasource/common.ts +++ b/lib/datasource/common.ts @@ -24,6 +24,8 @@ export interface Release { } export interface ReleaseResult { + sourceDirectory?: string; + latestVersion?: string; changelogUrl?: string; dependencyUrl?: string; deprecationMessage?: string; diff --git a/lib/types/clean-git-ref.d.ts b/lib/types/clean-git-ref.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..1ee0905c15247fac2f028ad1c2aa24811dd242e8 --- /dev/null +++ b/lib/types/clean-git-ref.d.ts @@ -0,0 +1,3 @@ +declare module 'clean-git-ref' { + export function clean(branch: string): string; +} diff --git a/lib/workers/repository/process/extract-update.js b/lib/workers/repository/process/extract-update.js index 0352e1b43c5419e4f23fc0731ef8444a842d4507..58545304cb6f87916e421e3c11a37553101c95cc 100644 --- a/lib/workers/repository/process/extract-update.js +++ b/lib/workers/repository/process/extract-update.js @@ -12,6 +12,7 @@ module.exports = { async function extractAndUpdate(config) { logger.debug('extractAndUpdate()'); + /** @type {any} */ const packageFiles = await extractAllDependencies(config); logger.trace({ config: packageFiles }, 'packageFiles'); await fetchUpdates(config, packageFiles); diff --git a/lib/workers/repository/process/lookup/common.ts b/lib/workers/repository/process/lookup/common.ts new file mode 100644 index 0000000000000000000000000000000000000000..d018bb90d559098e2811ecd5186abd3835cdb3b6 --- /dev/null +++ b/lib/workers/repository/process/lookup/common.ts @@ -0,0 +1,22 @@ +export interface LookupUpdate { + blockedByPin?: boolean; + branchName?: string; + commitMessageAction?: string; + displayFrom?: string; + displayTo?: string; + isLockfileUpdate?: boolean; + isPin?: boolean; + isRange?: boolean; + isRollback?: boolean; + isSingleVersion?: boolean; + fromVersion?: string; + newDigest?: string; + newDigestShort?: string; + newMajor?: number; + newMinor?: number; + newValue: string; + newVersion?: string; + semanticCommitType?: string; + toVersion?: string; + updateType: string; +} diff --git a/lib/workers/repository/process/lookup/filter.js b/lib/workers/repository/process/lookup/filter.ts similarity index 83% rename from lib/workers/repository/process/lookup/filter.js rename to lib/workers/repository/process/lookup/filter.ts index 6493acbef3b3f8e3ae3b711286494ffbea5ec6c9..cd6c6c01a939110ca3516e423a35b40aa941b934 100644 --- a/lib/workers/repository/process/lookup/filter.js +++ b/lib/workers/repository/process/lookup/filter.ts @@ -1,18 +1,25 @@ -const semver = require('semver'); -const { logger } = require('../../../../logger'); -const versioning = require('../../../../versioning'); +import * as semver from 'semver'; +import { logger } from '../../../../logger'; +import * as versioning from '../../../../versioning'; +import { Release } from '../../../../datasource'; -module.exports = { - filterVersions, -}; +export interface FilterConfig { + allowedVersions?: string; + depName?: string; + followTag?: string; + ignoreDeprecated?: boolean; + ignoreUnstable?: boolean; + respectLatest?: boolean; + versionScheme: string; +} -function filterVersions( - config, - fromVersion, - latestVersion, - versions, - releases -) { +export function filterVersions( + config: FilterConfig, + fromVersion: string, + latestVersion: string, + versions: string[], + releases: Release[] +): string[] { const { versionScheme, ignoreUnstable, diff --git a/lib/workers/repository/process/lookup/index.js b/lib/workers/repository/process/lookup/index.ts similarity index 84% rename from lib/workers/repository/process/lookup/index.js rename to lib/workers/repository/process/lookup/index.ts index 4564aa7aeabc2a6781bab10a265ada4d4983cd4c..d9ca7c5d245d7b93dd0a0b6bce6596dbbaacff91 100644 --- a/lib/workers/repository/process/lookup/index.js +++ b/lib/workers/repository/process/lookup/index.ts @@ -1,31 +1,68 @@ -const { logger } = require('../../../../logger'); -const versioning = require('../../../../versioning'); -const { getRollbackUpdate } = require('./rollback'); -const { getRangeStrategy } = require('../../../../manager'); -const { filterVersions } = require('./filter'); -const { +import { logger } from '../../../../logger'; +import * as versioning from '../../../../versioning'; +import { getRollbackUpdate, RollbackConfig } from './rollback'; +import { getRangeStrategy } from '../../../../manager'; +import { filterVersions, FilterConfig } from './filter'; +import { getPkgReleases, supportsDigests, getDigest, -} = require('../../../../datasource'); + Release, +} from '../../../../datasource'; +import { LookupUpdate } from './common'; +import { RangeConfig } from '../../../../manager/common'; +import { RenovateConfig } from '../../../../config'; -const clone = input => JSON.parse(JSON.stringify(input)); +const clone = <T>(input: T): T => JSON.parse(JSON.stringify(input)); -module.exports = { - lookupUpdates, -}; +export interface LookupWarning { + updateType: 'warning'; + message: string; +} + +export interface UpdateResult { + sourceDirectory?: string; + dockerRepository?: string; + dockerRegistry?: string; + changelogUrl?: string; + homepage?: string; + deprecationMessage?: string; + sourceUrl?: string; + skipReason?: string; + releases: Release[]; + + updates: LookupUpdate[]; + warnings: LookupWarning[]; +} + +export interface LookupUpdateConfig + extends RollbackConfig, + FilterConfig, + RangeConfig, + RenovateConfig { + separateMinorPatch?: boolean; + digestOneAndOnly?: boolean; + pinDigests?: boolean; + rollbackPrs?: boolean; + currentDigest?: string; + lockedVersion?: string; -async function lookupUpdates(config) { + separateMajorMinor?: boolean; + separateMultipleMajor?: boolean; +} + +export async function lookupUpdates( + config: LookupUpdateConfig +): Promise<UpdateResult> { const { depName, currentValue, lockedVersion } = config; logger.trace({ dependency: depName, currentValue }, 'lookupUpdates'); const version = versioning.get(config.versionScheme); - /** @type any */ - const res = { updates: [], warnings: [] }; + const res: UpdateResult = { updates: [], warnings: [] } as any; if (version.isValid(currentValue)) { const dependency = clone(await getPkgReleases(config)); if (!dependency) { // If dependency lookup fails then warn and return - const result = { + const result: LookupWarning = { updateType: 'warning', message: `Failed to look up dependency ${depName}`, }; @@ -93,12 +130,10 @@ async function lookupUpdates(config) { const rollback = getRollbackUpdate(config, allVersions); // istanbul ignore if if (!rollback) { - res.warnings.push([ - { - updateType: 'warning', - message: `Can't find version matching ${currentValue} for ${depName}`, - }, - ]); + res.warnings.push({ + updateType: 'warning', + message: `Can't find version matching ${currentValue} for ${depName}`, + }); return res; } res.updates.push(rollback); @@ -140,7 +175,7 @@ async function lookupUpdates(config) { ); const buckets = {}; for (const toVersion of filteredVersions) { - const update = { fromVersion, toVersion }; + const update: LookupUpdate = { fromVersion, toVersion } as any; try { update.newValue = version.getNewValue( currentValue, @@ -294,7 +329,11 @@ async function lookupUpdates(config) { return res; } -function getType(config, fromVersion, toVersion) { +function getType( + config: LookupUpdateConfig, + fromVersion: string, + toVersion: string +): string { const { versionScheme, rangeStrategy, currentValue } = config; const version = versioning.get(versionScheme); if (rangeStrategy === 'bump' && version.matches(toVersion, currentValue)) { @@ -315,7 +354,7 @@ function getType(config, fromVersion, toVersion) { return 'minor'; } -function getBucket(config, update) { +function getBucket(config: LookupUpdateConfig, update: LookupUpdate) { const { separateMajorMinor, separateMultipleMajor } = config; const { updateType, newMajor } = update; if (updateType === 'lockfileUpdate') { @@ -334,7 +373,11 @@ function getBucket(config, update) { return updateType; } -function getFromVersion(config, rangeStrategy, allVersions) { +function getFromVersion( + config: LookupUpdateConfig, + rangeStrategy: string, + allVersions: string[] +): string { const { currentValue, lockedVersion, versionScheme } = config; const version = versioning.get(versionScheme); if (version.isVersion(currentValue)) { diff --git a/lib/workers/repository/process/lookup/rollback.js b/lib/workers/repository/process/lookup/rollback.ts similarity index 77% rename from lib/workers/repository/process/lookup/rollback.js rename to lib/workers/repository/process/lookup/rollback.ts index 28b8fec0ab8d2a8a7d8a80ae38d7305c37ee9576..43ae0cbd67a2f8aac44c1da4938d4ffac70fc25e 100644 --- a/lib/workers/repository/process/lookup/rollback.js +++ b/lib/workers/repository/process/lookup/rollback.ts @@ -1,11 +1,18 @@ -const { logger } = require('../../../../logger'); -const versioning = require('../../../../versioning'); +import { logger } from '../../../../logger'; +import * as versioning from '../../../../versioning'; +import { LookupUpdate } from './common'; -module.exports = { - getRollbackUpdate, -}; +export interface RollbackConfig { + currentValue?: string; + depName?: string; + packageFile: Record<string, any>; + versionScheme: string; +} -function getRollbackUpdate(config, versions) { +export function getRollbackUpdate( + config: RollbackConfig, + versions: string[] +): LookupUpdate { const { packageFile, versionScheme, depName, currentValue } = config; const version = versioning.get(versionScheme); // istanbul ignore if @@ -42,7 +49,7 @@ function getRollbackUpdate(config, versions) { logger.info('No toVersion to roll back to'); return null; } - let fromVersion; + let fromVersion: string; const newValue = version.getNewValue( currentValue, 'replace', diff --git a/lib/workers/repository/updates/branchify.js b/lib/workers/repository/updates/branchify.ts similarity index 86% rename from lib/workers/repository/updates/branchify.js rename to lib/workers/repository/updates/branchify.ts index ffbe9a4f90c947be037180e560dff3e25fb18c40..15dc93ce9f42d0dacc9c685035050e00a7b54774 100644 --- a/lib/workers/repository/updates/branchify.js +++ b/lib/workers/repository/updates/branchify.ts @@ -1,11 +1,11 @@ import slugify from 'slugify'; +import handlebars from 'handlebars'; +import { clean as cleanGitRef } from 'clean-git-ref'; +import { logger, setMeta } from '../../../logger'; -const handlebars = require('handlebars'); -const cleanGitRef = require('clean-git-ref').clean; -const { logger, setMeta } = require('../../../logger'); - -const { generateBranchConfig } = require('./generate'); -const { flattenUpdates } = require('./flatten'); +import { generateBranchConfig } from './generate'; +import { flattenUpdates } from './flatten'; +import { RenovateConfig, ValidationMessage } from '../../../config'; /** * Clean git branch name @@ -15,14 +15,17 @@ const { flattenUpdates } = require('./flatten'); * - trailing dot * - whitespace */ -function cleanBranchName(branchName) { +function cleanBranchName(branchName: string): string { return cleanGitRef(branchName) .replace(/^\.|\.$/, '') // leading or trailing dot .replace(/\/\./g, '/') // leading dot after slash .replace(/\s/g, ''); // whitespace } -function branchifyUpgrades(config, packageFiles) { +export function branchifyUpgrades( + config: RenovateConfig, + packageFiles: Record<string, any[]> +) { logger.debug('branchifyUpgrades'); const updates = flattenUpdates(config, packageFiles); logger.debug( @@ -30,8 +33,8 @@ function branchifyUpgrades(config, packageFiles) { .map(u => u.depName) .join(', ')}` ); - const errors = []; - const warnings = []; + const errors: ValidationMessage[] = []; + const warnings: ValidationMessage[] = []; const branchUpgrades = {}; const branches = []; for (const u of updates) { @@ -40,7 +43,7 @@ function branchifyUpgrades(config, packageFiles) { update.currentVersion = update.currentValue; update.newVersion = update.newVersion || update.newValue; // massage for handlebars - const upper = str => str.charAt(0).toUpperCase() + str.substr(1); + const upper = (str: string) => str.charAt(0).toUpperCase() + str.substr(1); if (update.updateType) { update[`is${upper(update.updateType)}`] = true; } @@ -132,5 +135,3 @@ function branchifyUpgrades(config, packageFiles) { branchList, }; } - -export { branchifyUpgrades }; diff --git a/lib/workers/repository/updates/flatten.js b/lib/workers/repository/updates/flatten.ts similarity index 91% rename from lib/workers/repository/updates/flatten.js rename to lib/workers/repository/updates/flatten.ts index 94bc0e93b9acb0dd6b95186fac03716e1562758d..e8e3694d4352ab50533e5bfe1d34df36b9832c03 100644 --- a/lib/workers/repository/updates/flatten.js +++ b/lib/workers/repository/updates/flatten.ts @@ -1,21 +1,23 @@ import is from '@sindresorhus/is'; - -const { +import { getManagerConfig, mergeChildConfig, filterConfig, -} = require('../../../config'); -const { applyPackageRules } = require('../../../util/package-rules'); -const { get } = require('../../../manager'); - -export { flattenUpdates }; + RenovateConfig, + PackageRule, +} from '../../../config'; +import { applyPackageRules } from '../../../util/package-rules'; +import { get } from '../../../manager'; // Return only rules that contain an updateType -function getUpdateTypeRules(packageRules) { +function getUpdateTypeRules(packageRules: PackageRule[]): PackageRule[] { return packageRules.filter(rule => is.nonEmptyArray(rule.updateTypes)); } -function flattenUpdates(config, packageFiles) { +export function flattenUpdates( + config: RenovateConfig, + packageFiles: Record<string, any[]> +) { const updates = []; const updateTypes = [ 'major', diff --git a/lib/workers/repository/updates/generate.js b/lib/workers/repository/updates/generate.ts similarity index 94% rename from lib/workers/repository/updates/generate.js rename to lib/workers/repository/updates/generate.ts index c6177db7bf983767cbc6bdc4e53465a9bbe3ddf5..d77afc91f1fc68d9205c67859bd6d326f9e10949 100644 --- a/lib/workers/repository/updates/generate.js +++ b/lib/workers/repository/updates/generate.ts @@ -1,11 +1,16 @@ -const handlebars = require('handlebars'); -const { DateTime } = require('luxon'); -const semver = require('semver'); -const mdTable = require('markdown-table'); -const { logger } = require('../../../logger'); -const { mergeChildConfig } = require('../../../config'); +import * as handlebars from 'handlebars'; +import { DateTime } from 'luxon'; +import semver from 'semver'; +import mdTable from 'markdown-table'; +import { logger } from '../../../logger'; +import { mergeChildConfig, ManagerConfig } from '../../../config'; +import { PackageDependency } from '../../../manager/common'; -function ifTypesGroup(depNames, hasGroupName, branchUpgrades) { +function ifTypesGroup( + depNames: string[], + hasGroupName: boolean, + branchUpgrades: any[] +): boolean { return ( depNames.length === 2 && !hasGroupName && @@ -18,11 +23,10 @@ function ifTypesGroup(depNames, hasGroupName, branchUpgrades) { ); } -function generateBranchConfig(branchUpgrades) { +export function generateBranchConfig(branchUpgrades) { logger.debug(`generateBranchConfig(${branchUpgrades.length})`); logger.trace({ config: branchUpgrades }); - /** @type any */ - let config = { + let config: any = { upgrades: [], }; const hasGroupName = branchUpgrades[0].groupName !== null; @@ -287,7 +291,9 @@ function generateBranchConfig(branchUpgrades) { return config; } -function getTableValues(upgrade) { +function getTableValues( + upgrade: PackageDependency & ManagerConfig +): [string, string, string, string] | null { if (!upgrade.commitBodyTable) { return null; } @@ -320,7 +326,3 @@ function getTableValues(upgrade) { ); return null; } - -module.exports = { - generateBranchConfig, -}; diff --git a/test/workers/repository/updates/branchify.spec.js b/test/workers/repository/updates/branchify.spec.js index 628e0f28dfb146614fa31b6bdc089849958cf3f3..19e32e427b3f5981efa8f7b2e7da651eed1b3aa2 100644 --- a/test/workers/repository/updates/branchify.spec.js +++ b/test/workers/repository/updates/branchify.spec.js @@ -22,7 +22,7 @@ describe('workers/repository/updates/branchify', () => { describe('branchifyUpgrades()', () => { it('returns empty', async () => { flattenUpdates.mockReturnValueOnce([]); - const res = await branchifyUpgrades(config); + const res = await branchifyUpgrades(config, {}); expect(res.branches).toEqual([]); }); it('returns one branch if one input', async () => { @@ -36,7 +36,7 @@ describe('workers/repository/updates/branchify', () => { }, ]); config.repoIsOnboarded = true; - const res = await branchifyUpgrades(config); + const res = await branchifyUpgrades(config, {}); expect(Object.keys(res.branches)).toHaveLength(1); expect(res.branches[0].isMinor).toBe(true); expect(res.branches[0].upgrades[0].isMinor).toBe(true); @@ -89,7 +89,7 @@ describe('workers/repository/updates/branchify', () => { }, ]); config.repoIsOnboarded = true; - const res = await branchifyUpgrades(config); + const res = await branchifyUpgrades(config, {}); expect(Object.keys(res.branches)).toHaveLength(4); expect(res.branches[0].isMajor).toBe(true); expect(res.branches[0].groupSlug).toBe(`major-some-packages`); @@ -121,7 +121,7 @@ describe('workers/repository/updates/branchify', () => { prTitle: 'some-title', }, ]); - const res = await branchifyUpgrades(config); + const res = await branchifyUpgrades(config, {}); expect(Object.keys(res.branches)).toHaveLength(3); }); it('groups if same compiled branch names', async () => { @@ -145,7 +145,7 @@ describe('workers/repository/updates/branchify', () => { prTitle: 'some-title', }, ]); - const res = await branchifyUpgrades(config); + const res = await branchifyUpgrades(config, {}); expect(Object.keys(res.branches)).toHaveLength(2); }); it('groups if same compiled group name', async () => { @@ -173,7 +173,7 @@ describe('workers/repository/updates/branchify', () => { group: { branchName: 'renovate/my-group' }, }, ]); - const res = await branchifyUpgrades(config); + const res = await branchifyUpgrades(config, {}); expect(Object.keys(res.branches)).toHaveLength(2); }); it('enforces valid git branch name', async () => { @@ -240,7 +240,7 @@ describe('workers/repository/updates/branchify', () => { fixtures.map(({ upgrade }) => upgrade) ); - (await branchifyUpgrades(config)).branches.forEach( + (await branchifyUpgrades(config, {})).branches.forEach( ({ branchName }, index) => { expect(branchName).toBe(fixtures[index].expectedBranchName); }