mirror of
https://github.com/github/codeql-action.git
synced 2026-04-28 01:48:48 +00:00
120 lines
3.6 KiB
TypeScript
120 lines
3.6 KiB
TypeScript
import { getRepositoryProperties } from "../api-client";
|
|
import { Logger } from "../logging";
|
|
import { RepositoryNwo } from "../repository";
|
|
import { GitHubVariant, GitHubVersion } from "../util";
|
|
|
|
/**
|
|
* Enumerates repository property names that have some meaning to us.
|
|
*/
|
|
export enum RepositoryPropertyName {
|
|
DISABLE_OVERLAY = "github-codeql-disable-overlay",
|
|
EXTRA_QUERIES = "github-codeql-extra-queries",
|
|
}
|
|
|
|
function isKnownPropertyName(value: string): value is RepositoryPropertyName {
|
|
return Object.values(RepositoryPropertyName).includes(
|
|
value as RepositoryPropertyName,
|
|
);
|
|
}
|
|
|
|
type AllRepositoryProperties = {
|
|
[RepositoryPropertyName.DISABLE_OVERLAY]: boolean;
|
|
[RepositoryPropertyName.EXTRA_QUERIES]: string;
|
|
};
|
|
|
|
export type RepositoryProperties = Partial<AllRepositoryProperties>;
|
|
|
|
const mapRepositoryProperties: {
|
|
[K in RepositoryPropertyName]: (value: string) => AllRepositoryProperties[K];
|
|
} = {
|
|
[RepositoryPropertyName.DISABLE_OVERLAY]: (value) => value === "true",
|
|
[RepositoryPropertyName.EXTRA_QUERIES]: (value) => value,
|
|
};
|
|
|
|
function setProperty<K extends RepositoryPropertyName>(
|
|
properties: RepositoryProperties,
|
|
name: K,
|
|
value: string,
|
|
): void {
|
|
properties[name] = mapRepositoryProperties[name](value);
|
|
}
|
|
|
|
/**
|
|
* A repository property has a name and a value.
|
|
*/
|
|
interface GitHubRepositoryProperty {
|
|
property_name: string;
|
|
value: string;
|
|
}
|
|
|
|
/**
|
|
* The API returns a list of `RepositoryProperty` objects.
|
|
*/
|
|
export type GitHubPropertiesResponse = GitHubRepositoryProperty[];
|
|
|
|
/**
|
|
* Retrieves all known repository properties from the API.
|
|
*
|
|
* @param logger The logger to use.
|
|
* @param repositoryNwo Information about the repository for which to load properties.
|
|
* @returns Returns a partial mapping from `RepositoryPropertyName` to values.
|
|
*/
|
|
export async function loadPropertiesFromApi(
|
|
gitHubVersion: GitHubVersion,
|
|
logger: Logger,
|
|
repositoryNwo: RepositoryNwo,
|
|
): Promise<RepositoryProperties> {
|
|
// TODO: To be safe for now; later we should replace this with a version check once we know
|
|
// which version of GHES we expect this to be supported by.
|
|
if (gitHubVersion.type === GitHubVariant.GHES) {
|
|
return {};
|
|
}
|
|
|
|
try {
|
|
const response = await getRepositoryProperties(repositoryNwo);
|
|
const remoteProperties = response.data as GitHubPropertiesResponse;
|
|
|
|
if (!Array.isArray(remoteProperties)) {
|
|
throw new Error(
|
|
`Expected repository properties API to return an array, but got: ${JSON.stringify(response.data)}`,
|
|
);
|
|
}
|
|
|
|
logger.debug(
|
|
`Retrieved ${remoteProperties.length} repository properties: ${remoteProperties.map((p) => p.property_name).join(", ")}`,
|
|
);
|
|
|
|
const properties: RepositoryProperties = {};
|
|
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)}`,
|
|
);
|
|
}
|
|
|
|
if (isKnownPropertyName(property.property_name)) {
|
|
setProperty(properties, property.property_name, property.value);
|
|
}
|
|
}
|
|
|
|
if (Object.keys(properties).length === 0) {
|
|
logger.debug("No known repository properties were found.");
|
|
} else {
|
|
logger.debug(
|
|
"Loaded the following values for the repository properties:",
|
|
);
|
|
for (const [property, value] of Object.entries(properties).sort(
|
|
([nameA], [nameB]) => nameA.localeCompare(nameB),
|
|
)) {
|
|
logger.debug(` ${property}: ${value}`);
|
|
}
|
|
}
|
|
|
|
return properties;
|
|
} catch (e) {
|
|
throw new Error(
|
|
`Encountered an error while trying to determine repository properties: ${e}`,
|
|
);
|
|
}
|
|
}
|