mirror of
https://github.com/github/codeql-action.git
synced 2026-05-08 14:50:21 +00:00
# This is a combination of 4 commits.
# This is the 1st commit message: Add logic to download codeql platform-language pkg * Add `bundleName` argument to `getCodeQLBundleDownloadURL` * Add `languages` argument to `setupCodeQL`. The logic now tries to find the platform-language pkg before defaulting to the full bundle. We keep the toolcache clean by adding the pl version to the tool version. # The commit message #2 will be skipped: # add test # The commit message #3 will be skipped: # cleanup # The commit message #4 will be skipped: # linter
This commit is contained in:
+100
-13
@@ -1,9 +1,14 @@
|
||||
import * as github from "@actions/github";
|
||||
import * as toolcache from '@actions/tool-cache';
|
||||
import test from 'ava';
|
||||
import nock from 'nock';
|
||||
import * as path from 'path';
|
||||
import sinon from 'sinon';
|
||||
|
||||
|
||||
import * as api from './api-client';
|
||||
import * as codeql from './codeql';
|
||||
import * as defaults from './defaults.json'; // Referenced from codeql-action-sync-tool!
|
||||
import { Language } from './languages';
|
||||
import { getRunnerLogger } from './logging';
|
||||
import {setupTests} from './testing-utils';
|
||||
@@ -12,7 +17,8 @@ import * as util from './util';
|
||||
|
||||
setupTests(test);
|
||||
|
||||
test('download codeql bundle cache', async t => {
|
||||
test('download and populate codeql bundle cache', async t => {
|
||||
|
||||
await util.withTmpDir(async tmpDir => {
|
||||
const versions = ['20200601', '20200610'];
|
||||
const languages: Language[][] = [
|
||||
@@ -24,16 +30,15 @@ test('download codeql bundle cache', async t => {
|
||||
process.platform === 'linux' ? 'linux64' :
|
||||
process.platform === 'darwin' ? 'osx64' : undefined;
|
||||
|
||||
|
||||
for (let i = 0; i < versions.length; i++) {
|
||||
for (let j = 0; j < languages.length; j++) {
|
||||
const version = versions[i];
|
||||
const plVersion = (languages[j].length === 1) ? `${platform}-${languages[j][0]}` : undefined;
|
||||
const pkg = plVersion ? `codeql-${plVersion}.tar.gz` : `codeql-bundle.tar.gz`;
|
||||
|
||||
|
||||
nock('https://example.com')
|
||||
.get(`/download/codeql-bundle-${version}/${pkg}`)
|
||||
.replyWithFile(200, path.join(__dirname, `/../src/testdata/codeql-bundle.tar.gz`));
|
||||
.get(`/download/codeql-bundle-${version}/codeql-bundle.tar.gz`)
|
||||
.replyWithFile(200, path.join(__dirname, `/../src/testdata/codeql-bundle.tar.gz`));
|
||||
|
||||
await codeql.setupCodeQL(
|
||||
`https://example.com/download/codeql-bundle-${version}/codeql-bundle.tar.gz`,
|
||||
@@ -46,19 +51,81 @@ test('download codeql bundle cache', async t => {
|
||||
getRunnerLogger(true));
|
||||
|
||||
const toolcacheVersion = plVersion ? `0.0.0-${version}-${plVersion}` : `0.0.0-${version}`;
|
||||
t.assert(toolcache.find('CodeQL', toolcacheVersion), `Looking for ${toolcacheVersion} - ${plVersion}`);
|
||||
t.assert(toolcache.find('CodeQL', toolcacheVersion), `Looking for ${toolcacheVersion}`);
|
||||
}
|
||||
}
|
||||
|
||||
const cachedVersions = toolcache.findAllVersions('CodeQL');
|
||||
|
||||
t.is(cachedVersions.length, 4);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
test('use codeql bundle cache if pl version is not available', async t => {
|
||||
// If we look for a pl version but find in cache the bundle, we use the bundle
|
||||
test('download small codeql bundle if analyzing only one language', async t => {
|
||||
// Note: We do not specify a codeqlURL in this test, thus testing that
|
||||
// the logic for constructing the URL takes into account the
|
||||
// language being analyzed
|
||||
await util.withTmpDir(async tmpDir => {
|
||||
const languages: Language[][] = [
|
||||
[Language.cpp],
|
||||
[Language.cpp, Language.python] // Multi-language requires the full bundle
|
||||
];
|
||||
|
||||
const platform = process.platform === 'win32' ? 'win64' :
|
||||
process.platform === 'linux' ? 'linux64' :
|
||||
process.platform === 'darwin' ? 'osx64' : undefined;
|
||||
|
||||
for (let i = 0; i < languages.length; i++) {
|
||||
const plVersion = (languages[i].length === 1) ? `${platform}-${languages[i][0]}` : undefined;
|
||||
const pkg = plVersion ? `codeql-bundle-${plVersion}.tar.gz` : 'codeql-bundle.tar.gz';
|
||||
|
||||
// Mock the API client
|
||||
let client = new github.GitHub('123');
|
||||
const response = {
|
||||
data: {
|
||||
'assets': [
|
||||
{
|
||||
'name': `codeql-bundle-${platform}-cpp.tar.gz`,
|
||||
'url': `https://github.example.com/url/codeql-bundle-${platform}-cpp.tar.gz`
|
||||
},
|
||||
{
|
||||
'name': 'codeql-bundle.tar.gz',
|
||||
'url': 'https://github.example.com/url/codeql-bundle.tar.gz'
|
||||
},
|
||||
]
|
||||
},
|
||||
};
|
||||
sinon.stub(client.repos, "getReleaseByTag").resolves(response as any);
|
||||
sinon.stub(api, "getApiClient").value(() => client);
|
||||
|
||||
nock('https://github.example.com')
|
||||
.get(`/url/${pkg}`)
|
||||
.replyWithFile(200, path.join(__dirname, `/../src/testdata/codeql-bundle.tar.gz`));
|
||||
|
||||
await codeql.setupCodeQL(
|
||||
undefined,
|
||||
languages[i],
|
||||
'token',
|
||||
'https://github.example.com',
|
||||
tmpDir,
|
||||
tmpDir,
|
||||
'runner',
|
||||
getRunnerLogger(true));
|
||||
|
||||
const parsedVersion = codeql.getCodeQLURLVersion(`/${defaults.bundleVersion}/`, getRunnerLogger(true));
|
||||
const toolcacheVersion = plVersion ? `${parsedVersion}-${plVersion}` : parsedVersion;
|
||||
t.assert(toolcache.find('CodeQL', toolcacheVersion), `Looking for ${toolcacheVersion} - ${plVersion}`);
|
||||
}
|
||||
|
||||
const cachedVersions = toolcache.findAllVersions('CodeQL');
|
||||
t.is(cachedVersions.length, 2);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
test('use full codeql bundle cache if smaller bundle is not available', async t => {
|
||||
// If we look for a platform-language version but find the full bundle in the cache,
|
||||
// we use the full bundle
|
||||
await util.withTmpDir(async tmpDir => {
|
||||
const version = '20200601';
|
||||
|
||||
@@ -96,12 +163,32 @@ test('use codeql bundle cache if pl version is not available', async t => {
|
||||
});
|
||||
});
|
||||
|
||||
// test('use larger bundles if smaller ones are unavailble', async t => {
|
||||
// // TODO: This should check the fallback behavior of getCodeQLBundleDownloadURL
|
||||
// t.fail()
|
||||
// });
|
||||
test('use larger bundles if smaller ones are not released', async t => {
|
||||
// Mock the API client
|
||||
let client = new github.GitHub('123');
|
||||
const response = {
|
||||
data: {
|
||||
'assets': [
|
||||
{ 'name': 'full-bundle', 'url': 'url/file.gz' },
|
||||
]
|
||||
},
|
||||
};
|
||||
let getReleaseByTagMock = sinon.stub(client.repos, "getReleaseByTag").resolves(response as any);
|
||||
sinon.stub(api, "getApiClient").value(() => client);
|
||||
|
||||
// Setting this env is required by a dependency of getCodeQLBundleDownloadURL
|
||||
process.env['RUNNER_TEMP'] = "abc";
|
||||
|
||||
let codeqlURL = await codeql.getCodeQLBundleDownloadURL(
|
||||
['small-bundle', 'full-bundle'],
|
||||
"",
|
||||
"",
|
||||
'actions',
|
||||
getRunnerLogger(true));
|
||||
|
||||
t.deepEqual(codeqlURL, 'url/file.gz');
|
||||
t.assert(getReleaseByTagMock.called);
|
||||
});
|
||||
|
||||
test('parse codeql bundle url version', t => {
|
||||
|
||||
|
||||
+23
-13
@@ -126,7 +126,7 @@ function getCodeQLActionRepository(mode: util.Mode): string {
|
||||
return relativeScriptPathParts[0] + "/" + relativeScriptPathParts[1];
|
||||
}
|
||||
|
||||
async function getCodeQLBundleDownloadURL(
|
||||
export async function getCodeQLBundleDownloadURL(
|
||||
bundleNames: string[],
|
||||
githubAuth: string,
|
||||
githubUrl: string,
|
||||
@@ -211,7 +211,20 @@ export async function setupCodeQL(
|
||||
process.env['RUNNER_TEMP'] = tempDir;
|
||||
process.env['RUNNER_TOOL_CACHE'] = toolsDir;
|
||||
|
||||
// Compute package version
|
||||
// The URL identifies the release version. E.g., codeql-20200901 .
|
||||
// The plVersion identifies the platform-language combination of the package
|
||||
// within the release. E.g., `linux64-cpp` in `codeql-linux64-cpp.tar.gz`.
|
||||
// We expect the codeqlUrl (when given) to always point to the main bundle
|
||||
// `codeql-bundle.tar.gz`
|
||||
//
|
||||
// The logic is as follows:
|
||||
// - Always use the Toolcache if available.
|
||||
// - If we would like a platform-language package, but have the
|
||||
// full bundle in the cache, use that.
|
||||
// - If codeqlURL is specified, use that.
|
||||
// - If a single language is being analyzed, try to download the platform-language package.
|
||||
// - If it is not available in the release assets, fallback to the full bundle
|
||||
// - If multiple languages are being anlyzed, use the full bundle
|
||||
let plVersion: string | undefined = undefined;
|
||||
let platform: string;
|
||||
if (process.platform === 'win32') {
|
||||
@@ -228,12 +241,6 @@ export async function setupCodeQL(
|
||||
}
|
||||
|
||||
try {
|
||||
// The URL identifies the release version. E.g., codeql-20200901 .
|
||||
// The plVersion identifies the platform-language combination of the package
|
||||
// within the release. E.g., `linux64-cpp` in `codeql-linux64-cpp.tar.gz`.
|
||||
// We expect the codeqlUrl (when given) to always point to the main bundle
|
||||
// `codeql-bundle.tar.gz`
|
||||
|
||||
const codeqlURLVersion = getCodeQLURLVersion(codeqlURL || `/${CODEQL_BUNDLE_VERSION}/`, logger);
|
||||
|
||||
let codeqlFolder;
|
||||
@@ -257,11 +264,14 @@ export async function setupCodeQL(
|
||||
const codeqlToolcacheVersion = plVersion ? `${codeqlURLVersion}-${plVersion}` : codeqlURLVersion;
|
||||
logger.debug(`CodeQL not found in cache`);
|
||||
if (!codeqlURL) {
|
||||
const bundles = [
|
||||
CODEQL_BUNDLE_NAME.replace("-bundle", `-bundle-${plVersion}`),
|
||||
CODEQL_BUNDLE_NAME.replace("-bundle", `-bundle-${platform}`),
|
||||
CODEQL_BUNDLE_NAME,
|
||||
];
|
||||
// Provide a few options, from smaller to bigger
|
||||
let bundles: string[] = [];
|
||||
if (plVersion) {
|
||||
bundles.push(CODEQL_BUNDLE_NAME.replace("-bundle", `-bundle-${plVersion}`));
|
||||
}
|
||||
bundles.push(CODEQL_BUNDLE_NAME.replace("-bundle", `-bundle-${platform}`));
|
||||
bundles.push(CODEQL_BUNDLE_NAME);
|
||||
|
||||
codeqlURL = await getCodeQLBundleDownloadURL(bundles, githubAuth, githubUrl, mode, logger);
|
||||
}
|
||||
logger.debug(`Using CodeQL URL: ${codeqlURL}`);
|
||||
|
||||
Reference in New Issue
Block a user