diff --git a/lib/config/__snapshots__/secrets.spec.ts.snap b/lib/config/__snapshots__/secrets.spec.ts.snap deleted file mode 100644 index 14cd2abd4cb19eb0cdcd6c975683fee036b75740..0000000000000000000000000000000000000000 --- a/lib/config/__snapshots__/secrets.spec.ts.snap +++ /dev/null @@ -1,34 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`config/secrets applySecretsToConfig(config) replaces secrets in a array of objects 1`] = ` -Object { - "hostRules": Array [ - Object { - "hostType": "npm", - "token": "123test==", - }, - ], -} -`; - -exports[`config/secrets applySecretsToConfig(config) replaces secrets in a array of strings 1`] = ` -Object { - "allowedManagers": Array [ - "npm", - ], -} -`; - -exports[`config/secrets applySecretsToConfig(config) replaces secrets in a subobject 1`] = ` -Object { - "npm": Object { - "npmToken": "123test==", - }, -} -`; - -exports[`config/secrets applySecretsToConfig(config) replaces secrets in the top level 1`] = ` -Object { - "npmToken": "123test==", -} -`; diff --git a/lib/config/secrets.spec.ts b/lib/config/secrets.spec.ts index c8f32025b34125a831558dc18e5e8d70d6583c76..9bd740a3e825ecc21acc98434931e2b75f949d7f 100644 --- a/lib/config/secrets.spec.ts +++ b/lib/config/secrets.spec.ts @@ -65,7 +65,9 @@ describe('config/secrets', () => { npmToken: '{{ secrets.ARTIFACTORY_TOKEN }}', }; const res = applySecretsToConfig(config); - expect(res).toMatchSnapshot(); + expect(res).toStrictEqual({ + npmToken: '123test==', + }); expect(Object.keys(res)).not.toContain('secrets'); }); it('replaces secrets in a subobject', () => { @@ -74,7 +76,11 @@ describe('config/secrets', () => { npm: { npmToken: '{{ secrets.ARTIFACTORY_TOKEN }}' }, }; const res = applySecretsToConfig(config); - expect(res).toMatchSnapshot(); + expect(res).toStrictEqual({ + npm: { + npmToken: '123test==', + }, + }); expect(Object.keys(res)).not.toContain('secrets'); }); it('replaces secrets in a array of objects', () => { @@ -85,7 +91,9 @@ describe('config/secrets', () => { ], }; const res = applySecretsToConfig(config); - expect(res).toMatchSnapshot(); + expect(res).toStrictEqual({ + hostRules: [{ hostType: 'npm', token: '123test==' }], + }); expect(Object.keys(res)).not.toContain('secrets'); }); it('replaces secrets in a array of strings', () => { @@ -94,8 +102,36 @@ describe('config/secrets', () => { allowedManagers: ['{{ secrets.SECRET_MANAGER }}'], }; const res = applySecretsToConfig(config); - expect(res).toMatchSnapshot(); + expect(res).toStrictEqual({ + allowedManagers: ['npm'], + }); expect(Object.keys(res)).not.toContain('secrets'); }); + it('replaces secrets in a array of objects without deleting them', () => { + const config = { + secrets: { ARTIFACTORY_TOKEN: '123test==' }, + hostRules: [ + { hostType: 'npm', token: '{{ secrets.ARTIFACTORY_TOKEN }}' }, + ], + }; + const res = applySecretsToConfig(config, config.secrets, false); + expect(res).toStrictEqual({ + secrets: { ARTIFACTORY_TOKEN: '123test==' }, + hostRules: [{ hostType: 'npm', token: '123test==' }], + }); + expect(Object.keys(res)).toContain('secrets'); + }); + it('replaces secrets in a array of strings without deleting them', () => { + const config = { + secrets: { SECRET_MANAGER: 'npm' }, + allowedManagers: ['{{ secrets.SECRET_MANAGER }}'], + }; + const res = applySecretsToConfig(config, config.secrets, false); + expect(res).toStrictEqual({ + secrets: { SECRET_MANAGER: 'npm' }, + allowedManagers: ['npm'], + }); + expect(Object.keys(res)).toContain('secrets'); + }); }); }); diff --git a/lib/config/secrets.ts b/lib/config/secrets.ts index 4f1b1ab8ce32cc8f04977c4db142f839eed9bf0d..bbdc6d14ce6378ef35c6ae78f9e82e124d26c8dc 100644 --- a/lib/config/secrets.ts +++ b/lib/config/secrets.ts @@ -70,7 +70,7 @@ function replaceSecretsInString( throw error; } return value.replace(secretTemplateRegex, (_, secretName) => { - if (secrets[secretName]) { + if (secrets?.[secretName]) { return secrets[secretName]; } const error = new Error(CONFIG_VALIDATION); @@ -85,13 +85,16 @@ function replaceSecretsInString( function replaceSecretsinObject( config_: RenovateConfig, - secrets: Record<string, string> = {} + secrets: Record<string, string>, + deleteSecrets: boolean ): RenovateConfig { const config = { ...config_ }; - delete config.secrets; + if (deleteSecrets) { + delete config.secrets; + } for (const [key, value] of Object.entries(config)) { if (is.plainObject(value)) { - config[key] = replaceSecretsinObject(value, secrets); + config[key] = replaceSecretsinObject(value, secrets, deleteSecrets); } if (is.string(value)) { config[key] = replaceSecretsInString(key, value, secrets); @@ -99,7 +102,11 @@ function replaceSecretsinObject( if (is.array(value)) { for (const [arrayIndex, arrayItem] of value.entries()) { if (is.plainObject(arrayItem)) { - config[key][arrayIndex] = replaceSecretsinObject(arrayItem, secrets); + config[key][arrayIndex] = replaceSecretsinObject( + arrayItem, + secrets, + deleteSecrets + ); } else if (is.string(arrayItem)) { config[key][arrayIndex] = replaceSecretsInString( key, @@ -115,7 +122,8 @@ function replaceSecretsinObject( export function applySecretsToConfig( config: RenovateConfig, - secrets = config.secrets + secrets = config.secrets, + deleteSecrets = true ): RenovateConfig { // Add all secrets to be sanitized if (is.plainObject(secrets)) { @@ -123,5 +131,5 @@ export function applySecretsToConfig( addSecretForSanitizing(String(secret)); } } - return replaceSecretsinObject(config, secrets); + return replaceSecretsinObject(config, secrets, deleteSecrets); } diff --git a/lib/workers/repository/index.ts b/lib/workers/repository/index.ts index 0abc138df41f0a3faf6c057a69a1b8f2bc6f0ec3..24520140577c9681d99aa50b19fe202edaee4ba4 100644 --- a/lib/workers/repository/index.ts +++ b/lib/workers/repository/index.ts @@ -1,5 +1,6 @@ import fs from 'fs-extra'; import { GlobalConfig } from '../../config/global'; +import { applySecretsToConfig } from '../../config/secrets'; import type { RenovateConfig } from '../../config/types'; import { pkg } from '../../expose.cjs'; import { logger, setMeta } from '../../logger'; @@ -23,7 +24,7 @@ export async function renovateRepository( canRetry = true ): Promise<ProcessResult> { splitInit(); - let config = GlobalConfig.set(repoConfig); + let config = GlobalConfig.set(applySecretsToConfig(repoConfig, {}, false)); await removeDanglingContainers(); setMeta({ repository: config.repository }); logger.info({ renovateVersion: pkg.version }, 'Repository started');