diff --git a/.github/actions/prepare-test/action.yml b/.github/actions/prepare-test/action.yml index 5e2b5028f7..e31ad9c961 100644 --- a/.github/actions/prepare-test/action.yml +++ b/.github/actions/prepare-test/action.yml @@ -12,6 +12,10 @@ inputs: description: "If true, we setup kotlin" default: 'true' required: true + test-directory: + description: "The directory containing the test project that should be moved to the workspace root" + required: false + default: "tests/multi-language-repo" outputs: tools-url: description: "The value that should be passed as the 'tools' input of the 'init' step." @@ -21,10 +25,12 @@ runs: steps: - name: Move codeql-action shell: bash + env: + TEST_DIR: ${{ inputs.test-directory }} run: | mkdir ../action mv * .github ../action/ - mv ../action/tests/multi-language-repo/{*,.github} . + mv ../action/$TEST_DIR/{*,.github} . mv ../action/.github/workflows .github - id: get-url name: Determine URL diff --git a/.github/workflows/__ccr.yml b/.github/workflows/__ccr.yml index d218e7bfc3..5ee5cd9814 100644 --- a/.github/workflows/__ccr.yml +++ b/.github/workflows/__ccr.yml @@ -36,24 +36,12 @@ jobs: fail-fast: false matrix: include: - - os: ubuntu-latest - version: stable-v2.17.6 - - os: ubuntu-latest - version: stable-v2.18.4 - - os: ubuntu-latest - version: stable-v2.19.4 - - os: ubuntu-latest - version: stable-v2.20.7 - - os: ubuntu-latest - version: stable-v2.21.4 - - os: ubuntu-latest - version: stable-v2.22.4 - - os: ubuntu-latest - version: default - os: ubuntu-latest version: linked + test-directory: tests/multi-language-repo - os: ubuntu-latest - version: nightly-latest + version: linked + test-directory: tests/empty-repo name: CCR if: github.triggering_actor != 'dependabot[bot]' permissions: @@ -71,6 +59,7 @@ jobs: version: ${{ matrix.version }} use-all-platform-bundle: 'false' setup-kotlin: 'true' + test-directory: ${{ matrix.test-directory }} - uses: ./../action/init id: init with: diff --git a/lib/analyze-action-post.js b/lib/analyze-action-post.js index 3e77189961..5ab70eb43d 100644 --- a/lib/analyze-action-post.js +++ b/lib/analyze-action-post.js @@ -142861,6 +142861,7 @@ var cliErrorsConfig = { // was unintended to have CodeQL analysis run on it. ["NoSourceCodeSeen" /* NoSourceCodeSeen */]: { exitCode: 32, + toleratedByCCR: true, cliErrorMessageCandidates: [ new RegExp( "CodeQL detected code written in .* but could not process any of it" @@ -142949,6 +142950,16 @@ function getUnsupportedPlatformError(cliError) { `The CodeQL CLI does not support the platform/architecture combination of ${process.platform}/${process.arch} (see ${"https://codeql.github.com/docs/codeql-overview/system-requirements/" /* SYSTEM_REQUIREMENTS */}). The underlying error was: ${cliError.message}` ); } +var ToleratedConfigurationError = class extends ConfigurationError { + category; + constructor(category, message) { + super(message); + this.category = category; + } + getCategory() { + return this.category; + } +}; function wrapCliConfigurationError(cliError) { if (isUnsupportedPlatform()) { return getUnsupportedPlatformError(cliError); @@ -142962,6 +142973,12 @@ function wrapCliConfigurationError(cliError) { if (additionalErrorMessageToAppend !== void 0) { errorMessageBuilder = `${errorMessageBuilder} ${additionalErrorMessageToAppend}`; } + if (cliErrorsConfig[cliConfigErrorCategory].toleratedByCCR) { + return new ToleratedConfigurationError( + cliConfigErrorCategory, + errorMessageBuilder + ); + } return new ConfigurationError(errorMessageBuilder); } diff --git a/lib/analyze-action.js b/lib/analyze-action.js index 10b796278a..6bd0a803c3 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -105443,6 +105443,7 @@ var cliErrorsConfig = { // was unintended to have CodeQL analysis run on it. ["NoSourceCodeSeen" /* NoSourceCodeSeen */]: { exitCode: 32, + toleratedByCCR: true, cliErrorMessageCandidates: [ new RegExp( "CodeQL detected code written in .* but could not process any of it" @@ -105531,6 +105532,16 @@ function getUnsupportedPlatformError(cliError) { `The CodeQL CLI does not support the platform/architecture combination of ${process.platform}/${process.arch} (see ${"https://codeql.github.com/docs/codeql-overview/system-requirements/" /* SYSTEM_REQUIREMENTS */}). The underlying error was: ${cliError.message}` ); } +var ToleratedConfigurationError = class extends ConfigurationError { + category; + constructor(category, message) { + super(message); + this.category = category; + } + getCategory() { + return this.category; + } +}; function wrapCliConfigurationError(cliError) { if (isUnsupportedPlatform()) { return getUnsupportedPlatformError(cliError); @@ -105544,6 +105555,12 @@ function wrapCliConfigurationError(cliError) { if (additionalErrorMessageToAppend !== void 0) { errorMessageBuilder = `${errorMessageBuilder} ${additionalErrorMessageToAppend}`; } + if (cliErrorsConfig[cliConfigErrorCategory].toleratedByCCR) { + return new ToleratedConfigurationError( + cliConfigErrorCategory, + errorMessageBuilder + ); + } return new ConfigurationError(errorMessageBuilder); } @@ -111530,7 +111547,8 @@ async function run(startedAt2) { core14.exportVariable("CODEQL_ACTION_ANALYZE_DID_COMPLETE_SUCCESSFULLY" /* ANALYZE_DID_COMPLETE_SUCCESSFULLY */, "true"); } catch (unwrappedError) { const error3 = wrapError(unwrappedError); - if (getOptionalInput("expect-error") !== "true" || hasBadExpectErrorInput()) { + const tolerateErrorForCCR = isCCR() && error3 instanceof ToleratedConfigurationError; + if (!tolerateErrorForCCR && (getOptionalInput("expect-error") !== "true" || hasBadExpectErrorInput())) { core14.setFailed(error3.message); } await sendStatusReport2( diff --git a/lib/autobuild-action.js b/lib/autobuild-action.js index 41707279b7..eb148391c8 100644 --- a/lib/autobuild-action.js +++ b/lib/autobuild-action.js @@ -102023,6 +102023,7 @@ var cliErrorsConfig = { // was unintended to have CodeQL analysis run on it. ["NoSourceCodeSeen" /* NoSourceCodeSeen */]: { exitCode: 32, + toleratedByCCR: true, cliErrorMessageCandidates: [ new RegExp( "CodeQL detected code written in .* but could not process any of it" @@ -102111,6 +102112,16 @@ function getUnsupportedPlatformError(cliError) { `The CodeQL CLI does not support the platform/architecture combination of ${process.platform}/${process.arch} (see ${"https://codeql.github.com/docs/codeql-overview/system-requirements/" /* SYSTEM_REQUIREMENTS */}). The underlying error was: ${cliError.message}` ); } +var ToleratedConfigurationError = class extends ConfigurationError { + category; + constructor(category, message) { + super(message); + this.category = category; + } + getCategory() { + return this.category; + } +}; function wrapCliConfigurationError(cliError) { if (isUnsupportedPlatform()) { return getUnsupportedPlatformError(cliError); @@ -102124,6 +102135,12 @@ function wrapCliConfigurationError(cliError) { if (additionalErrorMessageToAppend !== void 0) { errorMessageBuilder = `${errorMessageBuilder} ${additionalErrorMessageToAppend}`; } + if (cliErrorsConfig[cliConfigErrorCategory].toleratedByCCR) { + return new ToleratedConfigurationError( + cliConfigErrorCategory, + errorMessageBuilder + ); + } return new ConfigurationError(errorMessageBuilder); } diff --git a/lib/init-action-post.js b/lib/init-action-post.js index 9aa6dbf87a..0204df89d2 100644 --- a/lib/init-action-post.js +++ b/lib/init-action-post.js @@ -146182,6 +146182,7 @@ var cliErrorsConfig = { // was unintended to have CodeQL analysis run on it. ["NoSourceCodeSeen" /* NoSourceCodeSeen */]: { exitCode: 32, + toleratedByCCR: true, cliErrorMessageCandidates: [ new RegExp( "CodeQL detected code written in .* but could not process any of it" @@ -146270,6 +146271,16 @@ function getUnsupportedPlatformError(cliError) { `The CodeQL CLI does not support the platform/architecture combination of ${process.platform}/${process.arch} (see ${"https://codeql.github.com/docs/codeql-overview/system-requirements/" /* SYSTEM_REQUIREMENTS */}). The underlying error was: ${cliError.message}` ); } +var ToleratedConfigurationError = class extends ConfigurationError { + category; + constructor(category, message) { + super(message); + this.category = category; + } + getCategory() { + return this.category; + } +}; function wrapCliConfigurationError(cliError) { if (isUnsupportedPlatform()) { return getUnsupportedPlatformError(cliError); @@ -146283,6 +146294,12 @@ function wrapCliConfigurationError(cliError) { if (additionalErrorMessageToAppend !== void 0) { errorMessageBuilder = `${errorMessageBuilder} ${additionalErrorMessageToAppend}`; } + if (cliErrorsConfig[cliConfigErrorCategory].toleratedByCCR) { + return new ToleratedConfigurationError( + cliConfigErrorCategory, + errorMessageBuilder + ); + } return new ConfigurationError(errorMessageBuilder); } diff --git a/lib/init-action.js b/lib/init-action.js index a90cc55655..2dc5d463e0 100644 --- a/lib/init-action.js +++ b/lib/init-action.js @@ -105276,6 +105276,7 @@ var cliErrorsConfig = { // was unintended to have CodeQL analysis run on it. ["NoSourceCodeSeen" /* NoSourceCodeSeen */]: { exitCode: 32, + toleratedByCCR: true, cliErrorMessageCandidates: [ new RegExp( "CodeQL detected code written in .* but could not process any of it" @@ -105364,6 +105365,16 @@ function getUnsupportedPlatformError(cliError) { `The CodeQL CLI does not support the platform/architecture combination of ${process.platform}/${process.arch} (see ${"https://codeql.github.com/docs/codeql-overview/system-requirements/" /* SYSTEM_REQUIREMENTS */}). The underlying error was: ${cliError.message}` ); } +var ToleratedConfigurationError = class extends ConfigurationError { + category; + constructor(category, message) { + super(message); + this.category = category; + } + getCategory() { + return this.category; + } +}; function wrapCliConfigurationError(cliError) { if (isUnsupportedPlatform()) { return getUnsupportedPlatformError(cliError); @@ -105377,6 +105388,12 @@ function wrapCliConfigurationError(cliError) { if (additionalErrorMessageToAppend !== void 0) { errorMessageBuilder = `${errorMessageBuilder} ${additionalErrorMessageToAppend}`; } + if (cliErrorsConfig[cliConfigErrorCategory].toleratedByCCR) { + return new ToleratedConfigurationError( + cliConfigErrorCategory, + errorMessageBuilder + ); + } return new ConfigurationError(errorMessageBuilder); } diff --git a/lib/resolve-environment-action.js b/lib/resolve-environment-action.js index 5093055f93..32439e9bbe 100644 --- a/lib/resolve-environment-action.js +++ b/lib/resolve-environment-action.js @@ -102022,6 +102022,7 @@ var cliErrorsConfig = { // was unintended to have CodeQL analysis run on it. ["NoSourceCodeSeen" /* NoSourceCodeSeen */]: { exitCode: 32, + toleratedByCCR: true, cliErrorMessageCandidates: [ new RegExp( "CodeQL detected code written in .* but could not process any of it" @@ -102110,6 +102111,16 @@ function getUnsupportedPlatformError(cliError) { `The CodeQL CLI does not support the platform/architecture combination of ${process.platform}/${process.arch} (see ${"https://codeql.github.com/docs/codeql-overview/system-requirements/" /* SYSTEM_REQUIREMENTS */}). The underlying error was: ${cliError.message}` ); } +var ToleratedConfigurationError = class extends ConfigurationError { + category; + constructor(category, message) { + super(message); + this.category = category; + } + getCategory() { + return this.category; + } +}; function wrapCliConfigurationError(cliError) { if (isUnsupportedPlatform()) { return getUnsupportedPlatformError(cliError); @@ -102123,6 +102134,12 @@ function wrapCliConfigurationError(cliError) { if (additionalErrorMessageToAppend !== void 0) { errorMessageBuilder = `${errorMessageBuilder} ${additionalErrorMessageToAppend}`; } + if (cliErrorsConfig[cliConfigErrorCategory].toleratedByCCR) { + return new ToleratedConfigurationError( + cliConfigErrorCategory, + errorMessageBuilder + ); + } return new ConfigurationError(errorMessageBuilder); } diff --git a/lib/setup-codeql-action.js b/lib/setup-codeql-action.js index 59af2bf5cc..5bac9ccb7f 100644 --- a/lib/setup-codeql-action.js +++ b/lib/setup-codeql-action.js @@ -102946,6 +102946,7 @@ var cliErrorsConfig = { // was unintended to have CodeQL analysis run on it. ["NoSourceCodeSeen" /* NoSourceCodeSeen */]: { exitCode: 32, + toleratedByCCR: true, cliErrorMessageCandidates: [ new RegExp( "CodeQL detected code written in .* but could not process any of it" @@ -103034,6 +103035,16 @@ function getUnsupportedPlatformError(cliError) { `The CodeQL CLI does not support the platform/architecture combination of ${process.platform}/${process.arch} (see ${"https://codeql.github.com/docs/codeql-overview/system-requirements/" /* SYSTEM_REQUIREMENTS */}). The underlying error was: ${cliError.message}` ); } +var ToleratedConfigurationError = class extends ConfigurationError { + category; + constructor(category, message) { + super(message); + this.category = category; + } + getCategory() { + return this.category; + } +}; function wrapCliConfigurationError(cliError) { if (isUnsupportedPlatform()) { return getUnsupportedPlatformError(cliError); @@ -103047,6 +103058,12 @@ function wrapCliConfigurationError(cliError) { if (additionalErrorMessageToAppend !== void 0) { errorMessageBuilder = `${errorMessageBuilder} ${additionalErrorMessageToAppend}`; } + if (cliErrorsConfig[cliConfigErrorCategory].toleratedByCCR) { + return new ToleratedConfigurationError( + cliConfigErrorCategory, + errorMessageBuilder + ); + } return new ConfigurationError(errorMessageBuilder); } diff --git a/lib/start-proxy-action-post.js b/lib/start-proxy-action-post.js index 331b4d2503..532dcfd780 100644 --- a/lib/start-proxy-action-post.js +++ b/lib/start-proxy-action-post.js @@ -143012,6 +143012,7 @@ var cliErrorsConfig = { // was unintended to have CodeQL analysis run on it. ["NoSourceCodeSeen" /* NoSourceCodeSeen */]: { exitCode: 32, + toleratedByCCR: true, cliErrorMessageCandidates: [ new RegExp( "CodeQL detected code written in .* but could not process any of it" diff --git a/lib/upload-lib.js b/lib/upload-lib.js index 4917e2df6c..991d6fe6ff 100644 --- a/lib/upload-lib.js +++ b/lib/upload-lib.js @@ -105056,6 +105056,7 @@ var cliErrorsConfig = { // was unintended to have CodeQL analysis run on it. ["NoSourceCodeSeen" /* NoSourceCodeSeen */]: { exitCode: 32, + toleratedByCCR: true, cliErrorMessageCandidates: [ new RegExp( "CodeQL detected code written in .* but could not process any of it" @@ -105144,6 +105145,16 @@ function getUnsupportedPlatformError(cliError) { `The CodeQL CLI does not support the platform/architecture combination of ${process.platform}/${process.arch} (see ${"https://codeql.github.com/docs/codeql-overview/system-requirements/" /* SYSTEM_REQUIREMENTS */}). The underlying error was: ${cliError.message}` ); } +var ToleratedConfigurationError = class extends ConfigurationError { + category; + constructor(category, message) { + super(message); + this.category = category; + } + getCategory() { + return this.category; + } +}; function wrapCliConfigurationError(cliError) { if (isUnsupportedPlatform()) { return getUnsupportedPlatformError(cliError); @@ -105157,6 +105168,12 @@ function wrapCliConfigurationError(cliError) { if (additionalErrorMessageToAppend !== void 0) { errorMessageBuilder = `${errorMessageBuilder} ${additionalErrorMessageToAppend}`; } + if (cliErrorsConfig[cliConfigErrorCategory].toleratedByCCR) { + return new ToleratedConfigurationError( + cliConfigErrorCategory, + errorMessageBuilder + ); + } return new ConfigurationError(errorMessageBuilder); } diff --git a/lib/upload-sarif-action-post.js b/lib/upload-sarif-action-post.js index 9eb7356679..5db204b901 100644 --- a/lib/upload-sarif-action-post.js +++ b/lib/upload-sarif-action-post.js @@ -142696,6 +142696,7 @@ var cliErrorsConfig = { // was unintended to have CodeQL analysis run on it. ["NoSourceCodeSeen" /* NoSourceCodeSeen */]: { exitCode: 32, + toleratedByCCR: true, cliErrorMessageCandidates: [ new RegExp( "CodeQL detected code written in .* but could not process any of it" diff --git a/lib/upload-sarif-action.js b/lib/upload-sarif-action.js index 852442e176..be536b5837 100644 --- a/lib/upload-sarif-action.js +++ b/lib/upload-sarif-action.js @@ -106224,6 +106224,7 @@ var cliErrorsConfig = { // was unintended to have CodeQL analysis run on it. ["NoSourceCodeSeen" /* NoSourceCodeSeen */]: { exitCode: 32, + toleratedByCCR: true, cliErrorMessageCandidates: [ new RegExp( "CodeQL detected code written in .* but could not process any of it" @@ -106312,6 +106313,16 @@ function getUnsupportedPlatformError(cliError) { `The CodeQL CLI does not support the platform/architecture combination of ${process.platform}/${process.arch} (see ${"https://codeql.github.com/docs/codeql-overview/system-requirements/" /* SYSTEM_REQUIREMENTS */}). The underlying error was: ${cliError.message}` ); } +var ToleratedConfigurationError = class extends ConfigurationError { + category; + constructor(category, message) { + super(message); + this.category = category; + } + getCategory() { + return this.category; + } +}; function wrapCliConfigurationError(cliError) { if (isUnsupportedPlatform()) { return getUnsupportedPlatformError(cliError); @@ -106325,6 +106336,12 @@ function wrapCliConfigurationError(cliError) { if (additionalErrorMessageToAppend !== void 0) { errorMessageBuilder = `${errorMessageBuilder} ${additionalErrorMessageToAppend}`; } + if (cliErrorsConfig[cliConfigErrorCategory].toleratedByCCR) { + return new ToleratedConfigurationError( + cliConfigErrorCategory, + errorMessageBuilder + ); + } return new ConfigurationError(errorMessageBuilder); } diff --git a/pr-checks/checks/ccr.yml b/pr-checks/checks/ccr.yml index f4140508e8..6a4f75ff1e 100644 --- a/pr-checks/checks/ccr.yml +++ b/pr-checks/checks/ccr.yml @@ -1,5 +1,7 @@ name: "CCR" description: "A standard analysis in CCR mode" +testDirectories: ["tests/multi-language-repo", "tests/empty-repo"] +versions: ["linked"] env: CODEQL_ACTION_ANALYSIS_KEY: "dynamic/copilot-pull-request-reviewer/codeql-action-test" steps: diff --git a/pr-checks/sync.py b/pr-checks/sync.py index 77696b91fd..3af031d4a7 100755 --- a/pr-checks/sync.py +++ b/pr-checks/sync.py @@ -83,10 +83,18 @@ def writeHeader(checkStream): runnerImagesForOs = [image for image in runnerImages if image.startswith(operatingSystem)] for runnerImage in runnerImagesForOs: - matrix.append({ - 'os': runnerImage, - 'version': version - }) + if 'testDirectories' in checkSpecification: + for testDirectory in checkSpecification.get('testDirectories'): + matrix.append({ + 'os': runnerImage, + 'version': version, + 'test-directory': testDirectory + }) + else: + matrix.append({ + 'os': runnerImage, + 'version': version + }) useAllPlatformBundle = "false" # Default to false if checkSpecification.get('useAllPlatformBundle'): @@ -129,17 +137,22 @@ def writeHeader(checkStream): }, ]) + prepareWith = { + 'version': '${{ matrix.version }}', + 'use-all-platform-bundle': useAllPlatformBundle, + # If the action is being run from a container, then do not setup kotlin. + # This is because the kotlin binaries cannot be downloaded from the container. + 'setup-kotlin': str(not 'container' in checkSpecification).lower(), + } + + if 'testDirectories' in checkSpecification: + prepareWith['test-directory'] = '${{ matrix.test-directory }}' + steps.append({ 'name': 'Prepare test', 'id': 'prepare-test', 'uses': './.github/actions/prepare-test', - 'with': { - 'version': '${{ matrix.version }}', - 'use-all-platform-bundle': useAllPlatformBundle, - # If the action is being run from a container, then do not setup kotlin. - # This is because the kotlin binaries cannot be downloaded from the container. - 'setup-kotlin': str(not 'container' in checkSpecification).lower(), - } + 'with': prepareWith, }) installGo = is_truthy(checkSpecification.get('installGo', '')) diff --git a/src/analyze-action.ts b/src/analyze-action.ts index 3cc1ad019a..3d544afad6 100644 --- a/src/analyze-action.ts +++ b/src/analyze-action.ts @@ -18,6 +18,7 @@ import { import { getApiDetails, getGitHubVersion } from "./api-client"; import { runAutobuild } from "./autobuild"; import { getTotalCacheSize, shouldStoreCache } from "./caching-utils"; +import { ToleratedConfigurationError } from "./cli-errors"; import { getCodeQL } from "./codeql"; import { Config, getConfig } from "./config-utils"; import { @@ -450,9 +451,16 @@ async function run(startedAt: Date) { core.exportVariable(EnvVar.ANALYZE_DID_COMPLETE_SUCCESSFULLY, "true"); } catch (unwrappedError) { const error = util.wrapError(unwrappedError); + + const tolerateErrorForCCR = + actionsUtil.isCCR() && error instanceof ToleratedConfigurationError; + + // Set the outcome of the action as failed if we are not expecting an error, + // or the `expect-error` value is invalid. if ( - actionsUtil.getOptionalInput("expect-error") !== "true" || - hasBadExpectErrorInput() + !tolerateErrorForCCR && + (actionsUtil.getOptionalInput("expect-error") !== "true" || + hasBadExpectErrorInput()) ) { core.setFailed(error.message); } diff --git a/src/cli-errors.ts b/src/cli-errors.ts index 5aba268cab..35ddfadc55 100644 --- a/src/cli-errors.ts +++ b/src/cli-errors.ts @@ -153,6 +153,7 @@ type CliErrorConfiguration = { cliErrorMessageCandidates: RegExp[]; exitCode?: number; additionalErrorMessageToAppend?: string; + toleratedByCCR?: boolean; }; /** @@ -228,6 +229,7 @@ const cliErrorsConfig: Record = { // was unintended to have CodeQL analysis run on it. [CliConfigErrorCategory.NoSourceCodeSeen]: { exitCode: 32, + toleratedByCCR: true, cliErrorMessageCandidates: [ new RegExp( "CodeQL detected code written in .* but could not process any of it", @@ -345,6 +347,20 @@ function getUnsupportedPlatformError(cliError: CliError): ConfigurationError { ); } +export class ToleratedConfigurationError extends ConfigurationError { + private category: CliConfigErrorCategory; + + constructor(category: CliConfigErrorCategory, message: string) { + super(message); + + this.category = category; + } + + public getCategory(): CliConfigErrorCategory { + return this.category; + } +} + /** * Changes an error received from the CLI to a ConfigurationError with the message * optionally being transformed, if it is a known configuration error. Otherwise, @@ -368,5 +384,11 @@ export function wrapCliConfigurationError(cliError: CliError): Error { errorMessageBuilder = `${errorMessageBuilder} ${additionalErrorMessageToAppend}`; } + if (cliErrorsConfig[cliConfigErrorCategory].toleratedByCCR) { + return new ToleratedConfigurationError( + cliConfigErrorCategory, + errorMessageBuilder, + ); + } return new ConfigurationError(errorMessageBuilder); } diff --git a/tests/empty-repo/.github/.gitkeep b/tests/empty-repo/.github/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/empty-repo/.gitkeep b/tests/empty-repo/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/empty-repo/README.md b/tests/empty-repo/README.md new file mode 100644 index 0000000000..efe0149bde --- /dev/null +++ b/tests/empty-repo/README.md @@ -0,0 +1 @@ +This test folder is intentionally left (almost) empty.