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", diff --git a/src/action-common.ts b/src/action-common.ts index dc76e9fdbb..cbb1cd3422 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 { 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 [] - ? BaseState + ? Record : Fs extends [ infer Head extends StateFeature, ...infer Tail extends readonly StateFeature[], @@ -60,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/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); 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 60e8fb5540..3bd30320e4 100644 --- a/src/testing-utils.ts +++ b/src/testing-utils.ts @@ -193,7 +193,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` value. */ export function initAllState( @@ -205,6 +213,7 @@ export function initAllState( logger: new RecordingLogger(), env: getTestEnv(), actions: getTestActionsEnv(), + apiClient: github.getOctokit("123"), features: createFeatures([]), ...overrides, }; 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 {