Merge branch 'main' into henrymercer/remove-action-config-parsing

This commit is contained in:
Henry Mercer 2024-01-05 16:14:49 +00:00
commit a533ec62b3
19 changed files with 74 additions and 248 deletions

View file

@ -6,6 +6,7 @@ Note that the only difference between `v2` and `v3` of the CodeQL Action is the
## [UNRELEASED]
- We are rolling out a feature in January 2024 that will disable Python dependency installation by default for all users. This improves the speed of analysis while having only a very minor impact on results. You can override this behavior by setting `CODEQL_ACTION_DISABLE_PYTHON_DEPENDENCY_INSTALLATION=false` in your workflow, however we plan to remove this ability in future versions of the CodeQL Action. [#2031](https://github.com/github/codeql-action/pull/2031)
- The CodeQL Action now requires CodeQL version 2.11.6 or later. For more information, see [the corresponding changelog entry for CodeQL Action version 2.22.7](#2227---16-nov-2023). [#2009](https://github.com/github/codeql-action/pull/2009)
## 3.22.12 - 22 Dec 2023

2
lib/analyze.js generated
View file

@ -53,7 +53,7 @@ async function setupPythonExtractor(logger, features, codeql) {
// If CODEQL_PYTHON is not set, no dependencies were installed, so we don't need to do anything
return;
}
if (await features.getValue(feature_flags_1.Feature.DisablePythonDependencyInstallationEnabled, codeql)) {
if (await (0, feature_flags_1.isPythonDependencyInstallationDisabled)(codeql, features)) {
logger.warning("We recommend that you remove the CODEQL_PYTHON environment variable from your workflow. This environment variable was originally used to specify a Python executable that included the dependencies of your Python code, however Python analysis no longer uses these dependencies." +
"\nIf you used CODEQL_PYTHON to force the version of Python to analyze as, please use CODEQL_EXTRACTOR_PYTHON_ANALYSIS_VERSION instead, such as 'CODEQL_EXTRACTOR_PYTHON_ANALYSIS_VERSION=2.7' or 'CODEQL_EXTRACTOR_PYTHON_ANALYSIS_VERSION=3.11'.");
return;

File diff suppressed because one or more lines are too long

17
lib/feature-flags.js generated
View file

@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Features = exports.FEATURE_FLAGS_FILE_NAME = exports.featureConfig = exports.Feature = exports.CODEQL_VERSION_FINE_GRAINED_PARALLELISM = exports.CODEQL_VERSION_BUNDLE_SEMANTICALLY_VERSIONED = void 0;
exports.isPythonDependencyInstallationDisabled = exports.Features = exports.FEATURE_FLAGS_FILE_NAME = exports.featureConfig = exports.Feature = exports.CODEQL_VERSION_FINE_GRAINED_PARALLELISM = exports.CODEQL_VERSION_BUNDLE_SEMANTICALLY_VERSIONED = void 0;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const semver = __importStar(require("semver"));
@ -52,6 +52,7 @@ var Feature;
Feature["CppDependencyInstallation"] = "cpp_dependency_installation_enabled";
Feature["DisableKotlinAnalysisEnabled"] = "disable_kotlin_analysis_enabled";
Feature["DisablePythonDependencyInstallationEnabled"] = "disable_python_dependency_installation_enabled";
Feature["PythonDefaultIsToSkipDependencyInstallationEnabled"] = "python_default_is_to_skip_dependency_installation_enabled";
Feature["EvaluatorFineGrainedParallelismEnabled"] = "evaluator_fine_grained_parallelism_enabled";
Feature["ExportDiagnosticsEnabled"] = "export_diagnostics_enabled";
Feature["QaTelemetryEnabled"] = "qa_telemetry_enabled";
@ -97,6 +98,15 @@ exports.featureConfig = {
minimumVersion: undefined,
defaultValue: false,
},
[Feature.PythonDefaultIsToSkipDependencyInstallationEnabled]: {
// we can reuse the same environment variable as above. If someone has set it to
// `true` in their workflow this means dependencies are not installed, setting it to
// `false` means dependencies _will_ be installed. The same semantics are applied
// here!
envVar: "CODEQL_ACTION_DISABLE_PYTHON_DEPENDENCY_INSTALLATION",
minimumVersion: "2.16.0",
defaultValue: false,
},
};
exports.FEATURE_FLAGS_FILE_NAME = "cached-feature-flags.json";
/**
@ -326,4 +336,9 @@ class GitHubFeatureFlags {
}
}
}
async function isPythonDependencyInstallationDisabled(codeql, features) {
return ((await features.getValue(Feature.DisablePythonDependencyInstallationEnabled, codeql)) ||
(await features.getValue(Feature.PythonDefaultIsToSkipDependencyInstallationEnabled, codeql)));
}
exports.isPythonDependencyInstallationDisabled = isPythonDependencyInstallationDisabled;
//# sourceMappingURL=feature-flags.js.map

File diff suppressed because one or more lines are too long

9
lib/init-action.js generated
View file

@ -145,7 +145,7 @@ async function run() {
await (0, init_1.checkInstallPython311)(config.languages, codeql);
if (config.languages.includes(languages_1.Language.python) &&
(0, actions_util_1.getRequiredInput)("setup-python-dependencies") === "true") {
if (await features.getValue(feature_flags_1.Feature.DisablePythonDependencyInstallationEnabled, codeql)) {
if (await (0, feature_flags_1.isPythonDependencyInstallationDisabled)(codeql, features)) {
logger.info("Skipping python dependency installation");
}
else {
@ -245,9 +245,14 @@ async function run() {
}
}
// Disable Python dependency extraction if feature flag set
if (await features.getValue(feature_flags_1.Feature.DisablePythonDependencyInstallationEnabled, codeql)) {
if (await (0, feature_flags_1.isPythonDependencyInstallationDisabled)(codeql, features)) {
core.exportVariable("CODEQL_EXTRACTOR_PYTHON_DISABLE_LIBRARY_EXTRACTION", "true");
}
else {
// From 2.16.0 the default for the python extractor is to not perform any library
// extraction, so we need to set this flag to enable it.
core.exportVariable("CODEQL_EXTRACTOR_PYTHON_FORCE_ENABLE_LIBRARY_EXTRACTION_UNTIL_2_17_0", "true");
}
const sourceRoot = path.resolve((0, util_1.getRequiredEnvParam)("GITHUB_WORKSPACE"), (0, actions_util_1.getOptionalInput)("source-root") || "");
const tracerConfig = await (0, init_1.runInit)(codeql, config, sourceRoot, "Runner.Worker.exe", (0, actions_util_1.getOptionalInput)("registries"), apiDetails, logger);
if (tracerConfig !== undefined) {

File diff suppressed because one or more lines are too long

View file

@ -12,7 +12,11 @@ import {
getCodeQL,
} from "./codeql";
import * as configUtils from "./config-utils";
import { FeatureEnablement, Feature } from "./feature-flags";
import {
FeatureEnablement,
Feature,
isPythonDependencyInstallationDisabled,
} from "./feature-flags";
import { isScannedLanguage, Language } from "./languages";
import { Logger } from "./logging";
import { DatabaseCreationTimings, EventReport } from "./status-report";
@ -122,12 +126,7 @@ async function setupPythonExtractor(
return;
}
if (
await features.getValue(
Feature.DisablePythonDependencyInstallationEnabled,
codeql,
)
) {
if (await isPythonDependencyInstallationDisabled(codeql, features)) {
logger.warning(
"We recommend that you remove the CODEQL_PYTHON environment variable from your workflow. This environment variable was originally used to specify a Python executable that included the dependencies of your Python code, however Python analysis no longer uses these dependencies." +
"\nIf you used CODEQL_PYTHON to force the version of Python to analyze as, please use CODEQL_EXTRACTOR_PYTHON_ANALYSIS_VERSION instead, such as 'CODEQL_EXTRACTOR_PYTHON_ANALYSIS_VERSION=2.7' or 'CODEQL_EXTRACTOR_PYTHON_ANALYSIS_VERSION=3.11'.",

View file

@ -48,6 +48,7 @@ export enum Feature {
CppDependencyInstallation = "cpp_dependency_installation_enabled",
DisableKotlinAnalysisEnabled = "disable_kotlin_analysis_enabled",
DisablePythonDependencyInstallationEnabled = "disable_python_dependency_installation_enabled",
PythonDefaultIsToSkipDependencyInstallationEnabled = "python_default_is_to_skip_dependency_installation_enabled",
EvaluatorFineGrainedParallelismEnabled = "evaluator_fine_grained_parallelism_enabled",
ExportDiagnosticsEnabled = "export_diagnostics_enabled",
QaTelemetryEnabled = "qa_telemetry_enabled",
@ -97,6 +98,15 @@ export const featureConfig: Record<
minimumVersion: undefined,
defaultValue: false,
},
[Feature.PythonDefaultIsToSkipDependencyInstallationEnabled]: {
// we can reuse the same environment variable as above. If someone has set it to
// `true` in their workflow this means dependencies are not installed, setting it to
// `false` means dependencies _will_ be installed. The same semantics are applied
// here!
envVar: "CODEQL_ACTION_DISABLE_PYTHON_DEPENDENCY_INSTALLATION",
minimumVersion: "2.16.0",
defaultValue: false,
},
};
/**
@ -441,3 +451,19 @@ class GitHubFeatureFlags {
}
}
}
export async function isPythonDependencyInstallationDisabled(
codeql: CodeQL,
features: FeatureEnablement,
): Promise<boolean> {
return (
(await features.getValue(
Feature.DisablePythonDependencyInstallationEnabled,
codeql,
)) ||
(await features.getValue(
Feature.PythonDefaultIsToSkipDependencyInstallationEnabled,
codeql,
))
);
}

View file

@ -16,7 +16,11 @@ import { getGitHubVersion } from "./api-client";
import { CodeQL } from "./codeql";
import * as configUtils from "./config-utils";
import { EnvVar } from "./environment";
import { Feature, Features } from "./feature-flags";
import {
Feature,
Features,
isPythonDependencyInstallationDisabled,
} from "./feature-flags";
import {
checkInstallPython311,
initCodeQL,
@ -289,12 +293,7 @@ async function run() {
config.languages.includes(Language.python) &&
getRequiredInput("setup-python-dependencies") === "true"
) {
if (
await features.getValue(
Feature.DisablePythonDependencyInstallationEnabled,
codeql,
)
) {
if (await isPythonDependencyInstallationDisabled(codeql, features)) {
logger.info("Skipping python dependency installation");
} else {
try {
@ -442,16 +441,18 @@ async function run() {
}
// Disable Python dependency extraction if feature flag set
if (
await features.getValue(
Feature.DisablePythonDependencyInstallationEnabled,
codeql,
)
) {
if (await isPythonDependencyInstallationDisabled(codeql, features)) {
core.exportVariable(
"CODEQL_EXTRACTOR_PYTHON_DISABLE_LIBRARY_EXTRACTION",
"true",
);
} else {
// From 2.16.0 the default for the python extractor is to not perform any library
// extraction, so we need to set this flag to enable it.
core.exportVariable(
"CODEQL_EXTRACTOR_PYTHON_FORCE_ENABLE_LIBRARY_EXTRACTION_UNTIL_2_17_0",
"true",
);
}
const sourceRoot = path.resolve(

View file

@ -1,21 +0,0 @@
const mongoose = require('mongoose');
Logger = require('./logger').Logger;
Note = require('./models/note').Note;
(async () => {
if (process.argv.length != 5) {
Logger.log("Creates a private note. Usage: node add-note.js <token> <title> <body>")
return;
}
// Open the default mongoose connection
await mongoose.connect('mongodb://localhost:27017/notes', { useFindAndModify: false });
const [userToken, title, body] = process.argv.slice(2);
await Note.create({ title, body, userToken });
Logger.log(`Created private note with title ${title} and body ${body} belonging to user with token ${userToken}.`);
await mongoose.connection.close();
})();

View file

@ -1,68 +0,0 @@
const bodyParser = require('body-parser');
const express = require('express');
const mongoose = require('mongoose');
const notesApi = require('./notes-api');
const usersApi = require('./users-api');
const addSampleData = module.exports.addSampleData = async () => {
const [userA, userB] = await User.create([
{
name: "A",
token: "tokenA"
},
{
name: "B",
token: "tokenB"
}
]);
await Note.create([
{
title: "Public note belonging to A",
body: "This is a public note belonging to A",
isPublic: true,
ownerToken: userA.token
},
{
title: "Public note belonging to B",
body: "This is a public note belonging to B",
isPublic: true,
ownerToken: userB.token
},
{
title: "Private note belonging to A",
body: "This is a private note belonging to A",
ownerToken: userA.token
},
{
title: "Private note belonging to B",
body: "This is a private note belonging to B",
ownerToken: userB.token
}
]);
}
module.exports.startApp = async () => {
// Open the default mongoose connection
await mongoose.connect('mongodb://mongo:27017/notes', { useFindAndModify: false });
// Drop contents of DB
mongoose.connection.dropDatabase();
// Add some sample data
await addSampleData();
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.get('/', async (_req, res) => {
res.send('Hello World');
});
app.use('/api/notes', notesApi.router);
app.use('/api/users', usersApi.router);
app.listen(3000);
Logger.log('Express started on port 3000');
};

View file

@ -1,7 +0,0 @@
const startApp = require('./app').startApp;
Logger = require('./logger').Logger;
Note = require('./models/note').Note;
User = require('./models/user').User;
startApp();

View file

@ -1,5 +0,0 @@
module.exports.Logger = class {
log(message, ...objs) {
console.log(message, objs);
}
};

View file

@ -1,8 +0,0 @@
const mongoose = require('mongoose');
module.exports.Note = mongoose.model('Note', new mongoose.Schema({
title: String,
body: String,
ownerToken: String,
isPublic: Boolean
}));

View file

@ -1,6 +0,0 @@
const mongoose = require('mongoose');
module.exports.User = mongoose.model('User', new mongoose.Schema({
name: String,
token: String
}));

View file

@ -1,44 +0,0 @@
const express = require('express')
const router = module.exports.router = express.Router();
function serializeNote(note) {
return {
title: note.title,
body: note.body
};
}
router.post('/find', async (req, res) => {
const notes = await Note.find({
ownerToken: req.body.token
}).exec();
res.json({
notes: notes.map(serializeNote)
});
});
router.get('/findPublic', async (_req, res) => {
const notes = await Note.find({
isPublic: true
}).exec();
res.json({
notes: notes.map(serializeNote)
});
});
router.post('/findVisible', async (req, res) => {
const notes = await Note.find({
$or: [
{
isPublic: true
},
{
ownerToken: req.body.token
}
]
}).exec();
res.json({
notes: notes.map(serializeNote)
});
});

View file

@ -1,37 +0,0 @@
const mongoose = require('mongoose');
Logger = require('./logger').Logger;
Note = require('./models/note').Note;
User = require('./models/user').User;
(async () => {
if (process.argv.length != 3) {
Logger.log("Outputs all notes visible to a user. Usage: node read-notes.js <token>")
return;
}
// Open the default mongoose connection
await mongoose.connect('mongodb://localhost:27017/notes', { useFindAndModify: false });
const ownerToken = process.argv[2];
const user = await User.findOne({
token: ownerToken
}).exec();
const notes = await Note.find({
$or: [
{ isPublic: true },
{ ownerToken }
]
}).exec();
notes.map(note => {
Logger.log("Title:" + note.title);
Logger.log("By:" + user.name);
Logger.log("Body:" + note.body);
Logger.log();
});
await mongoose.connection.close();
})();

View file

@ -1,25 +0,0 @@
const express = require('express')
Logger = require('./logger').Logger;
const router = module.exports.router = express.Router();
router.post('/updateName', async (req, res) => {
Logger.log("/updateName called with new name", req.body.name);
await User.findOneAndUpdate({
token: req.body.token
}, {
name: req.body.name
}).exec();
res.json({
name: req.body.name
});
});
router.post('/getName', async (req, res) => {
const user = await User.findOne({
token: req.body.token
}).exec();
res.json({
name: user.name
});
});