fix(deprecation): address DEP0169 (#4320)

This commit is contained in:
Matt Travi
2026-10-24 11:45:45 -05:00
committed by GitHub
2 changed files with 20 additions and 7 deletions
+18 -5
View File
@@ -1,4 +1,4 @@
import { format, parse } from "node:url";
import { format } from "node:url";
import { isNil } from "lodash-es";
import hostedGitInfo from "hosted-git-info";
import debugAuthUrl from "debug";
@@ -6,6 +6,17 @@ import { verifyAuth } from "./git.js";
const debug = debugAuthUrl("semantic-release:get-git-auth-url");
/**
* Get the protocol of a repository URL, if it has one (`null` for scp-like and shorthand URLs)
*
* @param {String} repositoryUrl User-given repository URL
*
* @return {String|null} The protocol, including the trailing `:`
*/
function getProtocol(repositoryUrl) {
return URL.canParse(repositoryUrl) ? new URL(repositoryUrl).protocol : null;
}
/**
* Machinery to format a repository URL with the given credentials
*
@@ -22,12 +33,14 @@ function formatAuthUrl(protocol, repositoryUrl, gitCredentials) {
const [match, auth, host, basePort, path] =
/^(?!.+:\/\/)(?:(?<auth>.*)@)?(?<host>.*?):(?<port>\d+)?:?\/?(?<path>.*)$/.exec(repositoryUrl) || [];
const { port, hostname, ...parsed } = parse(
const { port, hostname, pathname, search, hash } = new URL(
match ? `ssh://${auth ? `${auth}@` : ""}${host}${basePort ? `:${basePort}` : ""}/${path}` : repositoryUrl
);
return format({
...parsed,
pathname,
search,
hash,
auth: gitCredentials,
host: `${hostname}${protocol === "ssh:" ? "" : port ? `:${port}` : ""}`,
protocol: protocol && /http[^s]/.test(protocol) ? "http" : "https",
@@ -81,14 +94,14 @@ export default async (context) => {
let { repositoryUrl } = context.options;
const info = hostedGitInfo.fromUrl(repositoryUrl, { noGitPlus: true });
const { protocol, ...parsed } = parse(repositoryUrl);
const protocol = getProtocol(repositoryUrl);
if (info && info.getDefaultRepresentation() === "shortcut") {
// Expand shorthand URLs (such as `owner/repo` or `gitlab:owner/repo`)
repositoryUrl = info.https();
} else if (protocol && protocol.includes("http")) {
// Replace `git+https` and `git+http` with `https` or `http`
repositoryUrl = format({ ...parsed, protocol: protocol.includes("https") ? "https" : "http", href: null });
repositoryUrl = repositoryUrl.replace(/^[^:]+:/, protocol.includes("https") ? "https:" : "http:");
}
// Test if push is allowed without transforming the URL (e.g. is ssh keys are set up)
+2 -2
View File
@@ -1,4 +1,4 @@
import { format, parse } from "node:url";
import { format } from "node:url";
import test from "ava";
import { repeat } from "lodash-es";
import hideSensitive from "../lib/hide-sensitive.js";
@@ -87,7 +87,7 @@ test("Exclude environment variables with value shorter than SECRET_MIN_SIZE from
// `lib/get-git-auth-url.js` embeds credentials in the repository URL with `url.format()`, which
// encodes the `auth` field like `encodeURIComponent()` except that `:` separators are kept as is.
// Build the URLs asserted below the same way, so they match what a failing git command prints.
const gitAuthUrl = (auth) => format({ ...parse("https://host.com/owner/repo.git"), auth });
const gitAuthUrl = (auth) => format({ protocol: "https", host: "host.com", pathname: "/owner/repo.git", auth });
for (const character of ["@", "/", "?", "&", "=", "#", " "]) {
test(`Mask GIT_CREDENTIALS containing "${character}" in a git authentication URL`, (t) => {