mirror of https://github.com/renovatebot/renovate
423 lines
14 KiB
TypeScript
423 lines
14 KiB
TypeScript
import type { RequiredConfig } from '../../../../config/types';
|
|
import { logger } from '../../../../logger';
|
|
import * as env from './env';
|
|
import type { ParseConfigOptions } from './types';
|
|
|
|
describe('workers/global/config/parse/env', () => {
|
|
describe('.getConfig(env)', () => {
|
|
it('returns empty env', async () => {
|
|
expect(await env.getConfig({})).toEqual({ hostRules: [] });
|
|
});
|
|
|
|
it('supports boolean true', async () => {
|
|
const envParam: NodeJS.ProcessEnv = { RENOVATE_CONFIG_MIGRATION: 'true' };
|
|
expect((await env.getConfig(envParam)).configMigration).toBeTrue();
|
|
});
|
|
|
|
it('supports boolean false', async () => {
|
|
const envParam: NodeJS.ProcessEnv = {
|
|
RENOVATE_CONFIG_MIGRATION: 'false',
|
|
};
|
|
expect((await env.getConfig(envParam)).configMigration).toBeFalse();
|
|
});
|
|
|
|
it('throws exception for invalid boolean value', async () => {
|
|
const envParam: NodeJS.ProcessEnv = {
|
|
RENOVATE_CONFIG_MIGRATION: 'badvalue',
|
|
};
|
|
await expect(env.getConfig(envParam)).rejects.toThrow(
|
|
Error(
|
|
"Invalid boolean value: expected 'true' or 'false', but got 'badvalue'",
|
|
),
|
|
);
|
|
});
|
|
|
|
delete process.env.RENOVATE_CONFIG_MIGRATION;
|
|
|
|
it('supports list single', async () => {
|
|
const envParam: NodeJS.ProcessEnv = { RENOVATE_LABELS: 'a' };
|
|
expect((await env.getConfig(envParam)).labels).toEqual(['a']);
|
|
});
|
|
|
|
it('supports list multiple', async () => {
|
|
const envParam: NodeJS.ProcessEnv = { RENOVATE_LABELS: 'a,b,c' };
|
|
expect((await env.getConfig(envParam)).labels).toEqual(['a', 'b', 'c']);
|
|
});
|
|
|
|
it('supports list multiple without blank items', async () => {
|
|
const envParam: NodeJS.ProcessEnv = { RENOVATE_LABELS: 'a,b,c,' };
|
|
expect((await env.getConfig(envParam)).labels).toEqual(['a', 'b', 'c']);
|
|
});
|
|
|
|
it('supports string', async () => {
|
|
const envParam: NodeJS.ProcessEnv = { RENOVATE_TOKEN: 'a' };
|
|
expect((await env.getConfig(envParam)).token).toBe('a');
|
|
});
|
|
|
|
it('coerces string newlines', async () => {
|
|
const envParam: NodeJS.ProcessEnv = {
|
|
RENOVATE_GIT_PRIVATE_KEY: 'abc\\ndef',
|
|
};
|
|
expect((await env.getConfig(envParam)).gitPrivateKey).toBe('abc\ndef');
|
|
});
|
|
|
|
it('supports custom prefixes', async () => {
|
|
const envParam: NodeJS.ProcessEnv = {
|
|
ENV_PREFIX: 'FOOBAR_',
|
|
FOOBAR_TOKEN: 'abc',
|
|
};
|
|
const res = await env.getConfig(envParam);
|
|
expect(res).toMatchObject({ token: 'abc' });
|
|
});
|
|
|
|
it('supports json', async () => {
|
|
const envParam: NodeJS.ProcessEnv = {
|
|
RENOVATE_LOCK_FILE_MAINTENANCE: '{}',
|
|
};
|
|
expect((await env.getConfig(envParam)).lockFileMaintenance).toEqual({});
|
|
});
|
|
|
|
it('supports arrays of objects', async () => {
|
|
const envParam: NodeJS.ProcessEnv = {
|
|
RENOVATE_HOST_RULES: JSON.stringify([{ foo: 'bar' }]),
|
|
};
|
|
const res = await env.getConfig(envParam);
|
|
expect(res).toMatchObject({ hostRules: [{ foo: 'bar' }] });
|
|
});
|
|
|
|
test.each`
|
|
envArg | config
|
|
${{ RENOVATE_RECREATE_CLOSED: 'true' }} | ${{ recreateWhen: 'always' }}
|
|
${{ RENOVATE_RECREATE_CLOSED: 'false' }} | ${{ recreateWhen: 'auto' }}
|
|
${{ RENOVATE_RECREATE_WHEN: 'auto' }} | ${{ recreateWhen: 'auto' }}
|
|
${{ RENOVATE_RECREATE_WHEN: 'always' }} | ${{ recreateWhen: 'always' }}
|
|
${{ RENOVATE_RECREATE_WHEN: 'never' }} | ${{ recreateWhen: 'never' }}
|
|
`('"$envArg" -> $config', async ({ envArg, config }) => {
|
|
expect(await env.getConfig(envArg)).toMatchObject(config);
|
|
});
|
|
|
|
it('skips misconfigured arrays', async () => {
|
|
const envName = 'RENOVATE_HOST_RULES';
|
|
const val = JSON.stringify('foobar');
|
|
const envParam: NodeJS.ProcessEnv = { [envName]: val };
|
|
|
|
const res = await env.getConfig(envParam);
|
|
|
|
expect(res).toEqual({ hostRules: [] });
|
|
expect(logger.debug).toHaveBeenLastCalledWith(
|
|
{ val, envName },
|
|
'Could not parse object array',
|
|
);
|
|
});
|
|
|
|
it('skips garbage array values', async () => {
|
|
const envName = 'RENOVATE_HOST_RULES';
|
|
const val = '!@#';
|
|
const envParam: NodeJS.ProcessEnv = { [envName]: val };
|
|
|
|
const res = await env.getConfig(envParam);
|
|
|
|
expect(res).toEqual({ hostRules: [] });
|
|
expect(logger.debug).toHaveBeenLastCalledWith(
|
|
{ val, envName },
|
|
'Could not parse environment variable',
|
|
);
|
|
});
|
|
|
|
it('supports GitHub token', async () => {
|
|
const envParam: NodeJS.ProcessEnv = {
|
|
RENOVATE_TOKEN: 'github.com token',
|
|
};
|
|
expect(await env.getConfig(envParam)).toMatchSnapshot({
|
|
token: 'github.com token',
|
|
});
|
|
});
|
|
|
|
it('supports GitHub custom endpoint', async () => {
|
|
const envParam: NodeJS.ProcessEnv = {
|
|
RENOVATE_ENDPOINT: 'a ghe endpoint',
|
|
};
|
|
expect(await env.getConfig(envParam)).toMatchSnapshot({
|
|
endpoint: 'a ghe endpoint',
|
|
});
|
|
});
|
|
|
|
it('supports GitHub custom endpoint and github.com', async () => {
|
|
const envParam: NodeJS.ProcessEnv = {
|
|
GITHUB_COM_TOKEN: 'a github.com token',
|
|
RENOVATE_ENDPOINT: 'a ghe endpoint',
|
|
RENOVATE_TOKEN: 'a ghe token',
|
|
};
|
|
expect(await env.getConfig(envParam)).toMatchSnapshot({
|
|
endpoint: 'a ghe endpoint',
|
|
hostRules: [
|
|
{
|
|
hostType: 'github',
|
|
matchHost: 'github.com',
|
|
token: 'a github.com token',
|
|
},
|
|
],
|
|
token: 'a ghe token',
|
|
});
|
|
});
|
|
|
|
it('supports GitHub fine-grained PATs', async () => {
|
|
const envParam: NodeJS.ProcessEnv = {
|
|
GITHUB_COM_TOKEN: 'github_pat_XXXXXX',
|
|
RENOVATE_TOKEN: 'a github.com token',
|
|
};
|
|
expect(await env.getConfig(envParam)).toEqual({
|
|
token: 'a github.com token',
|
|
hostRules: [
|
|
{
|
|
hostType: 'github',
|
|
matchHost: 'github.com',
|
|
token: 'github_pat_XXXXXX',
|
|
},
|
|
],
|
|
});
|
|
});
|
|
|
|
it('supports GitHub custom endpoint and gitlab.com', async () => {
|
|
const envParam: NodeJS.ProcessEnv = {
|
|
RENOVATE_ENDPOINT: 'a ghe endpoint',
|
|
RENOVATE_TOKEN: 'a ghe token',
|
|
};
|
|
expect(await env.getConfig(envParam)).toMatchSnapshot({
|
|
endpoint: 'a ghe endpoint',
|
|
token: 'a ghe token',
|
|
});
|
|
});
|
|
|
|
it('supports GitLab token', async () => {
|
|
const envParam: NodeJS.ProcessEnv = {
|
|
RENOVATE_PLATFORM: 'gitlab',
|
|
RENOVATE_TOKEN: 'a gitlab.com token',
|
|
};
|
|
expect(await env.getConfig(envParam)).toMatchSnapshot({
|
|
platform: 'gitlab',
|
|
token: 'a gitlab.com token',
|
|
});
|
|
});
|
|
|
|
it('supports GitLab custom endpoint', async () => {
|
|
const envParam: NodeJS.ProcessEnv = {
|
|
RENOVATE_PLATFORM: 'gitlab',
|
|
RENOVATE_TOKEN: 'a gitlab token',
|
|
RENOVATE_ENDPOINT: 'a gitlab endpoint',
|
|
};
|
|
expect(await env.getConfig(envParam)).toMatchSnapshot({
|
|
endpoint: 'a gitlab endpoint',
|
|
platform: 'gitlab',
|
|
token: 'a gitlab token',
|
|
});
|
|
});
|
|
|
|
it('supports Azure DevOps', async () => {
|
|
const envParam: NodeJS.ProcessEnv = {
|
|
RENOVATE_PLATFORM: 'azure',
|
|
RENOVATE_TOKEN: 'an Azure DevOps token',
|
|
RENOVATE_ENDPOINT: 'an Azure DevOps endpoint',
|
|
};
|
|
expect(await env.getConfig(envParam)).toMatchSnapshot({
|
|
endpoint: 'an Azure DevOps endpoint',
|
|
platform: 'azure',
|
|
token: 'an Azure DevOps token',
|
|
});
|
|
});
|
|
|
|
it('supports Bitbucket token', async () => {
|
|
const envParam: NodeJS.ProcessEnv = {
|
|
RENOVATE_PLATFORM: 'bitbucket',
|
|
RENOVATE_ENDPOINT: 'a bitbucket endpoint',
|
|
RENOVATE_USERNAME: 'some-username',
|
|
RENOVATE_PASSWORD: 'app-password',
|
|
};
|
|
expect(await env.getConfig(envParam)).toMatchSnapshot({
|
|
platform: 'bitbucket',
|
|
endpoint: 'a bitbucket endpoint',
|
|
username: 'some-username',
|
|
password: 'app-password',
|
|
});
|
|
});
|
|
|
|
it('supports Bitbucket username/password', async () => {
|
|
const envParam: NodeJS.ProcessEnv = {
|
|
RENOVATE_PLATFORM: 'bitbucket',
|
|
RENOVATE_ENDPOINT: 'a bitbucket endpoint',
|
|
RENOVATE_USERNAME: 'some-username',
|
|
RENOVATE_PASSWORD: 'app-password',
|
|
};
|
|
expect(await env.getConfig(envParam)).toMatchSnapshot({
|
|
endpoint: 'a bitbucket endpoint',
|
|
hostRules: [],
|
|
password: 'app-password',
|
|
platform: 'bitbucket',
|
|
username: 'some-username',
|
|
});
|
|
});
|
|
|
|
it('merges full config from env', async () => {
|
|
const envParam: NodeJS.ProcessEnv = {
|
|
RENOVATE_CONFIG: '{"enabled":false,"token":"foo"}',
|
|
RENOVATE_TOKEN: 'a',
|
|
};
|
|
const config = await env.getConfig(envParam);
|
|
expect(config.enabled).toBeFalse();
|
|
expect(config.token).toBe('a');
|
|
});
|
|
|
|
it('massages converted experimental env vars', async () => {
|
|
const envParam: NodeJS.ProcessEnv = {
|
|
RENOVATE_X_MERGE_CONFIDENCE_API_BASE_URL: 'some-url', // converted
|
|
RENOVATE_X_MERGE_CONFIDENCE_SUPPORTED_DATASOURCES: '["docker"]', // converted
|
|
RENOVATE_X_AUTODISCOVER_REPO_SORT: 'alpha',
|
|
RENOVATE_X_DOCKER_MAX_PAGES: '10',
|
|
RENOVATE_AUTODISCOVER_REPO_ORDER: 'desc',
|
|
RENOVATE_X_DELETE_CONFIG_FILE: 'true',
|
|
RENOVATE_X_S3_ENDPOINT: 'endpoint',
|
|
RENOVATE_X_S3_PATH_STYLE: 'true',
|
|
};
|
|
const config = await env.getConfig(envParam);
|
|
expect(config).toMatchObject({
|
|
mergeConfidenceEndpoint: 'some-url',
|
|
mergeConfidenceDatasources: ['docker'],
|
|
autodiscoverRepoSort: 'alpha',
|
|
autodiscoverRepoOrder: 'desc',
|
|
dockerMaxPages: 10,
|
|
deleteConfigFile: true,
|
|
s3Endpoint: 'endpoint',
|
|
s3PathStyle: true,
|
|
});
|
|
});
|
|
|
|
describe('RENOVATE_CONFIG tests', () => {
|
|
let processExit: jest.SpyInstance<never, [code?: number]>;
|
|
|
|
beforeAll(() => {
|
|
processExit = jest
|
|
.spyOn(process, 'exit')
|
|
.mockImplementation((async () => {}) as never);
|
|
});
|
|
|
|
afterAll(() => {
|
|
processExit.mockRestore();
|
|
});
|
|
|
|
it('crashes', async () => {
|
|
const envParam: NodeJS.ProcessEnv = { RENOVATE_CONFIG: '!@#' };
|
|
await env.getConfig(envParam);
|
|
expect(processExit).toHaveBeenCalledWith(1);
|
|
});
|
|
|
|
it('migrates RENOVATE_CONFIG', async () => {
|
|
const envParam: NodeJS.ProcessEnv = {
|
|
RENOVATE_CONFIG: '{"automerge":"any","token":"foo"}',
|
|
};
|
|
const config = await env.getConfig(envParam);
|
|
expect(logger.warn).toHaveBeenCalledTimes(1);
|
|
expect(config.automerge).toBeTrue();
|
|
});
|
|
|
|
it('warns if config in RENOVATE_CONFIG is invalid', async () => {
|
|
const envParam: NodeJS.ProcessEnv = {
|
|
RENOVATE_CONFIG: '{"enabled":"invalid-value","prTitle":"something"}',
|
|
};
|
|
await env.getConfig(envParam);
|
|
expect(logger.warn).toHaveBeenCalledTimes(2);
|
|
});
|
|
});
|
|
|
|
describe('migrations', () => {
|
|
it('renames migrated variables', async () => {
|
|
const envParam: NodeJS.ProcessEnv = {
|
|
RENOVATE_GIT_LAB_AUTOMERGE: 'true',
|
|
};
|
|
const config = await env.getConfig(envParam);
|
|
expect(config.platformAutomerge).toBe(true);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('.getEnvName(definition)', () => {
|
|
it('returns empty', () => {
|
|
const option: ParseConfigOptions = {
|
|
name: 'foo',
|
|
env: false,
|
|
};
|
|
expect(env.getEnvName(option)).toBe('');
|
|
});
|
|
|
|
it('returns existing env', () => {
|
|
const option: ParseConfigOptions = {
|
|
name: 'foo',
|
|
env: 'FOO',
|
|
};
|
|
expect(env.getEnvName(option)).toBe('FOO');
|
|
});
|
|
|
|
it('generates RENOVATE_ env', () => {
|
|
const option: ParseConfigOptions = {
|
|
name: 'oneTwoThree',
|
|
};
|
|
expect(env.getEnvName(option)).toBe('RENOVATE_ONE_TWO_THREE');
|
|
});
|
|
|
|
it('dryRun boolean true', async () => {
|
|
const envParam: NodeJS.ProcessEnv = {
|
|
RENOVATE_DRY_RUN: 'true',
|
|
};
|
|
const config = await env.getConfig(envParam);
|
|
expect(config.dryRun).toBe('full');
|
|
});
|
|
|
|
it('dryRun boolean false', async () => {
|
|
const envParam: NodeJS.ProcessEnv = {
|
|
RENOVATE_DRY_RUN: 'false',
|
|
};
|
|
const config = await env.getConfig(envParam);
|
|
expect(config.dryRun).toBeUndefined();
|
|
});
|
|
|
|
it('dryRun null', async () => {
|
|
const envParam: NodeJS.ProcessEnv = {
|
|
RENOVATE_DRY_RUN: 'null',
|
|
};
|
|
const config = await env.getConfig(envParam);
|
|
expect(config.dryRun).toBeUndefined();
|
|
});
|
|
|
|
it('requireConfig boolean true', async () => {
|
|
const envParam: NodeJS.ProcessEnv = {
|
|
RENOVATE_REQUIRE_CONFIG: 'true' as RequiredConfig,
|
|
};
|
|
const config = await env.getConfig(envParam);
|
|
expect(config.requireConfig).toBe('required');
|
|
});
|
|
|
|
it('requireConfig boolean false', async () => {
|
|
const envParam: NodeJS.ProcessEnv = {
|
|
RENOVATE_REQUIRE_CONFIG: 'false' as RequiredConfig,
|
|
};
|
|
const config = await env.getConfig(envParam);
|
|
expect(config.requireConfig).toBe('optional');
|
|
});
|
|
|
|
it('platformCommit boolean true', async () => {
|
|
const envParam: NodeJS.ProcessEnv = {
|
|
RENOVATE_PLATFORM_COMMIT: 'true',
|
|
};
|
|
const config = await env.getConfig(envParam);
|
|
expect(config.platformCommit).toBe('enabled');
|
|
});
|
|
|
|
it('platformCommit boolean false', async () => {
|
|
const envParam: NodeJS.ProcessEnv = {
|
|
RENOVATE_PLATFORM_COMMIT: 'false',
|
|
};
|
|
const config = await env.getConfig(envParam);
|
|
expect(config.platformCommit).toBe('disabled');
|
|
});
|
|
});
|
|
});
|