Merge remote-tracking branch 'origin/main' into mbg/use-registry-proxy-for-repo-auth

This commit is contained in:
Michael B. Gale
2026-07-16 12:48:24 +01:00
32 changed files with 247 additions and 224 deletions

View File

@@ -1,8 +1,9 @@
import * as core from "@actions/core";
import { ActionsEnv, getActionsEnv } from "./actions-util";
import { Env } from "./environment";
import { FeatureEnablement } from "./feature-flags";
import type { ApiClient } from "./api-client";
import { Env, ReadOnlyEnv } from "./environment";
import type { FeatureEnablement } from "./feature-flags";
import { getActionsLogger, Logger } from "./logging";
import {
ActionName,
@@ -11,7 +12,7 @@ import {
} from "./status-report";
import { getEnv, getErrorMessage } from "./util";
/** Common state that is always available in `ActionState`. */
/** Base state that is available to an Action on startup. */
export interface BaseState {
/** The name of the Action. */
name: ActionName;
@@ -21,6 +22,7 @@ export interface BaseState {
/** Describes different state features that an Action may have. */
export interface FeatureState {
Base: BaseState;
Logger: {
/** The logger that is in use. */
logger: Logger;
@@ -29,10 +31,17 @@ export interface FeatureState {
/** Information about environment variables. */
env: Env;
};
ReadOnlyEnv: {
env: ReadOnlyEnv;
};
Actions: {
/** Access to Actions-related functionality. */
actions: ActionsEnv;
};
Api: {
/** A GitHub API client. */
apiClient: ApiClient;
};
FeatureFlags: {
/** Information about enabled feature flags. */
features: FeatureEnablement;
@@ -44,7 +53,7 @@ export type StateFeature = keyof FeatureState;
/** Constructs the intersection of all state types identifies by `Fs`. */
export type FieldsOf<Fs extends readonly StateFeature[]> = Fs extends []
? BaseState
? Record<never, never>
: Fs extends [
infer Head extends StateFeature,
...infer Tail extends readonly StateFeature[],
@@ -60,7 +69,7 @@ export type ActionState<Fs extends readonly StateFeature[]> = FieldsOf<Fs>;
* Each Action can then augment the `state` further if additional features are required.
*/
export type ActionMain = (
state: ActionState<["Logger", "Env", "Actions"]>,
state: ActionState<["Base", "Logger", "Env", "Actions"]>,
) => Promise<void>;
/** A specification for a CodeQL Action step. */

View File

@@ -212,7 +212,7 @@ async function runAutobuildIfLegacyGoWorkflow(config: Config, logger: Logger) {
await runAutobuild(config, BuiltInLanguage.go, logger);
}
async function run({ startedAt, logger }: ActionState<["Logger"]>) {
async function run({ startedAt, logger }: ActionState<["Base", "Logger"]>) {
// To capture errors appropriately, keep as much code within the try-catch as
// possible, and only use safe functions outside.

View File

@@ -1,5 +1,8 @@
import * as core from "@actions/core";
import * as githubUtils from "@actions/github/lib/utils";
import { type Octokit } from "@octokit/core";
import { type PaginateInterface } from "@octokit/plugin-paginate-rest";
import { type Api } from "@octokit/plugin-rest-endpoint-methods";
import * as retry from "@octokit/plugin-retry";
import { RequestRequestOptions } from "@octokit/types";
import {
@@ -122,6 +125,10 @@ export function getApiFetch(
return proxiedFetch;
}
/** The type of GitHub API client we use. */
export type ApiClient = Octokit & Api & { paginate: PaginateInterface };
/** Options for `createApiClientWithDetails`. */
interface CreateApiClientOptions {
allowExternal?: boolean;
proxy?: ProxyAgent;
@@ -130,7 +137,7 @@ interface CreateApiClientOptions {
function createApiClientWithDetails(
apiDetails: GitHubApiCombinedDetails,
{ allowExternal = false, proxy = undefined }: CreateApiClientOptions = {},
) {
): ApiClient {
const auth =
(allowExternal && apiDetails.externalRepoAuth) || apiDetails.auth;
const retryingOctokit = githubUtils.GitHub.plugin(retry.retry);

View File

@@ -68,7 +68,7 @@ async function sendCompletedStatusReport(
}
}
async function run({ startedAt, logger }: ActionState<["Logger"]>) {
async function run({ startedAt, logger }: ActionState<["Base", "Logger"]>) {
// To capture errors appropriately, keep as much code within the try-catch as
// possible, and only use safe functions outside.

View File

@@ -125,6 +125,7 @@ export function mergeDefaultSetupAndUserConfigs(
{
invalidKeys: schemaCheckResult.invalidKeys,
},
["internal-error"],
),
);
}
@@ -140,6 +141,7 @@ export function mergeDefaultSetupAndUserConfigs(
{
unrecognisedKeys: schemaCheckResult.unknownKeys,
},
["internal-error"],
),
);
}

View File

@@ -1,6 +1,6 @@
{
"bundleVersion": "codeql-bundle-v2.26.0",
"cliVersion": "2.26.0",
"priorBundleVersion": "codeql-bundle-v2.25.6",
"priorCliVersion": "2.25.6"
"bundleVersion": "codeql-bundle-v2.26.1",
"cliVersion": "2.26.1",
"priorBundleVersion": "codeql-bundle-v2.26.0",
"priorCliVersion": "2.26.0"
}

View File

@@ -6,24 +6,45 @@ import { Language } from "./languages";
import { getActionsLogger } from "./logging";
import { getCodeQLDatabasePath } from "./util";
/** Represents a diagnostic message for the tool status page, etc. */
export interface DiagnosticMessage {
/**
* Known tags for diagnostics. There is currently only "internal-error",
* but others may be added in the future.
*/
export type DiagnosticTag = "internal-error";
/** Optional information about the origin of a diagnostic. */
export type DiagnosticSourceOptions = {
/**
* Name of the CodeQL extractor. This is used to identify which tool component the reporting
* descriptor object should be nested under in SARIF.
*/
extractorName?: string;
/** An array of tags for the diagnostic. */
tags?: DiagnosticTag[];
};
/** Represents information about the origin of a diagnostic. */
export type DiagnosticSource = {
/**
* An identifier under which it makes sense to group this diagnostic message.
* This is used to build the SARIF reporting descriptor object.
*/
id: string;
/** Display name for the ID. This is used to build the SARIF reporting descriptor object. */
name: string;
} & DiagnosticSourceOptions;
/**
* Represents a diagnostic message for the tool status page, etc.
*
* Unlike {@link DiagnosticMessage}, properties which can automatically
* be populated are optional in this type.
*/
export type DiagnosticMessageOptions = {
/** ISO 8601 timestamp */
timestamp: string;
source: {
/**
* An identifier under which it makes sense to group this diagnostic message.
* This is used to build the SARIF reporting descriptor object.
*/
id: string;
/** Display name for the ID. This is used to build the SARIF reporting descriptor object. */
name: string;
/**
* Name of the CodeQL extractor. This is used to identify which tool component the reporting
* descriptor object should be nested under in SARIF.
*/
extractorName?: string;
};
timestamp?: string;
/** Information about the origin of the diagnostic. */
source?: DiagnosticSourceOptions;
/** GitHub flavored Markdown formatted message. Should include inline links to any help pages. */
markdownMessage?: string;
/** Plain text message. Used by components where the string processing needed to support Markdown is cumbersome. */
@@ -53,7 +74,15 @@ export interface DiagnosticMessage {
};
/** Structured metadata about the diagnostic message */
attributes?: { [key: string]: any };
}
};
/** Represents a diagnostic message for the tool status page, etc. */
export type DiagnosticMessage = DiagnosticMessageOptions & {
/** ISO 8601 timestamp */
timestamp: string;
/** Information about the origin of the diagnostic. */
source: DiagnosticSource;
};
/** Represents a diagnostic message that has not yet been written to the database. */
interface UnwrittenDiagnostic {
@@ -90,7 +119,7 @@ let diagnosticCounter = 0;
export function makeDiagnostic(
id: string,
name: string,
data: Partial<DiagnosticMessage> | undefined = undefined,
data: DiagnosticMessageOptions | undefined = undefined,
): DiagnosticMessage {
return {
...data,
@@ -243,6 +272,7 @@ export function makeTelemetryDiagnostic(
id: string,
name: string,
attributes: { [key: string]: any },
tags?: DiagnosticTag[],
): DiagnosticMessage {
return makeDiagnostic(id, name, {
attributes,
@@ -251,5 +281,8 @@ export function makeTelemetryDiagnostic(
statusPage: false,
telemetry: true,
},
source: {
tags,
},
});
}

View File

@@ -203,7 +203,9 @@ async function sendCompletedStatusReport(
}
}
async function run(actionState: ActionState<["Logger", "Env", "Actions"]>) {
async function run(
actionState: ActionState<["Base", "Logger", "Env", "Actions"]>,
) {
// To capture errors appropriately, keep as much code within the try-catch as
// possible, and only use safe functions outside.

View File

@@ -90,7 +90,7 @@ async function sendCompletedStatusReport(
async function run({
startedAt,
logger,
}: ActionState<["Logger"]>): Promise<void> {
}: ActionState<["Base", "Logger"]>): Promise<void> {
// To capture errors appropriately, keep as much code within the try-catch as
// possible, and only use safe functions outside.

View File

@@ -192,7 +192,15 @@ export function getTestActionsEnv(): ActionsEnv {
}
/** For testing purposes, we make all available state features accessible in `TestEnv`. */
type AllState = ["Logger", "Env", "Actions", "FeatureFlags"];
type AllState = [
"Base",
"Logger",
"Env",
"ReadOnlyEnv",
"Actions",
"Api",
"FeatureFlags",
];
/** Initialise a fresh `ActionState<AllState>` value. */
export function initAllState(
@@ -204,6 +212,7 @@ export function initAllState(
logger: new RecordingLogger(),
env: getTestEnv(),
actions: getTestActionsEnv(),
apiClient: github.getOctokit("123"),
features: createFeatures([]),
...overrides,
};

View File

@@ -54,7 +54,7 @@ async function sendSuccessStatusReport(
}
}
async function run({ startedAt, logger }: ActionState<["Logger"]>) {
async function run({ startedAt, logger }: ActionState<["Base", "Logger"]>) {
// To capture errors appropriately, keep as much code within the try-catch as
// possible, and only use safe functions outside.
try {