Files
renovate/lib/config/secrets.ts
Sebastian Poxhofer c32e2391a0 refactor(linters): add prefer-coerce-object rule (#45493)
Refs #45216

The object counterpart to `prefer-coerce-array`: `x ?? {}` becomes
`coerceObject(x)`. The rule flags a `??` whose default is a bare `{}`
literal, so a populated default or an asserted `({} as Foo)` still
passes; a `x ?? y ?? {}` chain maps onto `coerceObject(x, y)`.

Every hit across `lib/` converted cleanly, so no disable comments were
needed.
2026-08-28 09:27:59 +00:00

93 lines
2.6 KiB
TypeScript

import { isPlainObject } from '@sindresorhus/is';
import type { InterpolatorOptions } from '../util/interpolator.ts';
import {
replaceInterpolatedValuesInObject,
validateInterpolatedValues,
} from '../util/interpolator.ts';
import { coerceObject } from '../util/object.ts';
import { regEx } from '../util/regex.ts';
import { addSecretForSanitizing } from '../util/sanitize.ts';
import type { AllConfig, RenovateConfig } from './types.ts';
const namePattern = '[A-Za-z][A-Za-z0-9_]*';
const nameRegex = regEx(`^${namePattern}$`);
const secretTemplateRegex = regEx(`{{ *secrets\\.(${namePattern}) *}}`, 'g');
const variableTemplateRegex = regEx(
`{{ *variables\\.(${namePattern}) *}}`,
'g',
);
export const options: Record<'secrets' | 'variables', InterpolatorOptions> = {
secrets: {
name: 'secrets',
nameRegex,
templateRegex: secretTemplateRegex,
},
variables: {
name: 'variables',
nameRegex,
templateRegex: variableTemplateRegex,
},
};
function validateNestedInterpolatedValues<T extends 'secrets' | 'variables'>(
config: AllConfig,
key: T,
): void {
validateInterpolatedValues(config[key], options[key]);
if (config.repositories) {
for (const repository of config.repositories) {
if (isPlainObject(repository)) {
validateInterpolatedValues(repository[key], options[key]);
}
}
}
}
export function validateConfigSecretsAndVariables(
config: RenovateConfig,
): void {
validateNestedInterpolatedValues(config, 'secrets');
validateNestedInterpolatedValues(config, 'variables');
}
interface ApplySecretsAndVariablesConfig {
config: RenovateConfig;
secrets?: RenovateConfig['secrets'];
variables?: RenovateConfig['variables'];
deleteSecrets?: boolean;
deleteVariables?: boolean;
}
/**
* Applies both variables and secrets to the Renovate config by interpolating values
*/
export function applySecretsAndVariablesToConfig(
applyConfig: ApplySecretsAndVariablesConfig,
): RenovateConfig {
const { config, deleteSecrets, deleteVariables } = applyConfig;
const secrets = applyConfig.secrets ?? config.secrets;
const variables = applyConfig.variables ?? config.variables;
// Add all secrets to be sanitized
if (isPlainObject(secrets)) {
for (const secret of Object.values(secrets)) {
addSecretForSanitizing(secret);
}
}
const configWithVars = replaceInterpolatedValuesInObject(
config,
coerceObject(variables),
options.variables,
deleteVariables,
);
return replaceInterpolatedValuesInObject(
configWithVars,
coerceObject(secrets),
options.secrets,
deleteSecrets,
);
}