Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Support requesting CLI from toolcache with tools: toolcache
  • Loading branch information
mbg committed Oct 3, 2025
commit 425ef8559525de0beae442f8231cc3d3425cef08
2 changes: 2 additions & 0 deletions init/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ inputs:
- A special value `nightly` which uses the latest nightly version of the
CodeQL tools. Note that this is unstable and not recommended for
production use.
- A special value `toolcache` which uses the latest version available in the
toolcache on the runner.

If not specified, the Action will check in several places until it finds
the CodeQL tools.
Expand Down
33 changes: 32 additions & 1 deletion lib/analyze-action.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 32 additions & 1 deletion lib/init-action-post.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 32 additions & 1 deletion lib/init-action.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 32 additions & 1 deletion lib/upload-lib.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 32 additions & 1 deletion lib/upload-sarif-action.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

107 changes: 107 additions & 0 deletions src/setup-codeql.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,113 @@ test("setupCodeQLBundle logs the CodeQL CLI version being used when asked to dow
});
});

test("getCodeQLSource correctly returns latest version from toolcache when tools == toolcache", async (t) => {
const loggedMessages: LoggedMessage[] = [];
const logger = getRecordingLogger(loggedMessages);

const latestToolcacheVersion = "3.2.1";
const latestVersionPath = "/path/to/latest";
const testVersions = ["2.3.1", latestToolcacheVersion, "1.2.3"];
const findAllVersionsStub = sinon
.stub(toolcache, "findAllVersions")
.returns(testVersions);
const findStub = sinon.stub(toolcache, "find");
findStub
.withArgs("CodeQL", latestToolcacheVersion)
.returns(latestVersionPath);

await withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
const source = await setupCodeql.getCodeQLSource(
"toolcache",
SAMPLE_DEFAULT_CLI_VERSION,
SAMPLE_DOTCOM_API_DETAILS,
GitHubVariant.DOTCOM,
false,
logger,
);

// Check that the toolcache functions were called with the expected arguments
t.assert(
findAllVersionsStub.calledOnceWith("CodeQL"),
`toolcache.findAllVersions("CodeQL") wasn't called`,
);
t.assert(
findStub.calledOnceWith("CodeQL", latestToolcacheVersion),
`toolcache.find("CodeQL", ${latestToolcacheVersion}) wasn't called`,
);

// Check that `sourceType` and `toolsVersion` match expectations.
t.is(source.sourceType, "toolcache");
t.is(source.toolsVersion, latestToolcacheVersion);

// Check that key messages we would expect to find in the log are present.
const expectedMessages: string[] = [
`Attempting to use the latest CodeQL CLI version in the toolcache, as requested by 'tools: toolcache'.`,
`CLI version ${latestToolcacheVersion} is the latest version in the toolcache.`,
`Using CodeQL CLI version ${latestToolcacheVersion} from toolcache at ${latestVersionPath}`,
];
for (const expectedMessage of expectedMessages) {
t.assert(
loggedMessages.some(
(msg) =>
typeof msg.message === "string" &&
msg.message.includes(expectedMessage),
),
`Expected '${expectedMessage}' in the logger output, but didn't find it.`,
);
}
});
});

test("getCodeQLSource falls back to downloading the CLI if the toolcache doesn't have a CodeQL CLI when tools == toolcache", async (t) => {
const loggedMessages: LoggedMessage[] = [];
const logger = getRecordingLogger(loggedMessages);

const testVersions = [];
const findAllVersionsStub = sinon
.stub(toolcache, "findAllVersions")
.returns(testVersions);

await withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
const source = await setupCodeql.getCodeQLSource(
"toolcache",
SAMPLE_DEFAULT_CLI_VERSION,
SAMPLE_DOTCOM_API_DETAILS,
GitHubVariant.DOTCOM,
false,
logger,
);

// Check that the toolcache functions were called with the expected arguments
t.assert(
findAllVersionsStub.calledWith("CodeQL"),
`toolcache.findAllVersions("CodeQL") wasn't called`,
);

// Check that `sourceType` and `toolsVersion` match expectations.
t.is(source.sourceType, "download");
t.is(source.toolsVersion, SAMPLE_DEFAULT_CLI_VERSION.cliVersion);

// Check that key messages we would expect to find in the log are present.
const expectedMessages: string[] = [
`Attempting to use the latest CodeQL CLI version in the toolcache, as requested by 'tools: toolcache'.`,
`Found no CodeQL CLI in the toolcache, ignoring 'tools: toolcache'...`,
];
for (const expectedMessage of expectedMessages) {
t.assert(
loggedMessages.some(
(msg) =>
typeof msg.message === "string" &&
msg.message.includes(expectedMessage),
),
`Expected '${expectedMessage}' in the logger output, but didn't find it.`,
);
}
});
});

test('tryGetTagNameFromUrl extracts the right tag name for a repo name containing "codeql-bundle"', (t) => {
t.is(
setupCodeql.tryGetTagNameFromUrl(
Expand Down
Loading