Refactor parseNewRemoteFileAddress out of parseRemoteFileAddress

This commit is contained in:
Michael B. Gale
2026-07-14 20:41:00 +01:00
parent 3ac40703e2
commit 7ec982acb7
2 changed files with 71 additions and 34 deletions

41
lib/entry-points.js generated
View File

@@ -148296,6 +148296,25 @@ function parseOldRemoteFileAddress(input) {
ref: pieces.groups.ref.trim()
});
}
function parseNewRemoteFileAddress(env, configFile) {
const format = new RegExp(
"^((?<owner>[^:@/]+)/)?(?<repo>[^:@/]+)(@(?<ref>[^:]+))?(:(?<path>.+))?$"
);
const pieces = format.exec(configFile.trim());
const repo = pieces?.groups?.repo?.trim();
if (!pieces?.groups || !repo || repo.length === 0) {
return new Failure(void 0);
}
const owner = pieces.groups.owner?.trim();
const path29 = pieces.groups.path?.trim();
const ref = pieces.groups.ref?.trim();
return new Success({
owner: owner || getDefaultOwner(env),
repo,
path: path29 || DEFAULT_CONFIG_FILE_NAME,
ref: ref || DEFAULT_CONFIG_FILE_REF
});
}
async function parseRemoteFileAddress(actionState, configFile) {
const oldFormatAddressResult = parseOldRemoteFileAddress(configFile);
if (oldFormatAddressResult.isSuccess()) {
@@ -148309,30 +148328,22 @@ async function parseRemoteFileAddress(actionState, configFile) {
getConfigFileRepoOldFormatInvalidMessage(configFile)
);
}
const format = new RegExp(
"^((?<owner>[^:@/]+)/)?(?<repo>[^:@/]+)(@(?<ref>[^:]+))?(:(?<path>.+))?$"
const newFormatAddressResult = parseNewRemoteFileAddress(
actionState.env,
configFile
);
const pieces = format.exec(configFile.trim());
const repo = pieces?.groups?.repo?.trim();
if (!pieces?.groups || !repo || repo.length === 0) {
if (newFormatAddressResult.isFailure()) {
throw new ConfigurationError(
getConfigFileRepoFormatInvalidMessage(configFile)
);
}
const owner = pieces.groups.owner?.trim();
const path29 = pieces.groups.path?.trim();
const ref = pieces.groups.ref?.trim();
if (path29?.startsWith("/")) {
const address = newFormatAddressResult.value;
if (address.path.startsWith("/")) {
throw new ConfigurationError(
`The path component of '${configFile}' cannot be an absolute path.`
);
}
return {
owner: owner || getDefaultOwner(actionState.env),
repo,
path: path29 || DEFAULT_CONFIG_FILE_NAME,
ref: ref || DEFAULT_CONFIG_FILE_REF
};
return address;
}
// src/config/file.ts

View File

@@ -1,5 +1,5 @@
import { ActionState } from "../action-common";
import { Env, ActionsEnvVars } from "../environment";
import { ActionsEnvVars, ReadOnlyEnv } from "../environment";
import * as errorMessages from "../error-messages";
import { Feature } from "../feature-flags";
import { ConfigurationError, Failure, Result, Success } from "../util";
@@ -23,7 +23,7 @@ export const DEFAULT_CONFIG_FILE_NAME = ".github/codeql-action.yaml";
export const DEFAULT_CONFIG_FILE_REF = "main";
/** Extracts the owner from the `GITHUB_REPOSITORY` environment variable. */
function getDefaultOwner(env: Env): string {
function getDefaultOwner(env: ReadOnlyEnv): string {
const currentRepoNwo = env.getRequired(ActionsEnvVars.GITHUB_REPOSITORY);
const nwoParts = currentRepoNwo.split("/");
@@ -70,6 +70,42 @@ function parseOldRemoteFileAddress(
});
}
/**
* Attempts to parse `input` as a `RemoteFileAddress` using the new format.
*
* @param env The read-only environment to obtain the owner name from if needed.
* @param configFile The input to try and parse.
* @returns A `RemoteFileAddress` value if successful or `undefined` otherwise.
*/
export function parseNewRemoteFileAddress(
env: ReadOnlyEnv,
configFile: string,
): Result<RemoteFileAddress, undefined> {
// retrieve the various parts of the config location, and ensure they're present
const format = new RegExp(
"^((?<owner>[^:@/]+)/)?(?<repo>[^:@/]+)(@(?<ref>[^:]+))?(:(?<path>.+))?$",
);
const pieces = format.exec(configFile.trim());
const repo: string | undefined = pieces?.groups?.repo?.trim();
// Check that the regular expression matched and that we have at least the repo name.
if (!pieces?.groups || !repo || repo.length === 0) {
return new Failure(undefined);
}
const owner: string | undefined = pieces.groups.owner?.trim();
const path: string | undefined = pieces.groups.path?.trim();
const ref: string | undefined = pieces.groups.ref?.trim();
return new Success({
owner: owner || getDefaultOwner(env),
repo,
path: path || DEFAULT_CONFIG_FILE_NAME,
ref: ref || DEFAULT_CONFIG_FILE_REF,
});
}
/**
* Attempts to parse `configFile` into an array of `RemoteFileAddress` components.
*
@@ -101,15 +137,12 @@ export async function parseRemoteFileAddress(
}
// retrieve the various parts of the config location, and ensure they're present
const format = new RegExp(
"^((?<owner>[^:@/]+)/)?(?<repo>[^:@/]+)(@(?<ref>[^:]+))?(:(?<path>.+))?$",
const newFormatAddressResult = parseNewRemoteFileAddress(
actionState.env,
configFile,
);
const pieces = format.exec(configFile.trim());
const repo: string | undefined = pieces?.groups?.repo?.trim();
// Check that the regular expression matched and that we have at least the repo name.
if (!pieces?.groups || !repo || repo.length === 0) {
if (newFormatAddressResult.isFailure()) {
// Neither the old format nor the new format worked. Throw an error that
// explains the format we accept. We only mention the new format, since that's
// what we want to be used going forward.
@@ -118,21 +151,14 @@ export async function parseRemoteFileAddress(
);
}
const owner: string | undefined = pieces.groups.owner?.trim();
const path: string | undefined = pieces.groups.path?.trim();
const ref: string | undefined = pieces.groups.ref?.trim();
const address = newFormatAddressResult.value;
// Ensure that the path is a relative path.
if (path?.startsWith("/")) {
if (address.path.startsWith("/")) {
throw new ConfigurationError(
`The path component of '${configFile}' cannot be an absolute path.`,
);
}
return {
owner: owner || getDefaultOwner(actionState.env),
repo,
path: path || DEFAULT_CONFIG_FILE_NAME,
ref: ref || DEFAULT_CONFIG_FILE_REF,
};
return address;
}