Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,102 @@ describe("GitHubSourceControlProvider repository resolution", () => {
assert.deepStrictEqual(paths, ["github.com repos/acme/web"]);
}).pipe(Effect.provide(layer));
});

it.effect.each([
["github", "git@github:acme/web.git"],
["github.com-scale", "git@github.com-scale:acme/web.git"],
["github.com-scale", "ssh://git@github.com-scale:22/acme/web.git"],
] as const)("reads an SSH alias on %s through github.com (%s)", ([host, remoteUrl]) => {
const hosts: string[] = [];
const { layer } = harness({
remotes: remotesOutput(["origin", remoteUrl]),
api: {
rest: (input) =>
Effect.sync(() => {
hosts.push(`${input.host} ${input.path}`);
return restResponse({
full_name: "acme/web",
html_url: "https://github.com/acme/web",
ssh_url: "git@github.com:acme/web.git",
default_branch: "main",
});
}),
},
});
return Effect.gen(function* () {
const gh = yield* GitHubSourceControlProvider.make;
const resolveWebHost = gh.resolveRemoteWebHost;
assert.ok(resolveWebHost);
assert.strictEqual(
yield* resolveWebHost({
cwd: "/repo",
context: { ...githubContext(host), remoteUrl },
resolveContext: () => Effect.succeed(null),
}),
"github.com",
);
yield* gh.getDefaultBranch({ cwd: "/repo" });
yield* gh.getDefaultBranch({
cwd: "/repo",
context: { ...githubContext(host), remoteUrl },
});
assert.deepStrictEqual(hosts, ["github.com repos/acme/web", "github.com repos/acme/web"]);
}).pipe(Effect.provide(layer));
});

it.effect.each(["sole", "upstream", "missing"])(
"preserves an HTTPS context host with %s remotes",
(mode) => {
const paths: string[] = [];
const remoteUrl = "https://github.com-scale/me/web.git";
const { layer } = harness({
remotes:
mode === "missing"
? ""
: remotesOutput(
["origin", remoteUrl],
...(mode === "upstream"
? ([["upstream", "https://github.com/acme/web.git"]] as const)
: []),
),
api: {
rest: (input) =>
Effect.sync(() => {
paths.push(`${input.host} ${input.path}`);
return restResponse({
full_name: "me/web",
html_url: "https://github.com-scale/me/web",
ssh_url: "git@github.com-scale:me/web.git",
default_branch: "trunk",
});
}),
},
});
return Effect.gen(function* () {
const gh = yield* GitHubSourceControlProvider.make;
const resolveWebHost = gh.resolveRemoteWebHost;
assert.ok(resolveWebHost);
for (const url of [remoteUrl, "git@github.com-evil.example:me/web.git"]) {
assert.strictEqual(
yield* resolveWebHost({
cwd: "/repo",
context: { ...githubContext("github.com-scale"), remoteUrl: url },
resolveContext: () => Effect.succeed(null),
}),
url === remoteUrl ? "github.com-scale" : "github.com-evil.example",
);
}
assert.strictEqual(
yield* gh.getDefaultBranch({
cwd: "/repo",
context: { ...githubContext("github.com-scale"), remoteUrl },
}),
"trunk",
);
assert.deepStrictEqual(paths, ["github.com-scale repos/me/web"]);
}).pipe(Effect.provide(layer));
},
);
});

