Warn if a private registry configuration uses a PAT, but has no username

This commit is contained in:
Michael B. Gale
2026-01-24 13:02:41 +00:00
parent c12cf8d49a
commit 9fccf271ff
3 changed files with 130 additions and 19 deletions
+37 -1
View File
@@ -7,7 +7,12 @@ import { KnownLanguage } from "./languages";
import { getRunnerLogger } from "./logging";
import * as startProxyExports from "./start-proxy";
import { parseLanguage } from "./start-proxy";
import { setupTests } from "./testing-utils";
import {
checkExpectedLogMessages,
getRecordingLogger,
makeTestToken,
setupTests,
} from "./testing-utils";
setupTests(test);
@@ -174,6 +179,37 @@ test("getCredentials throws an error when non-printable characters are used", as
}
});
test("getCredentials logs a warning when a PAT is used without a username", async (t) => {
const loggedMessages = [];
const logger = getRecordingLogger(loggedMessages);
const likelyWrongCredentials = toEncodedJSON([
{
type: "git_server",
host: "https://github.com/",
password: `ghp_${makeTestToken()}`,
},
]);
const results = startProxyExports.getCredentials(
logger,
undefined,
likelyWrongCredentials,
undefined,
);
// The configuration should be accepted, despite the likely problem.
t.assert(results);
t.is(results.length, 1);
t.is(results[0].type, "git_server");
t.is(results[0].host, "https://github.com/");
t.assert(results[0].password?.startsWith("ghp_"));
// A warning should have been logged.
checkExpectedLogMessages(t, loggedMessages, [
"using a GitHub Personal Access Token (PAT), but no username was provided",
]);
});
test("parseLanguage", async (t) => {
// Exact matches
t.deepEqual(parseLanguage("csharp"), KnownLanguage.csharp);
+21
View File
@@ -1,6 +1,7 @@
import * as core from "@actions/core";
import { getApiClient } from "./api-client";
import * as artifactScanner from "./artifact-scanner";
import * as defaults from "./defaults.json";
import { KnownLanguage } from "./languages";
import { Logger } from "./logging";
@@ -62,6 +63,13 @@ export function parseLanguage(language: string): KnownLanguage | undefined {
return undefined;
}
function isPAT(value: string) {
return artifactScanner.isAuthToken(value, [
artifactScanner.GITHUB_PAT_CLASSIC_PATTERN,
artifactScanner.GITHUB_PAT_FINE_GRAINED_PATTERN,
]);
}
const LANGUAGE_TO_REGISTRY_TYPE: Partial<Record<KnownLanguage, string[]>> = {
java: ["maven_repository"],
csharp: ["nuget_feed"],
@@ -161,6 +169,19 @@ export function getCredentials(
);
}
// If the password or token looks like a GitHub PAT, warn if no username is configured.
if (
!isDefined(e.username) &&
((isDefined(e.password) && isPAT(e.password)) ||
(isDefined(e.token) && isPAT(e.token)))
) {
logger.warning(
`A ${e.type} private registry is configured for ${e.host || e.url} using a GitHub Personal Access Token (PAT), but no username was provided. ` +
`This may not work correctly. When configuring a private registry using a PAT, select "Username and password" and enter the username of the user ` +
`who generated the PAT.`,
);
}
out.push({
type: e.type,
host: e.host,