diff --git a/docs/usage/self-hosted-configuration.md b/docs/usage/self-hosted-configuration.md index 339805bbc3693f79e4409c9c3d6866d1d9d7defb..279077a95f833397ef88d4959456afaf07de23ca 100644 --- a/docs/usage/self-hosted-configuration.md +++ b/docs/usage/self-hosted-configuration.md @@ -487,3 +487,13 @@ This is currently applicable to `npm` and `lerna`/`npm` only, and only used in c ## username Mandatory if a GitHub app token is in use using the CLI. + +## writeDiscoveredRepos + +Optional parameter which allows to write the discovered repositories into a JSON file instead of renovating them. + +Usage: `renovate --write-discovered-repos=/tmp/renovate-repos.json` + +```json +["myOrg/myRepo", "myOrg/anotherRepo"] +``` diff --git a/lib/config/options/index.ts b/lib/config/options/index.ts index 622c0439077de4088b4ddfd1214447b8a43d6539..7a757b04d8cec1f986b72716fdf8e05e0cabf8a3 100644 --- a/lib/config/options/index.ts +++ b/lib/config/options/index.ts @@ -2051,6 +2051,13 @@ const options: RenovateOptions[] = [ stage: 'repository', globalOnly: true, }, + { + name: 'writeDiscoveredRepos', + description: 'Writes discovered repositories to a JSON file and then exit.', + type: 'string', + globalOnly: true, + env: false, + }, ]; export function getOptions(): RenovateOptions[] { diff --git a/lib/workers/global/index.spec.ts b/lib/workers/global/index.spec.ts index 988d2b352e10816051e5bf13e0a7cdc83d1fd772..13d93bcba47971b61c51e666f46a713a8c0b26fb 100644 --- a/lib/workers/global/index.spec.ts +++ b/lib/workers/global/index.spec.ts @@ -1,5 +1,6 @@ +import { expect } from '@jest/globals'; import { ERROR, WARN } from 'bunyan'; -import { logger } from '../../../test/util'; +import { fs, logger } from '../../../test/util'; import { PLATFORM_TYPE_GITHUB, PLATFORM_TYPE_GITLAB, @@ -12,6 +13,7 @@ import * as _limits from './limits'; import * as globalWorker from '.'; jest.mock('../repository'); +jest.mock('../../util/fs'); // imports are readonly const repositoryWorker = _repositoryWorker; @@ -130,4 +132,25 @@ describe('workers/global/index', () => { expect(repositoryWorker.renovateRepository).toHaveBeenCalledTimes(1); }); }); + + describe('write repositories to file', () => { + it('successfully write file', async () => { + configParser.parseConfigs.mockResolvedValueOnce({ + repositories: ['myOrg/myRepo'], + platform: PLATFORM_TYPE_GITHUB, + endpoint: 'https://github.com/', + writeDiscoveredRepos: '/tmp/renovate-output.json', + }); + fs.writeFile.mockReturnValueOnce(null); + + expect(await globalWorker.start()).toEqual(0); + expect(fs.writeFile).toHaveBeenCalledTimes(1); + expect(fs.writeFile).toHaveBeenCalledWith( + '/tmp/renovate-output.json', + '["myOrg/myRepo"]' + ); + expect(configParser.parseConfigs).toHaveBeenCalledTimes(1); + expect(repositoryWorker.renovateRepository).toHaveBeenCalledTimes(0); + }); + }); }); diff --git a/lib/workers/global/index.ts b/lib/workers/global/index.ts index d683f318669cb75bc7fd7f59bb1d8fc671936d5a..2c51a573d4b5b13a4ae594ee8ab9226fb4857f66 100644 --- a/lib/workers/global/index.ts +++ b/lib/workers/global/index.ts @@ -14,6 +14,7 @@ import type { } from '../../config/types'; import { CONFIG_PRESETS_INVALID } from '../../constants/error-messages'; import { getProblems, logger, setMeta } from '../../logger'; +import { writeFile } from '../../util/fs'; import * as hostRules from '../../util/host-rules'; import * as repositoryWorker from '../repository'; import { autodiscoverRepositories } from './autodiscover'; @@ -97,6 +98,16 @@ export async function start(): Promise<number> { // autodiscover repositories (needs to come after platform initialization) config = await autodiscoverRepositories(config); + + if (is.nonEmptyString(config.writeDiscoveredRepos)) { + const content = JSON.stringify(config.repositories); + await writeFile(config.writeDiscoveredRepos, content); + logger.info( + `Written discovered repositories to ${config.writeDiscoveredRepos}` + ); + return 0; + } + // Iterate through repositories sequentially for (const repository of config.repositories) { if (haveReachedLimits()) {