diff --git a/lib/config/definitions.ts b/lib/config/definitions.ts index 28742981dfb99a69585503bfb08243aa144b14a8..bbde257d65822ed09fd45c8f040f322dab5a795a 100644 --- a/lib/config/definitions.ts +++ b/lib/config/definitions.ts @@ -1456,32 +1456,6 @@ const options: RenovateOptions[] = [ type: 'object', default: { versioning: dockerVersioning.id, - managerBranchPrefix: 'docker-', - commitMessageTopic: '{{{depName}}} Docker tag', - major: { enabled: false }, - commitMessageExtra: - 'to v{{#if isMajor}}{{{newMajor}}}{{else}}{{{newVersion}}}{{/if}}', - digest: { - branchTopic: '{{{depNameSanitized}}}-{{{currentValue}}}', - commitMessageExtra: 'to {{newDigestShort}}', - commitMessageTopic: - '{{{depName}}}{{#if currentValue}}:{{{currentValue}}}{{/if}} Docker digest', - group: { - commitMessageTopic: '{{{groupName}}}', - commitMessageExtra: '', - }, - }, - pin: { - commitMessageExtra: '', - groupName: 'Docker digests', - group: { - commitMessageTopic: '{{{groupName}}}', - branchTopic: 'digests-pin', - }, - }, - group: { - commitMessageTopic: '{{{groupName}}} Docker tags', - }, }, mergeable: true, cli: false, diff --git a/lib/datasource/common.ts b/lib/datasource/common.ts index 8ae1040dbe2812eb4c4944b0eb34bec2862ac2ae..9b9037a8866ce00caaa0a925de5358003df304fe 100644 --- a/lib/datasource/common.ts +++ b/lib/datasource/common.ts @@ -70,6 +70,7 @@ export interface Datasource { getReleases(config: GetReleasesConfig): Promise<ReleaseResult | null>; defaultRegistryUrls?: string[]; appendRegistryUrls?: string[]; + defaultConfig?: object; } export class DatasourceError extends Error { diff --git a/lib/datasource/docker/index.ts b/lib/datasource/docker/index.ts index 9d12ed7da6624a7c4e4fbc1aa117611f199ac15d..acc5411fac6412857a8eca1dbb07c67808dee46d 100644 --- a/lib/datasource/docker/index.ts +++ b/lib/datasource/docker/index.ts @@ -16,6 +16,35 @@ import { HostRule } from '../../types'; export const id = 'docker'; +export const defaultConfig = { + managerBranchPrefix: 'docker-', + commitMessageTopic: '{{{depName}}} Docker tag', + major: { enabled: false }, + commitMessageExtra: + 'to v{{#if isMajor}}{{{newMajor}}}{{else}}{{{newVersion}}}{{/if}}', + digest: { + branchTopic: '{{{depNameSanitized}}}-{{{currentValue}}}', + commitMessageExtra: 'to {{newDigestShort}}', + commitMessageTopic: + '{{{depName}}}{{#if currentValue}}:{{{currentValue}}}{{/if}} Docker digest', + group: { + commitMessageTopic: '{{{groupName}}}', + commitMessageExtra: '', + }, + }, + pin: { + commitMessageExtra: '', + groupName: 'Docker digests', + group: { + commitMessageTopic: '{{{groupName}}}', + branchTopic: 'digests-pin', + }, + }, + group: { + commitMessageTopic: '{{{groupName}}} Docker tags', + }, +}; + const http = new Http(id); const ecrRegex = /\d+\.dkr\.ecr\.([-a-z0-9]+)\.amazonaws\.com/; diff --git a/lib/datasource/index.ts b/lib/datasource/index.ts index 7eb1ca8dc0cf64e6fff7cdb9cc442b580177bae2..1e277e1f1b25650f8c975201be3e4b9d54aed261 100644 --- a/lib/datasource/index.ts +++ b/lib/datasource/index.ts @@ -129,3 +129,8 @@ export async function getDigest( value ); } + +export async function getDefaultConfig(datasource: string): Promise<object> { + const loadedDatasource = await load(datasource); + return loadedDatasource?.defaultConfig || {}; +} diff --git a/lib/manager/circleci/__snapshots__/extract.spec.ts.snap b/lib/manager/circleci/__snapshots__/extract.spec.ts.snap index d9dc36298d4f5cfd33ca5d69da640d6b0cd50dfc..825af9c96d4ea318b456dd91c65410ee09a9a350 100644 --- a/lib/manager/circleci/__snapshots__/extract.spec.ts.snap +++ b/lib/manager/circleci/__snapshots__/extract.spec.ts.snap @@ -12,6 +12,7 @@ Array [ "managerData": Object { "lineNumber": 12, }, + "versioning": "docker", }, Object { "commitMessageTopic": "Node.js", @@ -23,6 +24,7 @@ Array [ "managerData": Object { "lineNumber": 57, }, + "versioning": "docker", }, Object { "commitMessageTopic": "Node.js", @@ -34,6 +36,7 @@ Array [ "managerData": Object { "lineNumber": 61, }, + "versioning": "docker", }, Object { "commitMessageTopic": "Node.js", @@ -45,6 +48,7 @@ Array [ "managerData": Object { "lineNumber": 65, }, + "versioning": "docker", }, ] `; @@ -99,6 +103,7 @@ Array [ "managerData": Object { "lineNumber": 20, }, + "versioning": "docker", }, Object { "currentDigest": "sha256:3870d35b962a943df72d948580fc66ceaaee1c4fbd205930f32e0f0760eb1077", @@ -109,6 +114,7 @@ Array [ "managerData": Object { "lineNumber": 27, }, + "versioning": "docker", }, Object { "currentDigest": "sha256:3870d35b962a943df72d948580fc66ceaaee1c4fbd205930f32e0f0760eb1077", @@ -119,6 +125,7 @@ Array [ "managerData": Object { "lineNumber": 34, }, + "versioning": "docker", }, Object { "currentDigest": "sha256:3870d35b962a943df72d948580fc66ceaaee1c4fbd205930f32e0f0760eb1077", @@ -129,6 +136,7 @@ Array [ "managerData": Object { "lineNumber": 41, }, + "versioning": "docker", }, Object { "currentDigest": "sha256:eb6325b75c1c70b4992eaa1bdd29e24e5f14d5324b4714a49f3e67783473214b", @@ -139,6 +147,7 @@ Array [ "managerData": Object { "lineNumber": 50, }, + "versioning": "docker", }, Object { "currentDigest": "sha256:3870d35b962a943df72d948580fc66ceaaee1c4fbd205930f32e0f0760eb1077", @@ -149,6 +158,7 @@ Array [ "managerData": Object { "lineNumber": 57, }, + "versioning": "docker", }, ] `; diff --git a/lib/manager/circleci/extract.ts b/lib/manager/circleci/extract.ts index ab866a5bcc98ee885437a78d44af0f3278833e21..71a0bbd1ab6339bcec52bd0f0320fb8a17533df8 100644 --- a/lib/manager/circleci/extract.ts +++ b/lib/manager/circleci/extract.ts @@ -53,6 +53,7 @@ export function extractPackageFile(content: string): PackageFile | null { 'CircleCI docker image' ); dep.depType = 'docker'; + dep.versioning = 'docker'; dep.managerData = { lineNumber }; deps.push(dep); } diff --git a/lib/manager/circleci/index.ts b/lib/manager/circleci/index.ts index 3ed943c3156ac4fc686507486f8a853e3660e471..5695fc3a5323f09437e16e6070de90b43fe1640f 100644 --- a/lib/manager/circleci/index.ts +++ b/lib/manager/circleci/index.ts @@ -1,10 +1,7 @@ import { extractPackageFile } from './extract'; import { updateDependency } from './update'; -import { LANGUAGE_DOCKER } from '../../constants/languages'; -const language = LANGUAGE_DOCKER; - -export { extractPackageFile, language, updateDependency }; +export { extractPackageFile, updateDependency }; export const defaultConfig = { fileMatch: ['(^|/).circleci/config.yml$'], diff --git a/lib/workers/repository/process/extract-update.spec.ts b/lib/workers/repository/process/extract-update.spec.ts index 7124d1c2d679086a44299c637001a0a31d245994..fe44bf28e7b38327c876a21327c677fd82828630 100644 --- a/lib/workers/repository/process/extract-update.spec.ts +++ b/lib/workers/repository/process/extract-update.spec.ts @@ -10,7 +10,7 @@ jest.mock('../extract'); const branchify = mocked(_branchify); -branchify.branchifyUpgrades.mockReturnValueOnce({ +branchify.branchifyUpgrades.mockResolvedValueOnce({ branches: [], branchList: [], }); diff --git a/lib/workers/repository/process/extract-update.ts b/lib/workers/repository/process/extract-update.ts index a53c71665aa2a43029354fd75821a1d926ec3911..5e258e56f3f37fd6776c70dca1fa74dcd792c5fb 100644 --- a/lib/workers/repository/process/extract-update.ts +++ b/lib/workers/repository/process/extract-update.ts @@ -25,7 +25,10 @@ export async function extractAndUpdate( await fetchUpdates(config, packageFiles); logger.debug({ config: packageFiles }, 'packageFiles with updates'); await raiseDeprecationWarnings(config, packageFiles); - const { branches, branchList } = branchifyUpgrades(config, packageFiles); + const { branches, branchList } = await branchifyUpgrades( + config, + packageFiles + ); sortBranches(branches); let res: WriteUpdateResult | undefined; // istanbul ignore else diff --git a/lib/workers/repository/process/fetch.ts b/lib/workers/repository/process/fetch.ts index bb445a933c0072d90331716011090dde4a67a194..d4b9aa11bad31966f173f1b444d08635a2041caf 100644 --- a/lib/workers/repository/process/fetch.ts +++ b/lib/workers/repository/process/fetch.ts @@ -75,7 +75,6 @@ async function fetchDepUpdates( currentValue, updates: dep.updates, }); - logger.debug({ packageFile, depName }, 'fetchDepUpdates finished'); } /* eslint-enable no-param-reassign */ } diff --git a/lib/workers/repository/updates/branchify.spec.ts b/lib/workers/repository/updates/branchify.spec.ts index cdcdd58ac76ed21c868072d41a7e41ca023c9700..dd793fee8a9ee288fa08806940d9d566308089d5 100644 --- a/lib/workers/repository/updates/branchify.spec.ts +++ b/lib/workers/repository/updates/branchify.spec.ts @@ -16,13 +16,13 @@ beforeEach(() => { describe('workers/repository/updates/branchify', () => { describe('branchifyUpgrades()', () => { - it('returns empty', () => { - flattenUpdates.mockReturnValueOnce([]); - const res = branchifyUpgrades(config, {}); + it('returns empty', async () => { + flattenUpdates.mockResolvedValueOnce([]); + const res = await branchifyUpgrades(config, {}); expect(res.branches).toEqual([]); }); - it('returns one branch if one input', () => { - flattenUpdates.mockReturnValueOnce([ + it('returns one branch if one input', async () => { + flattenUpdates.mockResolvedValueOnce([ { depName: 'foo', branchName: 'foo-{{version}}', @@ -32,13 +32,13 @@ describe('workers/repository/updates/branchify', () => { }, ]); config.repoIsOnboarded = true; - const res = 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); }); - it('uses major/minor/patch slugs', () => { - flattenUpdates.mockReturnValueOnce([ + it('uses major/minor/patch slugs', async () => { + flattenUpdates.mockResolvedValueOnce([ { depName: 'foo', branchName: 'foo-{{version}}', @@ -85,7 +85,7 @@ describe('workers/repository/updates/branchify', () => { }, ]); config.repoIsOnboarded = true; - const res = 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`); @@ -96,8 +96,8 @@ describe('workers/repository/updates/branchify', () => { expect(res.branches[3].isMajor).toBe(true); expect(res.branches[3].groupSlug).toBe(`major-2-other-packages`); }); - it('does not group if different compiled branch names', () => { - flattenUpdates.mockReturnValueOnce([ + it('does not group if different compiled branch names', async () => { + flattenUpdates.mockResolvedValueOnce([ { depName: 'foo', branchName: 'foo-{{version}}', @@ -117,11 +117,11 @@ describe('workers/repository/updates/branchify', () => { prTitle: 'some-title', }, ]); - const res = branchifyUpgrades(config, {}); + const res = await branchifyUpgrades(config, {}); expect(Object.keys(res.branches)).toHaveLength(3); }); - it('groups if same compiled branch names', () => { - flattenUpdates.mockReturnValueOnce([ + it('groups if same compiled branch names', async () => { + flattenUpdates.mockResolvedValueOnce([ { depName: 'foo', branchName: 'foo', @@ -141,11 +141,11 @@ describe('workers/repository/updates/branchify', () => { prTitle: 'some-title', }, ]); - const res = branchifyUpgrades(config, {}); + const res = await branchifyUpgrades(config, {}); expect(Object.keys(res.branches)).toHaveLength(2); }); - it('groups if same compiled group name', () => { - flattenUpdates.mockReturnValueOnce([ + it('groups if same compiled group name', async () => { + flattenUpdates.mockResolvedValueOnce([ { depName: 'foo', branchName: 'foo', @@ -169,10 +169,10 @@ describe('workers/repository/updates/branchify', () => { group: { branchName: 'renovate/my-group' }, }, ]); - const res = branchifyUpgrades(config, {}); + const res = await branchifyUpgrades(config, {}); expect(Object.keys(res.branches)).toHaveLength(2); }); - it('enforces valid git branch name', () => { + it('enforces valid git branch name', async () => { const fixtures = [ { upgrade: { @@ -232,11 +232,11 @@ describe('workers/repository/updates/branchify', () => { expectedBranchName: 'renovate/bad-branch-name9', }, ]; - flattenUpdates.mockReturnValueOnce( + flattenUpdates.mockResolvedValueOnce( fixtures.map(({ upgrade }) => upgrade) ); - branchifyUpgrades(config, {}).branches.forEach( + (await branchifyUpgrades(config, {})).branches.forEach( ({ branchName }, index: number) => { expect(branchName).toBe(fixtures[index].expectedBranchName); } diff --git a/lib/workers/repository/updates/branchify.ts b/lib/workers/repository/updates/branchify.ts index ef6b4cd741e570eab4ec81774663150d497e28bc..e599dfacadd75254ee331a9ee9e1a03b6f813b83 100644 --- a/lib/workers/repository/updates/branchify.ts +++ b/lib/workers/repository/updates/branchify.ts @@ -30,12 +30,12 @@ export type BranchifiedConfig = Merge< branchList: string[]; } >; -export function branchifyUpgrades( +export async function branchifyUpgrades( config: RenovateConfig, packageFiles: Record<string, any[]> -): BranchifiedConfig { +): Promise<BranchifiedConfig> { logger.debug('branchifyUpgrades'); - const updates = flattenUpdates(config, packageFiles); + const updates = await flattenUpdates(config, packageFiles); logger.debug( `${updates.length} flattened updates found: ${updates .map(u => u.depName) diff --git a/lib/workers/repository/updates/flatten.spec.ts b/lib/workers/repository/updates/flatten.spec.ts index dbd222c33b6734562691c59afd70d8a1172b0de7..a75a12a83ef02e13fa86d7b4ee30b49aa1b984ae 100644 --- a/lib/workers/repository/updates/flatten.spec.ts +++ b/lib/workers/repository/updates/flatten.spec.ts @@ -13,7 +13,7 @@ beforeEach(() => { describe('workers/repository/updates/flatten', () => { describe('flattenUpdates()', () => { - it('flattens', () => { + it('flattens', async () => { config.lockFileMaintenance.enabled = true; config.packageRules = [ { @@ -72,7 +72,7 @@ describe('workers/repository/updates/flatten', () => { }, ], }; - const res = flattenUpdates(config, packageFiles); + const res = await flattenUpdates(config, packageFiles); expect(res).toHaveLength(9); expect( res.filter(r => r.updateType === 'lockFileMaintenance') diff --git a/lib/workers/repository/updates/flatten.ts b/lib/workers/repository/updates/flatten.ts index 79258d50c89e3d9ec15c5f8515b5c640544d2dfd..7356951751b06b8c14c9200e768aa5dbe2784652 100644 --- a/lib/workers/repository/updates/flatten.ts +++ b/lib/workers/repository/updates/flatten.ts @@ -9,16 +9,17 @@ import { import { applyPackageRules } from '../../../util/package-rules'; import { get } from '../../../manager'; import { LANGUAGE_DOCKER } from '../../../constants/languages'; +import { getDefaultConfig } from '../../../datasource'; // Return only rules that contain an updateType function getUpdateTypeRules(packageRules: PackageRule[]): PackageRule[] { return packageRules.filter(rule => is.nonEmptyArray(rule.updateTypes)); } -export function flattenUpdates( +export async function flattenUpdates( config: RenovateConfig, packageFiles: Record<string, any[]> -): RenovateConfig[] { +): Promise<RenovateConfig[]> { const updates = []; const updateTypes = [ 'major', @@ -39,6 +40,11 @@ export function flattenUpdates( for (const update of dep.updates) { let updateConfig = mergeChildConfig(depConfig, update); delete updateConfig.updates; + // apply config from datasource + const datasourceConfig = await getDefaultConfig( + depConfig.datasource + ); + updateConfig = mergeChildConfig(updateConfig, datasourceConfig); updateConfig = applyPackageRules(updateConfig); // Keep only rules that haven't been applied yet (with updateTypes) updateConfig.packageRules = getUpdateTypeRules(