diff --git a/lib/entry-points.js b/lib/entry-points.js index 48a157aa6..7ad70e03d 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -151429,13 +151429,14 @@ function parseUserConfig(logger, pathInput, contents, validateConfig) { } // src/config/remote-file.ts +var DEFAULT_CONFIG_FILE_NAME = ".github/codeql-action.yaml"; var DEFAULT_CONFIG_FILE_REF = "main"; function parseRemoteFileAddress(configFile) { const format = new RegExp( - "(?[^/]+)/(?[^/]+)/(?[^@]+)(@(?.*))?" + "(?[^/]+)/(?[^/@]+)(/(?[^@]+))?(@(?.*))?" ); const pieces = format.exec(configFile); - if (!pieces?.groups?.owner || !pieces?.groups?.repo || !pieces?.groups?.path) { + if (!pieces?.groups?.owner || !pieces?.groups?.repo) { throw new ConfigurationError( getConfigFileRepoFormatInvalidMessage(configFile) ); @@ -151443,7 +151444,7 @@ function parseRemoteFileAddress(configFile) { return { owner: pieces.groups.owner, repo: pieces.groups.repo, - path: pieces.groups.path, + path: pieces.groups.path || DEFAULT_CONFIG_FILE_NAME, ref: pieces.groups.ref || DEFAULT_CONFIG_FILE_REF }; } diff --git a/src/config/remote-file.test.ts b/src/config/remote-file.test.ts index d45c2ec6d..457c24120 100644 --- a/src/config/remote-file.test.ts +++ b/src/config/remote-file.test.ts @@ -3,6 +3,7 @@ import test from "ava"; import { ConfigurationError } from "../util"; import { + DEFAULT_CONFIG_FILE_NAME, DEFAULT_CONFIG_FILE_REF, parseRemoteFileAddress, RemoteFileAddress, @@ -27,6 +28,22 @@ test("expandConfigFileInput accepts full remote addresses", async (t) => { ); }); +test("expandConfigFileInput accepts remote address without a path", async (t) => { + t.deepEqual(parseRemoteFileAddress("owner/repo@ref"), { + owner: "owner", + repo: "repo", + path: DEFAULT_CONFIG_FILE_NAME, + ref: "ref", + } satisfies RemoteFileAddress); + + t.deepEqual(parseRemoteFileAddress("owner/repo"), { + owner: "owner", + repo: "repo", + path: DEFAULT_CONFIG_FILE_NAME, + ref: DEFAULT_CONFIG_FILE_REF, + } satisfies RemoteFileAddress); +}); + test("expandConfigFileInput accepts remote address without a ref", async (t) => { t.deepEqual(parseRemoteFileAddress("owner/repo/path"), { owner: "owner", @@ -47,7 +64,7 @@ test("expandConfigFileInput rejects invalid values", async (t) => { t.throws(() => parseRemoteFileAddress(" "), { instanceOf: ConfigurationError, }); - t.throws(() => parseRemoteFileAddress("repo:/absolute"), { + t.throws(() => parseRemoteFileAddress("repo//absolute"), { instanceOf: ConfigurationError, }); t.throws(() => parseRemoteFileAddress("repo:file.yml:unexpected"), { diff --git a/src/config/remote-file.ts b/src/config/remote-file.ts index 9ab89ad4a..ad3486487 100644 --- a/src/config/remote-file.ts +++ b/src/config/remote-file.ts @@ -13,6 +13,9 @@ export interface RemoteFileAddress { ref: string; } +/** The default file path to use in configuration file shorthands. */ +export const DEFAULT_CONFIG_FILE_NAME = ".github/codeql-action.yaml"; + /** The default ref to use in configuration file shorthands. */ export const DEFAULT_CONFIG_FILE_REF = "main"; @@ -26,16 +29,12 @@ export const DEFAULT_CONFIG_FILE_REF = "main"; export function parseRemoteFileAddress(configFile: string): RemoteFileAddress { // retrieve the various parts of the config location, and ensure they're present const format = new RegExp( - "(?[^/]+)/(?[^/]+)/(?[^@]+)(@(?.*))?", + "(?[^/]+)/(?[^/@]+)(/(?[^@]+))?(@(?.*))?", ); const pieces = format.exec(configFile); // Check that the regular expression matched and that we have at least the required components. - if ( - !pieces?.groups?.owner || - !pieces?.groups?.repo || - !pieces?.groups?.path - ) { + if (!pieces?.groups?.owner || !pieces?.groups?.repo) { throw new ConfigurationError( errorMessages.getConfigFileRepoFormatInvalidMessage(configFile), ); @@ -44,7 +43,7 @@ export function parseRemoteFileAddress(configFile: string): RemoteFileAddress { return { owner: pieces.groups.owner, repo: pieces.groups.repo, - path: pieces.groups.path, + path: pieces.groups.path || DEFAULT_CONFIG_FILE_NAME, ref: pieces.groups.ref || DEFAULT_CONFIG_FILE_REF, }; }