describe("GitHubSourceControlProvider change request lookups by head", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -859,6 +859,9 @@ export const make = Effect.gen(function* () {

return SourceControlProvider.SourceControlProvider.of({
kind: SourceControlProviderKind.make("github"),
resolveRemoteWebHost: Effect.fn("GitHubSourceControlProvider.resolveRemoteWebHost")(
({ context }) => Effect.succeed(gitHubApiHostForRemote(context.remoteUrl)),
),
// GitHub matches bare heads; read a full page to disambiguate forks by owner.
headBranchProbe: ({ headSelectors }) => ({
headSelectors: headSelectors.filter((selector) => !selector.includes(":")),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { assert, describe, it } from "@effect/vitest";

import {
gitHubApiHostForRemote,
resolveGitHubRepository,
parseGitHubRepositorySelector,
selectGitHubBaseRepository,
} from "./gitHubRepositoryResolution.ts";
Expand Down Expand Up @@ -48,6 +49,64 @@ describe("selectGitHubBaseRepository", () => {
);
});

it("honors a marked SSH alias origin over upstream", () => {
for (const url of [
"git@github.com-scale:me/web.git",
"ssh://git@github.com-scale:22/me/web.git",
"git@github-work:me/web.git",
]) {
const input = {
remotes: remotes(["origin", url], ["upstream", "https://github.com/acme/web.git"]),
resolved: "remote.origin.gh-resolved base",
};
assert.deepStrictEqual(select(input), { owner: "me", name: "web" }, url);
assert.deepStrictEqual(
resolveGitHubRepository({ ...input, hostHint: undefined, defaultHost: "github.com" }),
{ host: "github.com", locator: { host: "github.com", owner: "me", name: "web" } },
url,
);
}
});

it("does not honor a github.com mark on a different or unrecognized host", () => {
for (const url of [
"git@github.com-evil.example:me/web.git",
"git@github.com.evil.example:me/web.git",
"git@evil-github.com:me/web.git",
"https://github.com-scale/me/web.git",
"git@work:me/web.git",
]) {
const input = {
remotes: remotes(["origin", url], ["upstream", "https://github.com/acme/web.git"]),
resolved: "remote.origin.gh-resolved base",
};
assert.strictEqual(select(input), null, url);
assert.deepStrictEqual(
resolveGitHubRepository({ ...input, hostHint: "github.com", defaultHost: "github.com" }),
{ host: "github.com", locator: { host: "github.com", owner: "acme", name: "web" } },
url,
);
}
});

it("preserves selection behavior for real hosts with explicit ports", () => {
const input = {
remotes: remotes(["origin", "https://github.example.com:8443/me/web.git"]),
resolved: "remote.origin.gh-resolved acme/other",
};
assert.strictEqual(
selectGitHubBaseRepository({ ...input, host: "github.example.com:8443" }),
null,
);
assert.deepStrictEqual(
resolveGitHubRepository({ ...input, hostHint: undefined, defaultHost: "github.com" }),
{
host: "github.example.com:8443",
locator: { host: "github.example.com:8443", owner: "me", name: "web" },
},
);
});

it("leaves gh to choose when it might weigh the remotes differently", () => {
for (const input of [
{ remotes: "" },
Expand All @@ -60,7 +119,7 @@ describe("selectGitHubBaseRepository", () => {
["mirror", "git@gitlab.com:me/web.git"],
),
},
{ remotes: remotes(["origin", "git@github-work:me/web.git"]) },
{ remotes: remotes(["origin", "git@work:me/web.git"]) },
{
remotes: remotes(
["origin", "git@github.com:me/web.git"],
Expand Down Expand Up @@ -91,6 +150,136 @@ describe("gitHubApiHostForRemote", () => {
});
});

describe("github.com-<name> SSH aliases", () => {
it("reads a per-account alias through github.com", () => {
for (const url of [
"git@github.com-scale:scalable-so/scalablev2.git",
"git@GitHub.com-Work:acme/web.git",
"ssh://git@github.com-personal/acme/web.git",
"ssh://git@github.com-scale:22/acme/web.git",
]) {
assert.strictEqual(gitHubApiHostForRemote(url), "github.com", url);
}
});

it("never maps a hostile or real DNS host onto github.com", () => {
for (const [url, host] of [
["git@github.com-evil.example:acme/web.git", "github.com-evil.example"],
["ssh://git@github.com-evil.example/acme/web.git", "github.com-evil.example"],
["git@github.com.evil.example:acme/web.git", "github.com.evil.example"],
["git@evil-github.com:acme/web.git", null],
["https://github.com-scale/acme/web.git", "github.com-scale"],
] as const) {
assert.strictEqual(gitHubApiHostForRemote(url), host, url);
}
});

it("resolves the API host and repository from an alias remote and its host hint", () => {
const remotes = [
"origin\tgit@github.com-scale:scalable-so/scalablev2.git (fetch)",
"origin\tgit@github.com-scale:scalable-so/scalablev2.git (push)",
].join("\n");
const expected = {
host: "github.com",
locator: { host: "github.com", owner: "scalable-so", name: "scalablev2" },
};
for (const hostHint of ["github.com-scale", undefined]) {
assert.deepStrictEqual(
resolveGitHubRepository({ remotes, resolved: "", hostHint, defaultHost: "github.com" }),
expected,
);
}
});

it.each([false, true])("preserves an HTTPS alias-shaped host hint (upstream: %s)", (upstream) => {
const remotes = [
"origin\thttps://github.com-scale/me/web.git (fetch)",
...(upstream ? ["upstream\thttps://github.com/acme/web.git (fetch)"] : []),
].join("\n");
assert.deepStrictEqual(
resolveGitHubRepository({
remotes,
resolved: "",
hostHint: "github.com-scale",
defaultHost: "github.com",
}),
{
host: "github.com-scale",
locator: { host: "github.com-scale", owner: "me", name: "web" },
},
);
});

it("requires matching SSH evidence to normalize a dotted hint", () => {
for (const remotes of [
"",
"origin\tgit@github.com-work:me/web.git (fetch)",
"origin\tgit@github.com-scale:me/web.git (push)",
]) {
assert.deepStrictEqual(
resolveGitHubRepository({
remotes,
resolved: "",
hostHint: "GitHub.com-Scale",
defaultHost: "github.com",
}),
{ host: "github.com-scale", locator: null },
);
}
});

it("preserves a dotted hint when matching remotes use both transports", () => {
const entries = [
"origin\thttps://github.com-scale/me/web.git (fetch)",
"upstream\tgit@github.com-scale:acme/web.git (fetch)",
];
for (const [remotes, hostHint, resolved] of [
[entries.join("\n"), "github.com-scale", "remote.origin.gh-resolved base"],
[entries.join("\n"), "github.com-scale", ""],
[entries.toReversed().join("\n"), undefined, "remote.origin.gh-resolved base"],
[entries.toReversed().join("\n"), undefined, ""],
] as const) {
assert.deepStrictEqual(
resolveGitHubRepository({
remotes,
resolved,
hostHint,
defaultHost: "github.com",
}),
{
host: "github.com-scale",
locator: { host: "github.com-scale", owner: "me", name: "web" },
},
);
}
});

it("retains dotless hint compatibility without remote evidence", () => {
for (const hostHint of ["github", "github-work", "workgithub"]) {
assert.deepStrictEqual(
resolveGitHubRepository({ remotes: "", resolved: "", hostHint, defaultHost: hostHint }),
{ host: "github.com", locator: null },
);
}
});

it("keeps a hostile host hint and its remote off github.com", () => {
const remotes = "origin\tgit@github.com-evil.example:acme/web.git (fetch)";
assert.deepStrictEqual(
resolveGitHubRepository({
remotes,
resolved: "",
hostHint: "github.com-evil.example",
defaultHost: "github.com-evil.example",
}),
{
host: "github.com-evil.example",
locator: { host: "github.com-evil.example", owner: "acme", name: "web" },
},
);
});
});

describe("parseGitHubRepositorySelector", () => {
it("reads host/owner/name only when the host is a plain hostname", () => {
assert.deepStrictEqual(parseGitHubRepositorySelector("GHE.corp:8443/acme/web", "github.com"), {
Expand Down
Loading
Loading