diff --git a/lib/workers/repository/init/__snapshots__/config.spec.ts.snap b/lib/workers/repository/init/__snapshots__/config.spec.ts.snap index 8fc9ed4d12ef63749ea8c6503c432692c6d25600..3b4c400fcd2bd085cf9dd650649efddd2a88c263 100644 --- a/lib/workers/repository/init/__snapshots__/config.spec.ts.snap +++ b/lib/workers/repository/init/__snapshots__/config.spec.ts.snap @@ -1,15 +1,586 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`workers/repository/init/config mergeRenovateConfig() returns error if cannot parse 1`] = `"renovate.json"`; +exports[`workers/repository/init/config detectRepoFileConfig() finds .github/renovate.json 1`] = `Promise {}`; -exports[`workers/repository/init/config mergeRenovateConfig() returns error if cannot parse 2`] = `"Invalid JSON (parsing failed)"`; +exports[`workers/repository/init/config detectRepoFileConfig() finds .gitlab/renovate.json 1`] = `Promise {}`; -exports[`workers/repository/init/config mergeRenovateConfig() returns error if cannot parse 3`] = `"Syntax error near cannot par"`; +exports[`workers/repository/init/config detectRepoFileConfig() finds .renovaterc.json 1`] = `Promise {}`; -exports[`workers/repository/init/config mergeRenovateConfig() throws error if duplicate keys 1`] = `".renovaterc"`; +exports[`workers/repository/init/config detectRepoFileConfig() finds and parse renovate.json5 1`] = `Promise {}`; -exports[`workers/repository/init/config mergeRenovateConfig() throws error if duplicate keys 2`] = `"Duplicate keys in JSON"`; +exports[`workers/repository/init/config detectRepoFileConfig() returns config if not found 1`] = `Promise {}`; -exports[`workers/repository/init/config mergeRenovateConfig() throws error if duplicate keys 3`] = `"\\"Syntax error: duplicated keys \\\\\\"enabled\\\\\\" near \\\\\\": false }\\""`; +exports[`workers/repository/init/config detectRepoFileConfig() returns error if cannot parse 1`] = `Promise {}`; + +exports[`workers/repository/init/config detectRepoFileConfig() throws error if duplicate keys 1`] = `Promise {}`; + +exports[`workers/repository/init/config detectRepoFileConfig() uses package.json config if found 1`] = `Promise {}`; + +exports[`workers/repository/init/config mergeRenovateConfig() continues if no errors 1`] = ` +Object { + "additionalReviewers": Array [], + "aliases": Object {}, + "allowedPostUpgradeCommands": Array [], + "ansible": Object { + "fileMatch": Array [ + "(^|/)tasks/[^/]+\\\\.ya?ml$", + ], + }, + "ansible-galaxy": Object { + "fileMatch": Array [ + "(^|/)requirements\\\\.ya?ml$", + ], + }, + "assignAutomerge": false, + "assignees": Array [], + "assigneesFromCodeOwners": false, + "assigneesSampleSize": null, + "autodiscover": false, + "autodiscoverFilter": null, + "automerge": false, + "automergeComment": "automergeComment", + "automergeType": "pr", + "azureAutoComplete": false, + "azureWorkItemId": 0, + "baseBranches": Array [], + "baseDir": null, + "bazel": Object { + "fileMatch": Array [ + "(^|/)WORKSPACE(|\\\\.bazel)$", + "\\\\.bzl$", + ], + }, + "bbUseDefaultReviewers": true, + "binarySource": "auto", + "branchName": "{{{branchPrefix}}}{{{managerBranchPrefix}}}{{{branchTopic}}}", + "branchPrefix": "renovate/", + "branchTopic": "{{{depNameSanitized}}}-{{{newMajor}}}{{#if isPatch}}.{{{newMinor}}}{{/if}}.x{{#if isLockfileUpdate}}-lockfile{{/if}}", + "buildkite": Object { + "commitMessageExtra": "to {{#if isMajor}}v{{{newMajor}}}{{else}}{{{newValue}}}{{/if}}", + "commitMessageTopic": "buildkite plugin {{depName}}", + "fileMatch": Array [ + "buildkite\\\\.ya?ml", + "\\\\.buildkite/.+\\\\.ya?ml$", + ], + "managerBranchPrefix": "buildkite-", + }, + "bumpVersion": null, + "bundler": Object { + "fileMatch": Array [ + "(^|/)Gemfile$", + ], + "versioning": "ruby", + }, + "cacheDir": null, + "cargo": Object { + "commitMessageTopic": "Rust crate {{depName}}", + "fileMatch": Array [ + "(^|/)Cargo.toml$", + ], + "managerBranchPrefix": "rust-", + "rangeStrategy": "bump", + "versioning": "cargo", + }, + "cdnurl": Object { + "fileMatch": Array [], + "versioning": "semver", + }, + "circleci": Object { + "fileMatch": Array [ + "(^|/).circleci/config.yml$", + ], + }, + "cocoapods": Object { + "fileMatch": Array [ + "(^|/)Podfile$", + ], + "versioning": "ruby", + }, + "commitBody": null, + "commitBodyTable": false, + "commitMessage": "{{{commitMessagePrefix}}} {{{commitMessageAction}}} {{{commitMessageTopic}}} {{{commitMessageExtra}}} {{{commitMessageSuffix}}}", + "commitMessageAction": "Update", + "commitMessageExtra": "to {{#if isMajor}}v{{{newMajor}}}{{else}}{{#if isSingleVersion}}v{{{toVersion}}}{{else}}{{{newValue}}}{{/if}}{{/if}}", + "commitMessagePrefix": null, + "commitMessageSuffix": null, + "commitMessageTopic": "dependency {{depName}}", + "compatibility": Object {}, + "composer": Object { + "fileMatch": Array [ + "(^|/)([\\\\w-]*)composer.json$", + ], + "versioning": "composer", + }, + "composerIgnorePlatformReqs": true, + "configWarningReuseIssue": true, + "dependencyDashboard": false, + "dependencyDashboardApproval": false, + "dependencyDashboardAutoclose": false, + "dependencyDashboardFooter": null, + "dependencyDashboardHeader": "This issue contains a list of Renovate updates and their statuses.", + "dependencyDashboardTitle": "Dependency Dashboard", + "deps-edn": Object { + "fileMatch": Array [ + "(^|/)deps\\\\.edn$", + ], + "versioning": "maven", + }, + "description": Array [], + "digest": Object { + "branchTopic": "{{{depNameSanitized}}}-digest", + "commitMessageExtra": "to {{newDigestShort}}", + "commitMessageTopic": "{{{depName}}} commit hash", + }, + "docker": Object { + "versioning": "docker", + }, + "docker-compose": Object { + "fileMatch": Array [ + "(^|/)docker-compose[^/]*\\\\.ya?ml$", + ], + }, + "dockerMapDotfiles": false, + "dockerUser": null, + "dockerfile": Object { + "fileMatch": Array [ + "(^|/|\\\\.)Dockerfile$", + "(^|/)Dockerfile\\\\.[^/]*$", + ], + }, + "dotnet": Object {}, + "draftPR": false, + "droneci": Object { + "fileMatch": Array [ + "(^|/).drone.yml$", + ], + }, + "dryRun": false, + "enabled": true, + "enabledManagers": Array [], + "encrypted": null, + "endpoint": null, + "errors": Array [], + "excludeCommitPaths": Array [], + "extends": Array [], + "fileMatch": Array [], + "followTag": null, + "force": null, + "forceCli": true, + "forkMode": false, + "git-submodules": Object { + "enabled": false, + "fileMatch": Array [ + "(^|/).gitmodules$", + ], + "versioning": "git", + }, + "gitAuthor": null, + "gitLabAutomerge": false, + "gitPrivateKey": null, + "github-actions": Object { + "fileMatch": Array [ + "^\\\\.github/main.workflow$", + "^\\\\.github/workflows/[^/]+\\\\.ya?ml$", + ], + "pinDigests": true, + }, + "gitlabci": Object { + "fileMatch": Array [ + "^\\\\.gitlab-ci\\\\.yml$", + ], + }, + "gitlabci-include": Object { + "fileMatch": Array [ + "^\\\\.gitlab-ci\\\\.yml$", + ], + }, + "golang": Object { + "commitMessageTopic": "module {{depNameShort}}", + }, + "gomod": Object { + "fileMatch": Array [ + "(^|/)go.mod$", + ], + }, + "gradle": Object { + "fileMatch": Array [ + "\\\\.gradle(\\\\.kts)?$", + "(^|/)gradle.properties$", + ], + "timeout": 600, + "versioning": "gradle", + }, + "gradle-wrapper": Object { + "fileMatch": Array [ + "(^|/)gradle/wrapper/gradle-wrapper.properties$", + ], + "versioning": "gradle", + }, + "group": Object { + "branchTopic": "{{{groupSlug}}}", + "commitMessageTopic": "{{{groupName}}}", + }, + "groupName": null, + "groupSlug": null, + "helm-requirements": Object { + "aliases": Object { + "stable": "https://kubernetes-charts.storage.googleapis.com/", + }, + "commitMessageTopic": "helm chart {{depName}}", + "fileMatch": Array [ + "(^|/)requirements.yaml$", + ], + }, + "helm-values": Object { + "commitMessageTopic": "helm values {{depName}}", + "fileMatch": Array [ + "(^|/)values.yaml$", + ], + "pinDigests": false, + }, + "helmfile": Object { + "aliases": Object { + "stable": "https://kubernetes-charts.storage.googleapis.com/", + }, + "commitMessageTopic": "helm chart {{depName}}", + "fileMatch": Array [ + "(^|/)helmfile.yaml$", + ], + }, + "helmv3": Object { + "aliases": Object { + "stable": "https://kubernetes-charts.storage.googleapis.com/", + }, + "commitMessageTopic": "helm chart {{depName}}", + "fileMatch": Array [ + "(^|/)Chart.yaml$", + ], + }, + "homebrew": Object { + "commitMessageTopic": "Homebrew Formula {{depName}}", + "fileMatch": Array [ + "^Formula/[^/]+[.]rb$", + ], + "managerBranchPrefix": "homebrew-", + }, + "hostRules": Array [ + Object { + "timeout": 60000, + }, + ], + "html": Object { + "digest": Object { + "enabled": false, + }, + "fileMatch": Array [ + "\\\\.html?$", + ], + "pinDigests": false, + "versioning": "semver", + }, + "ignoreDeprecated": true, + "ignoreDeps": Array [], + "ignoreNpmrcFile": false, + "ignorePaths": Array [ + "**/node_modules/**", + "**/bower_components/**", + ], + "ignorePresets": Array [], + "ignoreScripts": false, + "ignoreUnstable": true, + "includeForks": false, + "includePaths": Array [], + "java": Object {}, + "jenkins": Object { + "fileMatch": Array [ + "(^|/)plugins\\\\.txt", + ], + }, + "js": Object {}, + "kubernetes": Object { + "fileMatch": Array [], + }, + "kustomize": Object { + "fileMatch": Array [ + "(^|/)kustomization\\\\.yaml", + ], + }, + "labels": Array [], + "leiningen": Object { + "fileMatch": Array [ + "(^|/)project\\\\.clj$", + ], + "versioning": "maven", + }, + "lockFileMaintenance": Object { + "branchTopic": "lock-file-maintenance", + "commitMessageAction": "Lock file maintenance", + "commitMessageExtra": null, + "commitMessageTopic": null, + "enabled": false, + "groupName": null, + "prBodyDefinitions": Object { + "Change": "All locks refreshed", + }, + "rebaseStalePrs": true, + "recreateClosed": true, + "schedule": Array [ + "before 5am on monday", + ], + }, + "logContext": null, + "logFile": null, + "logFileLevel": "debug", + "logLevel": "info", + "major": Object {}, + "managerBranchPrefix": "", + "maven": Object { + "fileMatch": Array [ + "\\\\.pom\\\\.xml$", + "(^|/)pom\\\\.xml$", + ], + "versioning": "maven", + }, + "meteor": Object { + "fileMatch": Array [ + "(^|/)package.js$", + ], + }, + "minor": Object {}, + "mix": Object { + "fileMatch": Array [ + "(^|/)mix\\\\.exs$", + ], + "versioning": "hex", + }, + "node": Object { + "commitMessageTopic": "Node.js", + "major": Object { + "enabled": false, + }, + }, + "nodenv": Object { + "fileMatch": Array [ + "^.node-version$", + ], + "versioning": "node", + }, + "npm": Object { + "fileMatch": Array [ + "(^|/)package.json$", + ], + "prBodyDefinitions": Object { + "Change": "[{{#if displayFrom}}\`{{{displayFrom}}}\` -> {{else}}{{#if currentValue}}\`{{{currentValue}}}\` -> {{/if}}{{/if}}{{#if displayTo}}\`{{{displayTo}}}\`{{else}}\`{{{newValue}}}\`{{/if}}]({{#if depName}}https://renovatebot.com/diffs/npm/{{replace '/' '%2f' depName}}/{{{fromVersion}}}/{{{toVersion}}}{{/if}})", + }, + "rollbackPrs": true, + "versioning": "npm", + }, + "npmToken": null, + "npmrc": null, + "nuget": Object { + "fileMatch": Array [ + "\\\\.(?:cs|fs|vb)proj$", + "\\\\.(?:props|targets)$", + "\\\\.config\\\\/dotnet-tools\\\\.json$", + ], + }, + "nvm": Object { + "fileMatch": Array [ + "(^|/)\\\\.nvmrc$", + ], + "versioning": "node", + }, + "onboarding": true, + "onboardingBranch": "renovate/configure", + "onboardingCommitMessage": null, + "onboardingConfig": Object { + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + }, + "onboardingPrTitle": "Configure Renovate", + "optimizeForDisabled": false, + "packageRules": Array [], + "password": null, + "patch": Object {}, + "persistRepoData": false, + "php": Object {}, + "pin": Object { + "commitMessageAction": "Pin", + "group": Object { + "commitMessageExtra": "", + "commitMessageTopic": "dependencies", + }, + "groupName": "Pin Dependencies", + "groupSlug": "pin-dependencies", + "rebaseWhen": "behind-base-branch", + "recreateClosed": true, + "unpublishSafe": false, + }, + "pinDigests": false, + "pip_requirements": Object { + "fileMatch": Array [ + "(^|/)([\\\\w-]*)requirements.(txt|pip)$", + ], + }, + "pip_setup": Object { + "fileMatch": Array [ + "(^|/)setup.py$", + ], + }, + "pipenv": Object { + "fileMatch": Array [ + "(^|/)Pipfile$", + ], + }, + "platform": "github", + "poetry": Object { + "fileMatch": Array [ + "(^|/)pyproject\\\\.toml$", + ], + }, + "postUpdateOptions": Array [], + "postUpgradeTasks": Object { + "commands": Array [], + "fileFilters": Array [], + }, + "prBodyColumns": Array [ + "Package", + "Type", + "Update", + "Change", + ], + "prBodyDefinitions": Object { + "Change": "\`{{{displayFrom}}}\` -> \`{{{displayTo}}}\`", + "Current value": "{{{currentValue}}}", + "New value": "{{{newValue}}}", + "Package": "{{{depNameLinked}}}", + "Package file": "{{{packageFile}}}", + "References": "{{{references}}}", + "Type": "{{{depType}}}", + "Update": "{{{updateType}}}", + }, + "prBodyNotes": Array [], + "prBodyTemplate": "{{{header}}}{{{table}}}{{{notes}}}{{{changelogs}}}{{{configDescription}}}{{{controls}}}{{{footer}}}", + "prCommitsPerRunLimit": 0, + "prConcurrentLimit": 0, + "prCreation": "immediate", + "prFooter": "This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).", + "prHeader": null, + "prHourlyLimit": 0, + "prNotPendingHours": 25, + "prPriority": 0, + "prTitle": null, + "printConfig": false, + "privateKey": null, + "productLinks": Object { + "documentation": "https://docs.renovatebot.com/", + "help": "https://github.com/renovatebot/config-help/issues", + "homepage": "https://github.com/renovatebot/renovate", + }, + "pruneStaleBranches": true, + "pub": Object { + "fileMatch": Array [ + "(^|/)pubspec\\\\.ya?ml$", + ], + "versioning": "npm", + }, + "python": Object { + "versioning": "pep440", + }, + "rangeStrategy": "replace", + "rebaseLabel": "rebase", + "rebaseWhen": "auto", + "recreateClosed": false, + "redisUrl": null, + "regex": Object { + "pinDigests": false, + }, + "regexManagers": Array [], + "registryUrls": null, + "renovateJsonPresent": true, + "repositories": Array [], + "repositoryCache": "disabled", + "requireConfig": true, + "requiredStatusChecks": Array [], + "respectLatest": true, + "reviewers": Array [], + "reviewersFromCodeOwners": false, + "reviewersSampleSize": null, + "rollbackPrs": false, + "ruby": Object {}, + "ruby-version": Object { + "fileMatch": Array [ + "(^|/)\\\\.ruby-version$", + ], + "versioning": "ruby", + }, + "rust": Object {}, + "sbt": Object { + "fileMatch": Array [ + "\\\\.sbt$", + "project/[^/]*.scala$", + ], + "versioning": "ivy", + }, + "schedule": Array [ + "at any time", + ], + "semanticCommitScope": "deps", + "semanticCommitType": "chore", + "semanticCommits": null, + "separateMajorMinor": true, + "separateMinorPatch": false, + "separateMultipleMajor": false, + "setup-cfg": Object { + "fileMatch": Array [ + "(^|/)setup\\\\.cfg$", + ], + "versioning": "pep440", + }, + "skipInstalls": null, + "stabilityDays": 0, + "supportPolicy": Array [], + "suppressNotifications": Array [ + "deprecationWarningIssues", + ], + "swift": Object { + "fileMatch": Array [ + "(^|/)Package\\\\.swift", + ], + "rangeStrategy": "bump", + "versioning": "swift", + }, + "terraform": Object { + "commitMessageTopic": "Terraform {{managerData.terraformDependencyType}} {{depNameShort}}", + "fileMatch": Array [ + "\\\\.tf$", + ], + "versioning": "hashicorp", + }, + "timezone": null, + "token": null, + "travis": Object { + "fileMatch": Array [ + "^.travis.yml$", + ], + "versioning": "node", + }, + "trustLevel": "low", + "unicodeEmoji": true, + "unpublishSafe": false, + "updateLockFiles": true, + "updateNotScheduled": true, + "username": null, + "versioning": "semver", + "vulnerabilityAlerts": Object { + "commitMessageSuffix": "[SECURITY]", + "dependencyDashboardApproval": false, + "groupName": null, + "rangeStrategy": "update-lockfile", + "schedule": Array [], + }, + "warnings": Array [], + "yarnrc": null, +} +`; exports[`workers/repository/init/config mergeRenovateConfig() throws error if misconfigured 1`] = `[Error: config-validation]`; diff --git a/lib/workers/repository/init/config.spec.ts b/lib/workers/repository/init/config.spec.ts index 736f65077872e54241dca4b428e40130d6ce4e1d..b65abcc165c25119532e821ddd36f53f666c823e 100644 --- a/lib/workers/repository/init/config.spec.ts +++ b/lib/workers/repository/init/config.spec.ts @@ -6,7 +6,11 @@ import { mocked, } from '../../../../test/util'; import * as _migrateAndValidate from '../../../config/migrate-validate'; -import { mergeRenovateConfig } from './config'; +import { + mergeRenovateConfig, + detectRepoFileConfig, + checkForRepoConfigError, +} from './config'; jest.mock('../../../util/fs'); jest.mock('../../../util/git'); @@ -24,18 +28,11 @@ beforeEach(() => { jest.mock('../../../config/migrate-validate'); describe('workers/repository/init/config', () => { - describe('mergeRenovateConfig()', () => { - beforeEach(() => { - migrateAndValidate.migrateAndValidate.mockResolvedValue({ - warnings: [], - errors: [], - }); - }); + describe('detectRepoFileConfig()', () => { it('returns config if not found', async () => { git.getFileList.mockResolvedValue(['package.json']); fs.readLocalFile.mockResolvedValue('{}'); - const res = await mergeRenovateConfig(config); - expect(res).toMatchObject(config); + expect(detectRepoFileConfig()).toMatchSnapshot(); }); it('uses package.json config if found', async () => { git.getFileList.mockResolvedValue(['package.json']); @@ -46,46 +43,26 @@ describe('workers/repository/init/config', () => { }, }); fs.readLocalFile.mockResolvedValue(pJson); - const renovateConfig = await mergeRenovateConfig(config); - expect(renovateConfig).toBeTruthy(); + expect(detectRepoFileConfig()).toMatchSnapshot(); }); it('returns error if cannot parse', async () => { git.getFileList.mockResolvedValue(['package.json', 'renovate.json']); fs.readLocalFile.mockResolvedValue('cannot parse'); - let e; - try { - await mergeRenovateConfig(config); - } catch (err) { - e = err; - } - expect(e).toBeDefined(); - expect(e.configFile).toMatchSnapshot(); - expect(e.validationError).toMatchSnapshot(); - expect(e.validationMessage).toMatchSnapshot(); + expect(detectRepoFileConfig()).toMatchSnapshot(); }); it('throws error if duplicate keys', async () => { git.getFileList.mockResolvedValue(['package.json', '.renovaterc']); fs.readLocalFile.mockResolvedValue( '{ "enabled": true, "enabled": false }' ); - let e; - try { - await mergeRenovateConfig(config); - } catch (err) { - e = err; - } - expect(e).toBeDefined(); - expect(e.configFile).toMatchSnapshot(); - expect(e.validationError).toMatchSnapshot(); - expect(e.validationMessage).toMatchSnapshot(); + expect(detectRepoFileConfig()).toMatchSnapshot(); }); it('finds and parse renovate.json5', async () => { git.getFileList.mockResolvedValue(['package.json', 'renovate.json5']); fs.readLocalFile.mockResolvedValue(`{ // this is json5 format }`); - const renovateConfig = await mergeRenovateConfig(config); - expect(renovateConfig).toBeTruthy(); + expect(detectRepoFileConfig()).toMatchSnapshot(); }); it('finds .github/renovate.json', async () => { git.getFileList.mockResolvedValue([ @@ -93,8 +70,7 @@ describe('workers/repository/init/config', () => { '.github/renovate.json', ]); fs.readLocalFile.mockResolvedValue('{}'); - const renovateConfig = await mergeRenovateConfig(config); - expect(renovateConfig).toBeTruthy(); + expect(detectRepoFileConfig()).toMatchSnapshot(); }); it('finds .gitlab/renovate.json', async () => { git.getFileList.mockResolvedValue([ @@ -102,15 +78,27 @@ describe('workers/repository/init/config', () => { '.gitlab/renovate.json', ]); fs.readLocalFile.mockResolvedValue('{}'); - const renovateConfig = await mergeRenovateConfig(config); - expect(renovateConfig).toBeTruthy(); + expect(detectRepoFileConfig()).toMatchSnapshot(); }); it('finds .renovaterc.json', async () => { git.getFileList.mockResolvedValue(['package.json', '.renovaterc.json']); fs.readLocalFile.mockResolvedValue('{}'); - const renovateConfig = await mergeRenovateConfig(config); - expect(renovateConfig).toBeTruthy(); + expect(detectRepoFileConfig()).toMatchSnapshot(); + }); + }); + describe('checkForRepoConfigError', () => { + it('returns if no error', () => { + expect(checkForRepoConfigError({})).toBeUndefined(); + }); + it('throws on error', () => { + expect(() => + checkForRepoConfigError({ + error: { validationError: '', validationMessage: '' }, + }) + ).toThrow(); }); + }); + describe('mergeRenovateConfig()', () => { it('throws error if misconfigured', async () => { git.getFileList.mockResolvedValue(['package.json', '.renovaterc.json']); fs.readLocalFile.mockResolvedValue('{}'); @@ -126,5 +114,14 @@ describe('workers/repository/init/config', () => { expect(e).toBeDefined(); expect(e).toMatchSnapshot(); }); + it('continues if no errors', async () => { + git.getFileList.mockResolvedValue(['package.json', '.renovaterc.json']); + fs.readLocalFile.mockResolvedValue('{}'); + migrateAndValidate.migrateAndValidate.mockResolvedValue({ + warnings: [], + errors: [], + }); + expect(await mergeRenovateConfig(config)).toMatchSnapshot(); + }); }); }); diff --git a/lib/workers/repository/init/config.ts b/lib/workers/repository/init/config.ts index 3aaef3ab3e7a3ee39515c23cfe3c465825079cf1..969e4681417693efdad659beb240ffca573181c0 100644 --- a/lib/workers/repository/init/config.ts +++ b/lib/workers/repository/init/config.ts @@ -114,7 +114,7 @@ export async function detectRepoFileConfig(): Promise<RepoFileConfig> { return { fileName, config }; } -function checkForRepoConfigError(repoConfig: RepoFileConfig): void { +export function checkForRepoConfigError(repoConfig: RepoFileConfig): void { if (!repoConfig.error) { return; }