diff --git a/lib/analyze-action-post.js b/lib/analyze-action-post.js index 7c8823caa..6adbd9db4 100644 --- a/lib/analyze-action-post.js +++ b/lib/analyze-action-post.js @@ -161253,6 +161253,18 @@ var core6 = __toESM(require_core()); // src/config/db-config.ts var jsonschema = __toESM(require_lib2()); var semver2 = __toESM(require_semver2()); + +// src/feature-flags/properties.ts +var RepositoryPropertyName = /* @__PURE__ */ ((RepositoryPropertyName2) => { + RepositoryPropertyName2["DISABLE_OVERLAY"] = "github-codeql-disable-overlay"; + RepositoryPropertyName2["EXTRA_QUERIES"] = "github-codeql-extra-queries"; + return RepositoryPropertyName2; +})(RepositoryPropertyName || {}); +var KNOWN_REPOSITORY_PROPERTY_NAMES = new Set( + Object.values(RepositoryPropertyName) +); + +// src/config/db-config.ts var PACK_IDENTIFIER_PATTERN = (function() { const alphaNumeric = "[a-z0-9]"; const alphaNumericDash = "[a-z0-9-]"; diff --git a/lib/analyze-action.js b/lib/analyze-action.js index 806fd5c46..d20a7e6ff 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -107115,6 +107115,18 @@ function createCacheKeyHash(components) { // src/config/db-config.ts var jsonschema = __toESM(require_lib2()); var semver2 = __toESM(require_semver2()); + +// src/feature-flags/properties.ts +var RepositoryPropertyName = /* @__PURE__ */ ((RepositoryPropertyName2) => { + RepositoryPropertyName2["DISABLE_OVERLAY"] = "github-codeql-disable-overlay"; + RepositoryPropertyName2["EXTRA_QUERIES"] = "github-codeql-extra-queries"; + return RepositoryPropertyName2; +})(RepositoryPropertyName || {}); +var KNOWN_REPOSITORY_PROPERTY_NAMES = new Set( + Object.values(RepositoryPropertyName) +); + +// src/config/db-config.ts var PACK_IDENTIFIER_PATTERN = (function() { const alphaNumeric = "[a-z0-9]"; const alphaNumericDash = "[a-z0-9-]"; diff --git a/lib/autobuild-action.js b/lib/autobuild-action.js index 03b8b56cd..6a2dfbad6 100644 --- a/lib/autobuild-action.js +++ b/lib/autobuild-action.js @@ -103658,6 +103658,18 @@ var core6 = __toESM(require_core()); // src/config/db-config.ts var jsonschema = __toESM(require_lib2()); var semver2 = __toESM(require_semver2()); + +// src/feature-flags/properties.ts +var RepositoryPropertyName = /* @__PURE__ */ ((RepositoryPropertyName2) => { + RepositoryPropertyName2["DISABLE_OVERLAY"] = "github-codeql-disable-overlay"; + RepositoryPropertyName2["EXTRA_QUERIES"] = "github-codeql-extra-queries"; + return RepositoryPropertyName2; +})(RepositoryPropertyName || {}); +var KNOWN_REPOSITORY_PROPERTY_NAMES = new Set( + Object.values(RepositoryPropertyName) +); + +// src/config/db-config.ts var PACK_IDENTIFIER_PATTERN = (function() { const alphaNumeric = "[a-z0-9]"; const alphaNumericDash = "[a-z0-9-]"; diff --git a/lib/init-action-post.js b/lib/init-action-post.js index bc1294485..cb91c0bf3 100644 --- a/lib/init-action-post.js +++ b/lib/init-action-post.js @@ -164631,6 +164631,18 @@ var RiskAssessment = { // src/config/db-config.ts var jsonschema = __toESM(require_lib2()); var semver2 = __toESM(require_semver2()); + +// src/feature-flags/properties.ts +var RepositoryPropertyName = /* @__PURE__ */ ((RepositoryPropertyName2) => { + RepositoryPropertyName2["DISABLE_OVERLAY"] = "github-codeql-disable-overlay"; + RepositoryPropertyName2["EXTRA_QUERIES"] = "github-codeql-extra-queries"; + return RepositoryPropertyName2; +})(RepositoryPropertyName || {}); +var KNOWN_REPOSITORY_PROPERTY_NAMES = new Set( + Object.values(RepositoryPropertyName) +); + +// src/config/db-config.ts var PACK_IDENTIFIER_PATTERN = (function() { const alphaNumeric = "[a-z0-9]"; const alphaNumericDash = "[a-z0-9-]"; diff --git a/lib/init-action.js b/lib/init-action.js index ad82159e7..d78abb1b6 100644 --- a/lib/init-action.js +++ b/lib/init-action.js @@ -104283,17 +104283,25 @@ var RepositoryPropertyName = /* @__PURE__ */ ((RepositoryPropertyName2) => { RepositoryPropertyName2["EXTRA_QUERIES"] = "github-codeql-extra-queries"; return RepositoryPropertyName2; })(RepositoryPropertyName || {}); +var KNOWN_REPOSITORY_PROPERTY_NAMES = new Set( + Object.values(RepositoryPropertyName) +); function isKnownPropertyName(value) { - return Object.values(RepositoryPropertyName).includes( - value - ); + return KNOWN_REPOSITORY_PROPERTY_NAMES.has(value); } -var mapRepositoryProperties = { - ["github-codeql-disable-overlay" /* DISABLE_OVERLAY */]: (value) => value === "true", - ["github-codeql-extra-queries" /* EXTRA_QUERIES */]: (value) => value +var repositoryPropertyParsers = { + ["github-codeql-disable-overlay" /* DISABLE_OVERLAY */]: (name, value, logger) => { + if (value !== "true" && value !== "false") { + logger.warning( + `Repository property '${name}' has unexpected value '${value}'. Expected 'true' or 'false'. Defaulting to false.` + ); + } + return value === "true"; + }, + ["github-codeql-extra-queries" /* EXTRA_QUERIES */]: (_name, value) => value }; -function setProperty2(properties, name, value) { - properties[name] = mapRepositoryProperties[name](value); +function setProperty2(properties, name, value, logger) { + properties[name] = repositoryPropertyParsers[name](name, value, logger); } async function loadPropertiesFromApi(gitHubVersion, logger, repositoryNwo) { if (gitHubVersion.type === "GitHub Enterprise Server" /* GHES */) { @@ -104314,11 +104322,16 @@ async function loadPropertiesFromApi(gitHubVersion, logger, repositoryNwo) { for (const property of remoteProperties) { if (property.property_name === void 0) { throw new Error( - `Expected property object to have a 'property_name', but got: ${JSON.stringify(property)}` + `Expected repository property object to have a 'property_name', but got: ${JSON.stringify(property)}` + ); + } + if (typeof property.value !== "string") { + throw new Error( + `Expected repository property '${property.property_name}' to have a string value, but got: ${JSON.stringify(property)}` ); } if (isKnownPropertyName(property.property_name)) { - setProperty2(properties, property.property_name, property.value); + setProperty2(properties, property.property_name, property.value, logger); } } if (Object.keys(properties).length === 0) { diff --git a/lib/resolve-environment-action.js b/lib/resolve-environment-action.js index 8aac361a3..ad7b6c8ec 100644 --- a/lib/resolve-environment-action.js +++ b/lib/resolve-environment-action.js @@ -103657,6 +103657,18 @@ var core6 = __toESM(require_core()); // src/config/db-config.ts var jsonschema = __toESM(require_lib2()); var semver2 = __toESM(require_semver2()); + +// src/feature-flags/properties.ts +var RepositoryPropertyName = /* @__PURE__ */ ((RepositoryPropertyName2) => { + RepositoryPropertyName2["DISABLE_OVERLAY"] = "github-codeql-disable-overlay"; + RepositoryPropertyName2["EXTRA_QUERIES"] = "github-codeql-extra-queries"; + return RepositoryPropertyName2; +})(RepositoryPropertyName || {}); +var KNOWN_REPOSITORY_PROPERTY_NAMES = new Set( + Object.values(RepositoryPropertyName) +); + +// src/config/db-config.ts var PACK_IDENTIFIER_PATTERN = (function() { const alphaNumeric = "[a-z0-9]"; const alphaNumericDash = "[a-z0-9-]"; diff --git a/lib/setup-codeql-action.js b/lib/setup-codeql-action.js index 6a521cc92..099e162ae 100644 --- a/lib/setup-codeql-action.js +++ b/lib/setup-codeql-action.js @@ -104651,6 +104651,18 @@ var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); // src/config/db-config.ts var jsonschema = __toESM(require_lib2()); var semver5 = __toESM(require_semver2()); + +// src/feature-flags/properties.ts +var RepositoryPropertyName = /* @__PURE__ */ ((RepositoryPropertyName2) => { + RepositoryPropertyName2["DISABLE_OVERLAY"] = "github-codeql-disable-overlay"; + RepositoryPropertyName2["EXTRA_QUERIES"] = "github-codeql-extra-queries"; + return RepositoryPropertyName2; +})(RepositoryPropertyName || {}); +var KNOWN_REPOSITORY_PROPERTY_NAMES = new Set( + Object.values(RepositoryPropertyName) +); + +// src/config/db-config.ts var PACK_IDENTIFIER_PATTERN = (function() { const alphaNumeric = "[a-z0-9]"; const alphaNumericDash = "[a-z0-9-]"; diff --git a/lib/start-proxy-action-post.js b/lib/start-proxy-action-post.js index afed44174..78a4ed2a8 100644 --- a/lib/start-proxy-action-post.js +++ b/lib/start-proxy-action-post.js @@ -160888,6 +160888,18 @@ var core6 = __toESM(require_core()); // src/config/db-config.ts var jsonschema = __toESM(require_lib2()); var semver2 = __toESM(require_semver2()); + +// src/feature-flags/properties.ts +var RepositoryPropertyName = /* @__PURE__ */ ((RepositoryPropertyName2) => { + RepositoryPropertyName2["DISABLE_OVERLAY"] = "github-codeql-disable-overlay"; + RepositoryPropertyName2["EXTRA_QUERIES"] = "github-codeql-extra-queries"; + return RepositoryPropertyName2; +})(RepositoryPropertyName || {}); +var KNOWN_REPOSITORY_PROPERTY_NAMES = new Set( + Object.values(RepositoryPropertyName) +); + +// src/config/db-config.ts var PACK_IDENTIFIER_PATTERN = (function() { const alphaNumeric = "[a-z0-9]"; const alphaNumericDash = "[a-z0-9-]"; diff --git a/lib/start-proxy-action.js b/lib/start-proxy-action.js index 1f83e0a9f..daed18596 100644 --- a/lib/start-proxy-action.js +++ b/lib/start-proxy-action.js @@ -121258,6 +121258,18 @@ var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); // src/config/db-config.ts var jsonschema = __toESM(require_lib2()); var semver5 = __toESM(require_semver2()); + +// src/feature-flags/properties.ts +var RepositoryPropertyName = /* @__PURE__ */ ((RepositoryPropertyName2) => { + RepositoryPropertyName2["DISABLE_OVERLAY"] = "github-codeql-disable-overlay"; + RepositoryPropertyName2["EXTRA_QUERIES"] = "github-codeql-extra-queries"; + return RepositoryPropertyName2; +})(RepositoryPropertyName || {}); +var KNOWN_REPOSITORY_PROPERTY_NAMES = new Set( + Object.values(RepositoryPropertyName) +); + +// src/config/db-config.ts var PACK_IDENTIFIER_PATTERN = (function() { const alphaNumeric = "[a-z0-9]"; const alphaNumericDash = "[a-z0-9-]"; diff --git a/lib/upload-lib.js b/lib/upload-lib.js index 01383883e..f66b8ce9b 100644 --- a/lib/upload-lib.js +++ b/lib/upload-lib.js @@ -106710,6 +106710,18 @@ var core6 = __toESM(require_core()); // src/config/db-config.ts var jsonschema = __toESM(require_lib2()); var semver2 = __toESM(require_semver2()); + +// src/feature-flags/properties.ts +var RepositoryPropertyName = /* @__PURE__ */ ((RepositoryPropertyName2) => { + RepositoryPropertyName2["DISABLE_OVERLAY"] = "github-codeql-disable-overlay"; + RepositoryPropertyName2["EXTRA_QUERIES"] = "github-codeql-extra-queries"; + return RepositoryPropertyName2; +})(RepositoryPropertyName || {}); +var KNOWN_REPOSITORY_PROPERTY_NAMES = new Set( + Object.values(RepositoryPropertyName) +); + +// src/config/db-config.ts var PACK_IDENTIFIER_PATTERN = (function() { const alphaNumeric = "[a-z0-9]"; const alphaNumericDash = "[a-z0-9-]"; diff --git a/lib/upload-sarif-action-post.js b/lib/upload-sarif-action-post.js index 67c09a211..4e0869c70 100644 --- a/lib/upload-sarif-action-post.js +++ b/lib/upload-sarif-action-post.js @@ -161038,6 +161038,18 @@ var core6 = __toESM(require_core()); // src/config/db-config.ts var jsonschema = __toESM(require_lib5()); var semver2 = __toESM(require_semver2()); + +// src/feature-flags/properties.ts +var RepositoryPropertyName = /* @__PURE__ */ ((RepositoryPropertyName2) => { + RepositoryPropertyName2["DISABLE_OVERLAY"] = "github-codeql-disable-overlay"; + RepositoryPropertyName2["EXTRA_QUERIES"] = "github-codeql-extra-queries"; + return RepositoryPropertyName2; +})(RepositoryPropertyName || {}); +var KNOWN_REPOSITORY_PROPERTY_NAMES = new Set( + Object.values(RepositoryPropertyName) +); + +// src/config/db-config.ts var PACK_IDENTIFIER_PATTERN = (function() { const alphaNumeric = "[a-z0-9]"; const alphaNumericDash = "[a-z0-9-]"; diff --git a/lib/upload-sarif-action.js b/lib/upload-sarif-action.js index 34114e3ea..64189de33 100644 --- a/lib/upload-sarif-action.js +++ b/lib/upload-sarif-action.js @@ -107382,6 +107382,18 @@ var path7 = __toESM(require("path")); // src/config/db-config.ts var jsonschema = __toESM(require_lib2()); var semver5 = __toESM(require_semver2()); + +// src/feature-flags/properties.ts +var RepositoryPropertyName = /* @__PURE__ */ ((RepositoryPropertyName2) => { + RepositoryPropertyName2["DISABLE_OVERLAY"] = "github-codeql-disable-overlay"; + RepositoryPropertyName2["EXTRA_QUERIES"] = "github-codeql-extra-queries"; + return RepositoryPropertyName2; +})(RepositoryPropertyName || {}); +var KNOWN_REPOSITORY_PROPERTY_NAMES = new Set( + Object.values(RepositoryPropertyName) +); + +// src/config/db-config.ts var PACK_IDENTIFIER_PATTERN = (function() { const alphaNumeric = "[a-z0-9]"; const alphaNumericDash = "[a-z0-9-]"; diff --git a/src/feature-flags/properties.test.ts b/src/feature-flags/properties.test.ts index a7c425002..8cf8ef7cd 100644 --- a/src/feature-flags/properties.test.ts +++ b/src/feature-flags/properties.test.ts @@ -28,6 +28,9 @@ test("loadPropertiesFromApi throws if response data is not an array", async (t) logger, mockRepositoryNwo, ), + { + message: /Expected repository properties API to return an array/, + }, ); }); @@ -48,6 +51,9 @@ test("loadPropertiesFromApi throws if response data contains unexpected objects" logger, mockRepositoryNwo, ), + { + message: /Expected repository property object to have a 'property_name'/, + }, ); }); @@ -95,3 +101,117 @@ test("loadPropertiesFromApi loads known properties", async (t) => { ); t.deepEqual(response, { "github-codeql-extra-queries": "+queries" }); }); + +test("loadPropertiesFromApi parses true boolean property", async (t) => { + sinon.stub(api, "getRepositoryProperties").resolves({ + headers: {}, + status: 200, + url: "", + data: [ + { + property_name: "github-codeql-disable-overlay", + value: "true", + }, + { property_name: "github-codeql-extra-queries", value: "+queries" }, + ] satisfies properties.GitHubPropertiesResponse, + }); + const logger = getRunnerLogger(true); + const warningSpy = sinon.spy(logger, "warning"); + const mockRepositoryNwo = parseRepositoryNwo("owner/repo"); + const response = await properties.loadPropertiesFromApi( + { + type: util.GitHubVariant.DOTCOM, + }, + logger, + mockRepositoryNwo, + ); + t.deepEqual(response, { + "github-codeql-disable-overlay": true, + "github-codeql-extra-queries": "+queries", + }); + t.true(warningSpy.notCalled); +}); + +test("loadPropertiesFromApi parses false boolean property", async (t) => { + sinon.stub(api, "getRepositoryProperties").resolves({ + headers: {}, + status: 200, + url: "", + data: [ + { + property_name: "github-codeql-disable-overlay", + value: "false", + }, + ] satisfies properties.GitHubPropertiesResponse, + }); + const logger = getRunnerLogger(true); + const warningSpy = sinon.spy(logger, "warning"); + const mockRepositoryNwo = parseRepositoryNwo("owner/repo"); + const response = await properties.loadPropertiesFromApi( + { + type: util.GitHubVariant.DOTCOM, + }, + logger, + mockRepositoryNwo, + ); + t.deepEqual(response, { + "github-codeql-disable-overlay": false, + }); + t.true(warningSpy.notCalled); +}); + +test("loadPropertiesFromApi throws if property value is not a string", async (t) => { + sinon.stub(api, "getRepositoryProperties").resolves({ + headers: {}, + status: 200, + url: "", + data: [{ property_name: "github-codeql-extra-queries", value: 123 }], + }); + const logger = getRunnerLogger(true); + const mockRepositoryNwo = parseRepositoryNwo("owner/repo"); + await t.throwsAsync( + properties.loadPropertiesFromApi( + { + type: util.GitHubVariant.DOTCOM, + }, + logger, + mockRepositoryNwo, + ), + { + message: + /Expected repository property 'github-codeql-extra-queries' to have a string value/, + }, + ); +}); + +test("loadPropertiesFromApi warns if boolean property has unexpected value", async (t) => { + sinon.stub(api, "getRepositoryProperties").resolves({ + headers: {}, + status: 200, + url: "", + data: [ + { + property_name: "github-codeql-disable-overlay", + value: "yes", + }, + ] satisfies properties.GitHubPropertiesResponse, + }); + const logger = getRunnerLogger(true); + const warningSpy = sinon.spy(logger, "warning"); + const mockRepositoryNwo = parseRepositoryNwo("owner/repo"); + const response = await properties.loadPropertiesFromApi( + { + type: util.GitHubVariant.DOTCOM, + }, + logger, + mockRepositoryNwo, + ); + t.deepEqual(response, { + "github-codeql-disable-overlay": false, + }); + t.true(warningSpy.calledOnce); + t.is( + warningSpy.firstCall.args[0], + "Repository property 'github-codeql-disable-overlay' has unexpected value 'yes'. Expected 'true' or 'false'. Defaulting to false.", + ); +}); diff --git a/src/feature-flags/properties.ts b/src/feature-flags/properties.ts index 70af80129..9477cbad4 100644 --- a/src/feature-flags/properties.ts +++ b/src/feature-flags/properties.ts @@ -11,10 +11,12 @@ export enum RepositoryPropertyName { EXTRA_QUERIES = "github-codeql-extra-queries", } +const KNOWN_REPOSITORY_PROPERTY_NAMES = new Set( + Object.values(RepositoryPropertyName), +); + function isKnownPropertyName(value: string): value is RepositoryPropertyName { - return Object.values(RepositoryPropertyName).includes( - value as RepositoryPropertyName, - ); + return KNOWN_REPOSITORY_PROPERTY_NAMES.has(value); } type AllRepositoryProperties = { @@ -24,31 +26,45 @@ type AllRepositoryProperties = { export type RepositoryProperties = Partial; -const mapRepositoryProperties: { - [K in RepositoryPropertyName]: (value: string) => AllRepositoryProperties[K]; +/** Parsers that transform repository properties from the API response into typed values. */ +const repositoryPropertyParsers: { + [K in RepositoryPropertyName]: ( + name: K, + value: string, + logger: Logger, + ) => AllRepositoryProperties[K]; } = { - [RepositoryPropertyName.DISABLE_OVERLAY]: (value) => value === "true", - [RepositoryPropertyName.EXTRA_QUERIES]: (value) => value, + [RepositoryPropertyName.DISABLE_OVERLAY]: (name, value, logger) => { + if (value !== "true" && value !== "false") { + logger.warning( + `Repository property '${name}' has unexpected value '${value}'. Expected 'true' or 'false'. Defaulting to false.`, + ); + } + return value === "true"; + }, + [RepositoryPropertyName.EXTRA_QUERIES]: (_name, value) => value, }; +/** Update the partial set of repository properties with the parsed value of the specified property. */ function setProperty( properties: RepositoryProperties, name: K, value: string, + logger: Logger, ): void { - properties[name] = mapRepositoryProperties[name](value); + properties[name] = repositoryPropertyParsers[name](name, value, logger); } /** * A repository property has a name and a value. */ -interface GitHubRepositoryProperty { +export interface GitHubRepositoryProperty { property_name: string; value: string; } /** - * The API returns a list of `RepositoryProperty` objects. + * The API returns a list of `GitHubRepositoryProperty` objects. */ export type GitHubPropertiesResponse = GitHubRepositoryProperty[]; @@ -88,12 +104,18 @@ export async function loadPropertiesFromApi( for (const property of remoteProperties) { if (property.property_name === undefined) { throw new Error( - `Expected property object to have a 'property_name', but got: ${JSON.stringify(property)}`, + `Expected repository property object to have a 'property_name', but got: ${JSON.stringify(property)}`, + ); + } + + if (typeof property.value !== "string") { + throw new Error( + `Expected repository property '${property.property_name}' to have a string value, but got: ${JSON.stringify(property)}`, ); } if (isKnownPropertyName(property.property_name)) { - setProperty(properties, property.property_name, property.value); + setProperty(properties, property.property_name, property.value, logger); } }