From 4fb6147969a038746b5bcc1b4b0e37f0cb22d0b6 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 13 Jul 2026 16:36:51 +0100 Subject: [PATCH 1/6] Add `ReadOnlyEnv` to `FeatureState` --- src/action-common.ts | 5 ++++- src/testing-utils.ts | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/action-common.ts b/src/action-common.ts index dc76e9fdbb..2f071ce206 100644 --- a/src/action-common.ts +++ b/src/action-common.ts @@ -1,7 +1,7 @@ import * as core from "@actions/core"; import { ActionsEnv, getActionsEnv } from "./actions-util"; -import { Env } from "./environment"; +import { Env, ReadOnlyEnv } from "./environment"; import { FeatureEnablement } from "./feature-flags"; import { getActionsLogger, Logger } from "./logging"; import { @@ -29,6 +29,9 @@ export interface FeatureState { /** Information about environment variables. */ env: Env; }; + ReadOnlyEnv: { + env: ReadOnlyEnv; + }; Actions: { /** Access to Actions-related functionality. */ actions: ActionsEnv; diff --git a/src/testing-utils.ts b/src/testing-utils.ts index 60e8fb5540..c234e2e505 100644 --- a/src/testing-utils.ts +++ b/src/testing-utils.ts @@ -193,7 +193,7 @@ export function getTestActionsEnv(): ActionsEnv { } /** For testing purposes, we make all available state features accessible in `TestEnv`. */ -type AllState = ["Logger", "Env", "Actions", "FeatureFlags"]; +type AllState = ["Logger", "Env", "ReadOnlyEnv", "Actions", "FeatureFlags"]; /** Initialise a fresh `ActionState` value. */ export function initAllState( From 1542951d09805730bf3cced2fde315c7f571a834 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 13 Jul 2026 16:51:59 +0100 Subject: [PATCH 2/6] Type the API client --- src/api-client.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/api-client.ts b/src/api-client.ts index eafac7ec76..1a4d421fe8 100644 --- a/src/api-client.ts +++ b/src/api-client.ts @@ -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 { getActionVersion, getRequiredInput } from "./actions-util"; @@ -43,10 +46,13 @@ export interface GitHubApiExternalRepoDetails { apiURL: string | undefined; } +/** The type of GitHub API client we use. */ +export type ApiClient = Octokit & Api & { paginate: PaginateInterface }; + function createApiClientWithDetails( apiDetails: GitHubApiCombinedDetails, { allowExternal = false } = {}, -) { +): ApiClient { const auth = (allowExternal && apiDetails.externalRepoAuth) || apiDetails.auth; const retryingOctokit = githubUtils.GitHub.plugin(retry.retry); From 2dbfdcaa83fbf4757beee5dff1e9e663b058fde3 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 13 Jul 2026 16:55:44 +0100 Subject: [PATCH 3/6] Add `Api` to `ActionState` --- src/action-common.ts | 7 ++++++- src/testing-utils.ts | 10 +++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/action-common.ts b/src/action-common.ts index 2f071ce206..5ea008d010 100644 --- a/src/action-common.ts +++ b/src/action-common.ts @@ -1,8 +1,9 @@ import * as core from "@actions/core"; import { ActionsEnv, getActionsEnv } from "./actions-util"; +import type { ApiClient } from "./api-client"; import { Env, ReadOnlyEnv } from "./environment"; -import { FeatureEnablement } from "./feature-flags"; +import type { FeatureEnablement } from "./feature-flags"; import { getActionsLogger, Logger } from "./logging"; import { ActionName, @@ -36,6 +37,10 @@ export interface FeatureState { /** Access to Actions-related functionality. */ actions: ActionsEnv; }; + Api: { + /** A GitHub API client. */ + apiClient: ApiClient; + }; FeatureFlags: { /** Information about enabled feature flags. */ features: FeatureEnablement; diff --git a/src/testing-utils.ts b/src/testing-utils.ts index c234e2e505..8ef102caf9 100644 --- a/src/testing-utils.ts +++ b/src/testing-utils.ts @@ -193,7 +193,14 @@ export function getTestActionsEnv(): ActionsEnv { } /** For testing purposes, we make all available state features accessible in `TestEnv`. */ -type AllState = ["Logger", "Env", "ReadOnlyEnv", "Actions", "FeatureFlags"]; +type AllState = [ + "Logger", + "Env", + "ReadOnlyEnv", + "Actions", + "Api", + "FeatureFlags", +]; /** Initialise a fresh `ActionState` value. */ export function initAllState( @@ -205,6 +212,7 @@ export function initAllState( logger: new RecordingLogger(), env: getTestEnv(), actions: getTestActionsEnv(), + apiClient: github.getOctokit("123"), features: createFeatures([]), ...overrides, }; From 2f9048cfbd5c1d845b5e61a47dad45d5ca07bdf5 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Tue, 14 Jul 2026 10:12:44 +0100 Subject: [PATCH 4/6] Require `BaseState` to be declared explicitly --- src/action-common.ts | 5 +++-- src/analyze-action.ts | 2 +- src/autobuild-action.ts | 2 +- src/init-action.ts | 4 +++- src/setup-codeql-action.ts | 2 +- src/testing-utils.ts | 1 + src/upload-sarif-action.ts | 2 +- 7 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/action-common.ts b/src/action-common.ts index 5ea008d010..9929a00161 100644 --- a/src/action-common.ts +++ b/src/action-common.ts @@ -22,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; @@ -52,7 +53,7 @@ export type StateFeature = keyof FeatureState; /** Constructs the intersection of all state types identifies by `Fs`. */ export type FieldsOf = Fs extends [] - ? BaseState + ? Record : Fs extends [ infer Head extends StateFeature, ...infer Tail extends readonly StateFeature[], @@ -68,7 +69,7 @@ export type ActionState = FieldsOf; * 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; /** A specification for a CodeQL Action step. */ diff --git a/src/analyze-action.ts b/src/analyze-action.ts index f7cbbaabe3..5104719bc7 100644 --- a/src/analyze-action.ts +++ b/src/analyze-action.ts @@ -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. diff --git a/src/autobuild-action.ts b/src/autobuild-action.ts index afda0e236a..b78bffb9d8 100644 --- a/src/autobuild-action.ts +++ b/src/autobuild-action.ts @@ -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. diff --git a/src/init-action.ts b/src/init-action.ts index acaba701be..8d0434160b 100644 --- a/src/init-action.ts +++ b/src/init-action.ts @@ -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. diff --git a/src/setup-codeql-action.ts b/src/setup-codeql-action.ts index a6b5f83f5e..3336afc1a2 100644 --- a/src/setup-codeql-action.ts +++ b/src/setup-codeql-action.ts @@ -90,7 +90,7 @@ async function sendCompletedStatusReport( async function run({ startedAt, logger, -}: ActionState<["Logger"]>): Promise { +}: ActionState<["Base", "Logger"]>): Promise { // To capture errors appropriately, keep as much code within the try-catch as // possible, and only use safe functions outside. diff --git a/src/testing-utils.ts b/src/testing-utils.ts index 8ef102caf9..3bd30320e4 100644 --- a/src/testing-utils.ts +++ b/src/testing-utils.ts @@ -194,6 +194,7 @@ export function getTestActionsEnv(): ActionsEnv { /** For testing purposes, we make all available state features accessible in `TestEnv`. */ type AllState = [ + "Base", "Logger", "Env", "ReadOnlyEnv", diff --git a/src/upload-sarif-action.ts b/src/upload-sarif-action.ts index 214f3bf980..d3437510ce 100644 --- a/src/upload-sarif-action.ts +++ b/src/upload-sarif-action.ts @@ -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 { From 28a0813a12a5de1afe21e3fd2b3bfed402e41b95 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Tue, 14 Jul 2026 14:44:54 +0100 Subject: [PATCH 5/6] Fix comment --- src/action-common.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/action-common.ts b/src/action-common.ts index 9929a00161..cbb1cd3422 100644 --- a/src/action-common.ts +++ b/src/action-common.ts @@ -12,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; From 4f688dedd0d790c9ab67b0b7095a45b227d5bd9b Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Tue, 14 Jul 2026 14:45:17 +0100 Subject: [PATCH 6/6] Make dependencies explicit --- package-lock.json | 3 +++ package.json | 3 +++ 2 files changed, 6 insertions(+) diff --git a/package-lock.json b/package-lock.json index 208964cbcc..2e8c4006c0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,6 +22,9 @@ "@actions/http-client": "^3.0.0", "@actions/io": "^2.0.0", "@actions/tool-cache": "^3.0.1", + "@octokit/core": "^7.0.6", + "@octokit/plugin-paginate-rest": "^14.0.0", + "@octokit/plugin-rest-endpoint-methods": "^17.0.0", "@octokit/plugin-retry": "^8.1.0", "archiver": "^8.0.0", "fast-deep-equal": "^3.1.3", diff --git a/package.json b/package.json index b1190b0438..efafe1742c 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,9 @@ "@actions/http-client": "^3.0.0", "@actions/io": "^2.0.0", "@actions/tool-cache": "^3.0.1", + "@octokit/core": "^7.0.6", + "@octokit/plugin-paginate-rest": "^14.0.0", + "@octokit/plugin-rest-endpoint-methods": "^17.0.0", "@octokit/plugin-retry": "^8.1.0", "archiver": "^8.0.0", "fast-deep-equal": "^3.1.3",