diff --git a/extensions/ql-vscode/test/vscode-tests/cli-integration/remote-queries/remote-queries-manager.test.ts b/extensions/ql-vscode/test/vscode-tests/cli-integration/remote-queries/remote-queries-manager.test.ts deleted file mode 100644 index f298b266a..000000000 --- a/extensions/ql-vscode/test/vscode-tests/cli-integration/remote-queries/remote-queries-manager.test.ts +++ /dev/null @@ -1,358 +0,0 @@ -import { join } from "path"; -import { - CancellationTokenSource, - commands, - ExtensionContext, - extensions, - QuickPickItem, - Uri, - window, -} from "vscode"; -import { load } from "js-yaml"; - -import { QlPack } from "../../../../src/remote-queries/run-remote-query"; -import { CodeQLCliServer } from "../../../../src/cli"; -import { CodeQLExtensionInterface } from "../../../../src/extension"; -import { - setRemoteControllerRepo, - setRemoteRepositoryLists, -} from "../../../../src/config"; -import { UserCancellationException } from "../../../../src/commandRunner"; -import * as ghApiClient from "../../../../src/remote-queries/gh-api/gh-api-client"; -import { Repository } from "../../../../src/remote-queries/gh-api/repository"; -import { createMockExtensionContext } from "../../no-workspace"; -import { OutputChannelLogger } from "../../../../src/common"; -import { RemoteQueriesSubmission } from "../../../../src/remote-queries/shared/remote-queries"; -import { readBundledPack } from "../../utils/bundled-pack-helpers"; -import { RemoteQueriesManager } from "../../../../src/remote-queries/remote-queries-manager"; -import { - fixWorkspaceReferences, - restoreWorkspaceReferences, -} from "../global.helper"; -import { createMockApp } from "../../../__mocks__/appMock"; -import { App } from "../../../../src/common/app"; - -// up to 3 minutes per test -jest.setTimeout(3 * 60 * 1000); - -describe("Remote queries", () => { - const baseDir = join(__dirname, ".."); - - const qlpackFileWithWorkspaceRefs = getFile( - "data-remote-qlpack/qlpack.yml", - ).fsPath; - - let cli: CodeQLCliServer; - let cancellationTokenSource: CancellationTokenSource; - const progress = jest.fn(); - let showQuickPickSpy: jest.SpiedFunction; - let getRepositoryFromNwoStub: jest.SpiedFunction< - typeof ghApiClient.getRepositoryFromNwo - >; - let ctx: ExtensionContext; - let logger: any; - let app: App; - let remoteQueriesManager: RemoteQueriesManager; - - let originalDeps: Record | undefined; - - beforeEach(async () => { - showQuickPickSpy = jest.spyOn(window, "showQuickPick"); - getRepositoryFromNwoStub = jest.spyOn(ghApiClient, "getRepositoryFromNwo"); - - const extension = await extensions - .getExtension>( - "GitHub.vscode-codeql", - )! - .activate(); - if ("cliServer" in extension) { - cli = extension.cliServer; - } else { - throw new Error( - "Extension not initialized. Make sure cli is downloaded and installed properly.", - ); - } - - ctx = createMockExtensionContext(); - - logger = new OutputChannelLogger("test-logger"); - app = createMockApp({}); - remoteQueriesManager = new RemoteQueriesManager( - ctx, - app, - cli, - "fake-storage-dir", - logger, - ); - - cancellationTokenSource = new CancellationTokenSource(); - - // Should not have asked for a language - showQuickPickSpy - .mockResolvedValueOnce({ - repositories: ["github/vscode-codeql"], - } as unknown as QuickPickItem) - .mockResolvedValue("javascript" as unknown as QuickPickItem); - - const dummyRepository: Repository = { - id: 123, - name: "vscode-codeql", - full_name: "github/vscode-codeql", - private: false, - }; - getRepositoryFromNwoStub.mockResolvedValue(dummyRepository); - - // always run in the vscode-codeql repo - await setRemoteControllerRepo("github/vscode-codeql"); - await setRemoteRepositoryLists({ - "vscode-codeql": ["github/vscode-codeql"], - }); - - // Only new version support `${workspace}` in qlpack.yml - originalDeps = await fixWorkspaceReferences( - qlpackFileWithWorkspaceRefs, - cli, - ); - }); - - afterEach(async () => { - await restoreWorkspaceReferences(qlpackFileWithWorkspaceRefs, originalDeps); - }); - - describe("runRemoteQuery", () => { - let mockSubmitRemoteQueries: jest.SpiedFunction< - typeof ghApiClient.submitRemoteQueries - >; - let executeCommandSpy: jest.SpiedFunction; - - beforeEach(() => { - mockSubmitRemoteQueries = jest - .spyOn(ghApiClient, "submitRemoteQueries") - .mockResolvedValue({ - workflow_run_id: 20, - repositories_queried: ["octodemo/hello-world-1"], - }); - - executeCommandSpy = jest.spyOn(commands, "executeCommand"); - }); - - it("should run a remote query that is part of a qlpack", async () => { - const fileUri = getFile("data-remote-qlpack/in-pack.ql"); - - await remoteQueriesManager.runRemoteQuery( - fileUri, - progress, - cancellationTokenSource.token, - ); - - expect(mockSubmitRemoteQueries).toBeCalledTimes(1); - expect(executeCommandSpy).toBeCalledWith( - "codeQL.monitorRemoteQuery", - expect.any(String), - expect.objectContaining({ queryFilePath: fileUri.fsPath }), - ); - - const request: RemoteQueriesSubmission = - mockSubmitRemoteQueries.mock.calls[0][1]; - - const packFS = await readBundledPack(request.queryPack); - - // to retrieve the list of repositories - expect(showQuickPickSpy).toBeCalledTimes(1); - - expect(getRepositoryFromNwoStub).toBeCalledTimes(1); - - // check a few files that we know should exist and others that we know should not - expect(packFS.fileExists("in-pack.ql")).toBe(true); - expect(packFS.fileExists("lib.qll")).toBe(true); - expect(packFS.fileExists("qlpack.yml")).toBe(true); - - // depending on the cli version, we should have one of these files - expect( - packFS.fileExists("qlpack.lock.yml") || - packFS.fileExists("codeql-pack.lock.yml"), - ).toBe(true); - expect(packFS.fileExists("not-in-pack.ql")).toBe(false); - - // should have generated a correct qlpack file - const qlpackContents: any = load( - packFS.fileContents("qlpack.yml").toString("utf-8"), - ); - expect(qlpackContents.name).toBe("codeql-remote/query"); - - verifyQlPack("in-pack.ql", packFS.fileContents("qlpack.yml"), "0.0.0"); - - const libraryDir = ".codeql/libraries/codeql"; - const packNames = packFS.directoryContents(libraryDir).sort(); - - // check dependencies. - expect(packNames).toContain("javascript-all"); - }); - - it("should run a remote query that is not part of a qlpack", async () => { - const fileUri = getFile("data-remote-no-qlpack/in-pack.ql"); - - await remoteQueriesManager.runRemoteQuery( - fileUri, - progress, - cancellationTokenSource.token, - ); - - expect(mockSubmitRemoteQueries).toBeCalledTimes(1); - expect(executeCommandSpy).toBeCalledWith( - "codeQL.monitorRemoteQuery", - expect.any(String), - expect.objectContaining({ queryFilePath: fileUri.fsPath }), - ); - - const request: RemoteQueriesSubmission = - mockSubmitRemoteQueries.mock.calls[0][1]; - - const packFS = await readBundledPack(request.queryPack); - - // to retrieve the list of repositories - // and a second time to ask for the language - expect(showQuickPickSpy).toBeCalledTimes(2); - - expect(getRepositoryFromNwoStub).toBeCalledTimes(1); - - // check a few files that we know should exist and others that we know should not - expect(packFS.fileExists("in-pack.ql")).toBe(true); - expect(packFS.fileExists("qlpack.yml")).toBe(true); - // depending on the cli version, we should have one of these files - expect( - packFS.fileExists("qlpack.lock.yml") || - packFS.fileExists("codeql-pack.lock.yml"), - ).toBe(true); - expect(packFS.fileExists("lib.qll")).toBe(false); - expect(packFS.fileExists("not-in-pack.ql")).toBe(false); - - // the compiled pack - verifyQlPack("in-pack.ql", packFS.fileContents("qlpack.yml"), "0.0.0"); - - // should have generated a correct qlpack file - const qlpackContents: any = load( - packFS.fileContents("qlpack.yml").toString("utf-8"), - ); - expect(qlpackContents.name).toBe("codeql-remote/query"); - expect(qlpackContents.version).toBe("0.0.0"); - expect(qlpackContents.dependencies?.["codeql/javascript-all"]).toBe("*"); - - const libraryDir = ".codeql/libraries/codeql"; - const packNames = packFS.directoryContents(libraryDir).sort(); - - // check dependencies. - expect(packNames).toContain("javascript-all"); - }); - - it("should run a remote query that is nested inside a qlpack", async () => { - const fileUri = getFile("data-remote-qlpack-nested/subfolder/in-pack.ql"); - - await remoteQueriesManager.runRemoteQuery( - fileUri, - progress, - cancellationTokenSource.token, - ); - - expect(mockSubmitRemoteQueries).toBeCalledTimes(1); - expect(executeCommandSpy).toBeCalledWith( - "codeQL.monitorRemoteQuery", - expect.any(String), - expect.objectContaining({ queryFilePath: fileUri.fsPath }), - ); - - const request: RemoteQueriesSubmission = - mockSubmitRemoteQueries.mock.calls[0][1]; - - const packFS = await readBundledPack(request.queryPack); - - // to retrieve the list of repositories - expect(showQuickPickSpy).toBeCalledTimes(1); - - expect(getRepositoryFromNwoStub).toBeCalledTimes(1); - - // check a few files that we know should exist and others that we know should not - expect(packFS.fileExists("subfolder/in-pack.ql")).toBe(true); - expect(packFS.fileExists("codeql-pack.yml")).toBe(true); - // depending on the cli version, we should have one of these files - expect( - packFS.fileExists("qlpack.lock.yml") || - packFS.fileExists("codeql-pack.lock.yml"), - ).toBe(true); - expect(packFS.fileExists("otherfolder/lib.qll")).toBe(true); - expect(packFS.fileExists("not-in-pack.ql")).toBe(false); - - // the compiled pack - verifyQlPack( - "subfolder/in-pack.ql", - packFS.fileContents("codeql-pack.yml"), - "0.0.0", - ); - - // should have generated a correct qlpack file - const qlpackContents: any = load( - packFS.fileContents("codeql-pack.yml").toString("utf-8"), - ); - expect(qlpackContents.name).toBe("codeql-remote/query"); - expect(qlpackContents.version).toBe("0.0.0"); - expect(qlpackContents.dependencies?.["codeql/javascript-all"]).toBe("*"); - - const libraryDir = ".codeql/libraries/codeql"; - const packNames = packFS.directoryContents(libraryDir).sort(); - - // check dependencies. - expect(packNames).toContain("javascript-all"); - }); - - it("should cancel a run before uploading", async () => { - const fileUri = getFile("data-remote-no-qlpack/in-pack.ql"); - - const promise = remoteQueriesManager.runRemoteQuery( - fileUri, - progress, - cancellationTokenSource.token, - ); - - cancellationTokenSource.cancel(); - - await expect(promise).rejects.toThrow(UserCancellationException); - }); - }); - - function verifyQlPack( - queryPath: string, - contents: Buffer, - packVersion: string, - ) { - const qlPack = load(contents.toString("utf-8")) as QlPack; - - // don't check the build metadata since it is variable - delete (qlPack as any).buildMetadata; - - expect(qlPack).toEqual( - expect.objectContaining({ - name: "codeql-remote/query", - version: packVersion, - dependencies: { - "codeql/javascript-all": "*", - }, - defaultSuite: [ - { - description: "Query suite for variant analysis", - }, - { - query: queryPath, - }, - ], - }), - ); - - // v2.11.6 and later set this to false. - // Earlier versions don't set it at all. - expect(qlPack.library).toBeFalsy(); - } - - function getFile(file: string): Uri { - return Uri.file(join(baseDir, file)); - } -}); diff --git a/extensions/ql-vscode/test/vscode-tests/no-workspace/remote-queries/gh-api/gh-actions-api-client.test.ts b/extensions/ql-vscode/test/vscode-tests/no-workspace/remote-queries/gh-api/gh-actions-api-client.test.ts deleted file mode 100644 index 2a6ef3772..000000000 --- a/extensions/ql-vscode/test/vscode-tests/no-workspace/remote-queries/gh-api/gh-actions-api-client.test.ts +++ /dev/null @@ -1,136 +0,0 @@ -import { - cancelRemoteQuery, - cancelVariantAnalysis, - getRepositoriesMetadata, -} from "../../../../../src/remote-queries/gh-api/gh-actions-api-client"; -import { RemoteQuery } from "../../../../../src/remote-queries/remote-query"; -import { createMockVariantAnalysis } from "../../../../factories/remote-queries/shared/variant-analysis"; -import { VariantAnalysis } from "../../../../../src/remote-queries/shared/variant-analysis"; -import { - testCredentialsWithStub, - testCredentialsWithRealOctokit, -} from "../../../../factories/authentication"; - -jest.setTimeout(10000); - -describe("gh-actions-api-client mock responses", () => { - const mockRequest = jest.fn(); - const mockCredentials = testCredentialsWithStub(mockRequest); - - describe("cancelRemoteQuery", () => { - it("should cancel a remote query", async () => { - mockRequest.mockReturnValue({ status: 202 }); - await cancelRemoteQuery(mockCredentials, createMockRemoteQuery()); - - expect(mockRequest).toHaveBeenCalledTimes(1); - expect(mockRequest).toHaveBeenCalledWith( - "POST /repos/github/codeql/actions/runs/123/cancel", - ); - }); - - it("should fail to cancel a remote query", async () => { - mockRequest.mockResolvedValue({ - status: 409, - data: { message: "Uh oh!" }, - }); - - await expect( - cancelRemoteQuery(mockCredentials, createMockRemoteQuery()), - ).rejects.toThrow(/Error cancelling variant analysis: 409 Uh oh!/); - expect(mockRequest).toHaveBeenCalledTimes(1); - expect(mockRequest).toHaveBeenCalledWith( - "POST /repos/github/codeql/actions/runs/123/cancel", - ); - }); - - function createMockRemoteQuery(): RemoteQuery { - return { - actionsWorkflowRunId: 123, - controllerRepository: { - owner: "github", - name: "codeql", - }, - } as unknown as RemoteQuery; - } - }); - - describe("cancelVariantAnalysis", () => { - let variantAnalysis: VariantAnalysis; - beforeAll(() => { - variantAnalysis = createMockVariantAnalysis({}); - }); - - it("should cancel a variant analysis", async () => { - mockRequest.mockResolvedValue({ status: 202 }); - await cancelVariantAnalysis(mockCredentials, variantAnalysis); - - expect(mockRequest).toHaveBeenCalledTimes(1); - expect(mockRequest).toHaveBeenCalledWith( - `POST /repos/${variantAnalysis.controllerRepo.fullName}/actions/runs/${variantAnalysis.actionsWorkflowRunId}/cancel`, - ); - }); - - it("should fail to cancel a variant analysis", async () => { - mockRequest.mockResolvedValue({ - status: 409, - data: { message: "Uh oh!" }, - }); - - await expect( - cancelVariantAnalysis(mockCredentials, variantAnalysis), - ).rejects.toThrow(/Error cancelling variant analysis: 409 Uh oh!/); - expect(mockRequest).toHaveBeenCalledTimes(1); - expect(mockRequest).toHaveBeenCalledWith( - `POST /repos/${variantAnalysis.controllerRepo.fullName}/actions/runs/${variantAnalysis.actionsWorkflowRunId}/cancel`, - ); - }); - }); -}); - -describe("gh-actions-api-client real responses", () => { - it("should get the stargazers for repos", async () => { - if (skip()) { - return; - } - - const credentials = testCredentialsWithRealOctokit( - process.env.VSCODE_CODEQL_GITHUB_TOKEN!, - ); - const stargazers = await getRepositoriesMetadata( - credentials, - [ - "github/codeql", - "github/vscode-codeql", - "rails/rails", - "angular/angular", - "github/hucairz", // This one should not be in the list - ], - // choose a page size that is small enough to ensure we make multiple requests - 2, - ); - - const stargazersKeys = Object.keys(stargazers).sort(); - expect(stargazersKeys).toEqual([ - "angular/angular", - "github/codeql", - "github/vscode-codeql", - "rails/rails", - ]); - }); - - function skip() { - if (!process.env.VSCODE_CODEQL_GITHUB_TOKEN) { - if (process.env.CI) { - throw new Error( - "The VSCODE_CODEQL_GITHUB_TOKEN must be set to a valid GITHUB token on CI", - ); - } else { - console.log( - "Skipping gh-actions-api-client real responses tests. To run these tests, set the value VSCODE_CODEQL_GITHUB_TOKEN to a GitHub token.", - ); - } - return true; - } - return false; - } -}); diff --git a/extensions/ql-vscode/test/vscode-tests/no-workspace/remote-queries/remote-queries-api.test.ts b/extensions/ql-vscode/test/vscode-tests/no-workspace/remote-queries/remote-queries-api.test.ts deleted file mode 100644 index fe96be07c..000000000 --- a/extensions/ql-vscode/test/vscode-tests/no-workspace/remote-queries/remote-queries-api.test.ts +++ /dev/null @@ -1,272 +0,0 @@ -import { EOL } from "os"; -import { parseResponse } from "../../../../src/remote-queries/remote-queries-api"; -import { Repository } from "../../../../src/remote-queries/shared/repository"; - -describe("parseResponse", () => { - const controllerRepository: Repository = { - id: 123, - fullName: "org/name", - private: true, - }; - - it("should parse a successful response", () => { - const result = parseResponse(controllerRepository, { - workflow_run_id: 123, - repositories_queried: ["a/b", "c/d"], - }); - - expect(result.popupMessage).toBe( - "Successfully scheduled runs on 2 repositories. [Click here to see the progress](https://github.com/org/name/actions/runs/123).", - ); - expect(result.logMessage).toBe( - [ - "Successfully scheduled runs on 2 repositories. See https://github.com/org/name/actions/runs/123.", - "", - "Repositories queried:", - "a/b, c/d", - ].join(EOL), - ); - }); - - it("should parse a response with invalid repos", () => { - const result = parseResponse(controllerRepository, { - workflow_run_id: 123, - repositories_queried: ["a/b", "c/d"], - errors: { - invalid_repositories: ["e/f", "g/h"], - }, - }); - - expect(result.popupMessage).toBe( - [ - "Successfully scheduled runs on 2 repositories. [Click here to see the progress](https://github.com/org/name/actions/runs/123).", - "", - "Some repositories could not be scheduled. See extension log for details.", - ].join(EOL), - ); - expect(result.logMessage).toBe( - [ - "Successfully scheduled runs on 2 repositories. See https://github.com/org/name/actions/runs/123.", - "", - "Repositories queried:", - "a/b, c/d", - "", - "Some repositories could not be scheduled.", - "", - "2 repositories invalid and could not be found:", - "e/f, g/h", - ].join(EOL), - ); - }); - - it("should parse a response with repos w/o databases", () => { - const result = parseResponse(controllerRepository, { - workflow_run_id: 123, - repositories_queried: ["a/b", "c/d"], - errors: { - repositories_without_database: ["e/f", "g/h"], - }, - }); - - expect(result.popupMessage).toBe( - [ - "Successfully scheduled runs on 2 repositories. [Click here to see the progress](https://github.com/org/name/actions/runs/123).", - "", - "Some repositories could not be scheduled. See extension log for details.", - ].join(EOL), - ); - expect(result.logMessage).toBe( - [ - "Successfully scheduled runs on 2 repositories. See https://github.com/org/name/actions/runs/123.", - "", - "Repositories queried:", - "a/b, c/d", - "", - "Some repositories could not be scheduled.", - "", - "2 repositories did not have a CodeQL database available:", - "e/f, g/h", - "For each public repository that has not yet been added to the database service, we will try to create a database next time the store is updated.", - ].join(EOL), - ); - }); - - it("should parse a response with private repos", () => { - const result = parseResponse(controllerRepository, { - workflow_run_id: 123, - repositories_queried: ["a/b", "c/d"], - errors: { - private_repositories: ["e/f", "g/h"], - }, - }); - - expect(result.popupMessage).toBe( - [ - "Successfully scheduled runs on 2 repositories. [Click here to see the progress](https://github.com/org/name/actions/runs/123).", - "", - "Some repositories could not be scheduled. See extension log for details.", - ].join(EOL), - ); - expect(result.logMessage).toBe( - [ - "Successfully scheduled runs on 2 repositories. See https://github.com/org/name/actions/runs/123.", - "", - "Repositories queried:", - "a/b, c/d", - "", - "Some repositories could not be scheduled.", - "", - "2 repositories not public:", - "e/f, g/h", - "When using a public controller repository, only public repositories can be queried.", - ].join(EOL), - ); - }); - - it("should parse a response with cutoff repos and cutoff repos count", () => { - const result = parseResponse(controllerRepository, { - workflow_run_id: 123, - repositories_queried: ["a/b", "c/d"], - errors: { - cutoff_repositories: ["e/f", "g/h"], - cutoff_repositories_count: 2, - }, - }); - - expect(result.popupMessage).toBe( - [ - "Successfully scheduled runs on 2 repositories. [Click here to see the progress](https://github.com/org/name/actions/runs/123).", - "", - "Some repositories could not be scheduled. See extension log for details.", - ].join(EOL), - ); - expect(result.logMessage).toBe( - [ - "Successfully scheduled runs on 2 repositories. See https://github.com/org/name/actions/runs/123.", - "", - "Repositories queried:", - "a/b, c/d", - "", - "Some repositories could not be scheduled.", - "", - "2 repositories over the limit for a single request:", - "e/f, g/h", - "Repositories were selected based on how recently they had been updated.", - ].join(EOL), - ); - }); - - it("should parse a response with cutoff repos count but not cutoff repos", () => { - const result = parseResponse(controllerRepository, { - workflow_run_id: 123, - repositories_queried: ["a/b", "c/d"], - errors: { - cutoff_repositories_count: 2, - }, - }); - - expect(result.popupMessage).toBe( - [ - "Successfully scheduled runs on 2 repositories. [Click here to see the progress](https://github.com/org/name/actions/runs/123).", - "", - "Some repositories could not be scheduled. See extension log for details.", - ].join(EOL), - ); - expect(result.logMessage).toBe( - [ - "Successfully scheduled runs on 2 repositories. See https://github.com/org/name/actions/runs/123.", - "", - "Repositories queried:", - "a/b, c/d", - "", - "Some repositories could not be scheduled.", - "", - "2 repositories over the limit for a single request.", - "Repositories were selected based on how recently they had been updated.", - ].join(EOL), - ); - }); - - it("should parse a response with invalid repos and repos w/o databases", () => { - const result = parseResponse(controllerRepository, { - workflow_run_id: 123, - repositories_queried: ["a/b", "c/d"], - errors: { - invalid_repositories: ["e/f", "g/h"], - repositories_without_database: ["i/j", "k/l"], - }, - }); - - expect(result.popupMessage).toBe( - [ - "Successfully scheduled runs on 2 repositories. [Click here to see the progress](https://github.com/org/name/actions/runs/123).", - "", - "Some repositories could not be scheduled. See extension log for details.", - ].join(EOL), - ); - expect(result.logMessage).toBe( - [ - "Successfully scheduled runs on 2 repositories. See https://github.com/org/name/actions/runs/123.", - "", - "Repositories queried:", - "a/b, c/d", - "", - "Some repositories could not be scheduled.", - "", - "2 repositories invalid and could not be found:", - "e/f, g/h", - "", - "2 repositories did not have a CodeQL database available:", - "i/j, k/l", - "For each public repository that has not yet been added to the database service, we will try to create a database next time the store is updated.", - ].join(EOL), - ); - }); - - it('should parse a response with one repo of each category, and not pluralize "repositories"', () => { - const result = parseResponse(controllerRepository, { - workflow_run_id: 123, - repositories_queried: ["a/b"], - errors: { - private_repositories: ["e/f"], - cutoff_repositories: ["i/j"], - cutoff_repositories_count: 1, - invalid_repositories: ["m/n"], - repositories_without_database: ["q/r"], - }, - }); - - expect(result.popupMessage).toBe( - [ - "Successfully scheduled runs on 1 repository. [Click here to see the progress](https://github.com/org/name/actions/runs/123).", - "", - "Some repositories could not be scheduled. See extension log for details.", - ].join(EOL), - ); - expect(result.logMessage).toBe( - [ - "Successfully scheduled runs on 1 repository. See https://github.com/org/name/actions/runs/123.", - "", - "Repositories queried:", - "a/b", - "", - "Some repositories could not be scheduled.", - "", - "1 repository invalid and could not be found:", - "m/n", - "", - "1 repository did not have a CodeQL database available:", - "q/r", - "For each public repository that has not yet been added to the database service, we will try to create a database next time the store is updated.", - "", - "1 repository not public:", - "e/f", - "When using a public controller repository, only public repositories can be queried.", - "", - "1 repository over the limit for a single request:", - "i/j", - "Repositories were selected based on how recently they had been updated.", - ].join(EOL), - ); - }); -});