Add minimal proxy init code

This commit is contained in:
Michael B. Gale
2026-07-08 16:24:23 +01:00
parent 5172487de5
commit a29dee455c
3 changed files with 121 additions and 10 deletions

View File

@@ -6,7 +6,7 @@ import * as sinon from "sinon";
import * as actionsUtil from "./actions-util";
import * as api from "./api-client";
import { DO_NOT_RETRY_STATUSES } from "./api-client";
import { ActionsEnvVars } from "./environment";
import { ActionsEnvVars, RegistryProxyVars } from "./environment";
import { getTestEnv, setupTests } from "./testing-utils";
import * as util from "./util";
@@ -27,14 +27,17 @@ test.serial("getApiClient", async (t) => {
sinon.stub(actionsUtil, "getRequiredInput").withArgs("token").returns("xyz");
api.getApiClient(env);
const apiClient = api.getApiClient(env);
t.truthy(apiClient);
t.true(githubStub.calledOnce);
t.assert(
githubStub.calledOnceWithExactly({
auth: "token xyz",
baseUrl: "http://api.github.localhost",
log: sinon.match.any,
userAgent: `CodeQL-Action/${actionsUtil.getActionVersion()}`,
request: sinon.match.any,
retry: {
doNotRetry: DO_NOT_RETRY_STATUSES,
},
@@ -204,3 +207,32 @@ test.serial(
}
},
);
test("getRegistryProxy - returns undefined if the proxy is not configured", async (t) => {
// Empty environment.
t.is(api.getRegistryProxy(getTestEnv()), undefined);
// Only the host.
t.is(
api.getRegistryProxy(
getTestEnv({ [RegistryProxyVars.PROXY_HOST]: "localhost" }),
),
undefined,
);
// Only the port.
t.is(
api.getRegistryProxy(
getTestEnv({ [RegistryProxyVars.PROXY_PORT]: "1234" }),
),
undefined,
);
});
test("getRegistryProxy - returns value when both vars are set", async (t) => {
const proxy = api.getRegistryProxy(
getTestEnv({
[RegistryProxyVars.PROXY_HOST]: "localhost",
[RegistryProxyVars.PROXY_PORT]: "1234",
}),
);
t.truthy(proxy);
});

View File

@@ -1,9 +1,21 @@
import * as core from "@actions/core";
import * as githubUtils from "@actions/github/lib/utils";
import * as retry from "@octokit/plugin-retry";
import {
ProxyAgent,
RequestInfo,
RequestInit,
fetch as undiciFetch,
} from "undici";
import { getActionVersion, getRequiredInput } from "./actions-util";
import { EnvVar, ReadOnlyEnv, ActionsEnvVars, getEnv } from "./environment";
import {
ActionsEnvVars,
EnvVar,
ReadOnlyEnv,
RegistryProxyVars,
getEnv,
} from "./environment";
import { Logger } from "./logging";
import { getRepositoryNwo, RepositoryNwo } from "./repository";
import {
@@ -43,6 +55,47 @@ export interface GitHubApiExternalRepoDetails {
apiURL: string | undefined;
}
/**
* Gets the configuration for the private registry authentication proxy,
* if it is available in the environment.
*
* @param env The environment to query for the proxy host and port.
* @returns A `ProxyAgent` corresponding to the private registry proxy,
* or `undefined` if we couldn't retrieve the host and port.
*/
export function getRegistryProxy(env: ReadOnlyEnv): ProxyAgent | undefined {
const host = env.getOptional(RegistryProxyVars.PROXY_HOST);
const port = env.getOptional(RegistryProxyVars.PROXY_PORT);
const cert = env.getOptional(RegistryProxyVars.PROXY_CA_CERTIFICATE);
if (host && port) {
return new ProxyAgent({
uri: `http://${host}:${port}`,
keepAliveTimeout: 10,
keepAliveMaxTimeout: 10,
requestTls: cert ? { ca: cert } : undefined,
});
}
return undefined;
}
/**
* Returns an implementation of `fetch` to use for API requests.
* This will run API requests through the private registry authentication proxy
* if it is configured.
*
* @param env The environment to query for the proxy host and port.
*/
export function getApiFetch(env: ReadOnlyEnv): typeof undiciFetch {
const dispatcher = getRegistryProxy(env);
const proxiedFetch = (req: RequestInfo, init?: RequestInit) => {
return undiciFetch(req, { ...init, dispatcher });
};
return proxiedFetch;
}
function createApiClientWithDetails(
apiDetails: GitHubApiCombinedDetails,
{ allowExternal = false } = {},
@@ -60,6 +113,7 @@ function createApiClientWithDetails(
warn: core.warning,
error: core.error,
},
request: { fetch: getApiFetch(getEnv()) },
retry: {
doNotRetry: DO_NOT_RETRY_STATUSES,
},