diff --git a/packages/source-control-gitlab/src/server/GitLabCli.ts b/packages/source-control-gitlab/src/server/GitLabCli.ts index 7690304897af4..c51ae52ffd59e 100644 --- a/packages/source-control-gitlab/src/server/GitLabCli.ts +++ b/packages/source-control-gitlab/src/server/GitLabCli.ts @@ -277,6 +277,7 @@ export class GitLabCli extends Context.Service< readonly listMergeRequests: (input: { readonly cwd: string; + readonly host?: string | undefined; readonly headSelector: string; readonly source?: SourceControlProvider.SourceControlRefSelector; readonly state: "open" | "closed" | "merged" | "all"; @@ -285,6 +286,7 @@ export class GitLabCli extends Context.Service< readonly getMergeRequest: (input: { readonly cwd: string; + readonly host?: string | undefined; readonly reference: string; }) => Effect.Effect; @@ -301,6 +303,7 @@ export class GitLabCli extends Context.Service< readonly createMergeRequest: (input: { readonly cwd: string; + readonly host?: string | undefined; readonly baseBranch: string; readonly headSelector: string; readonly source?: SourceControlProvider.SourceControlRefSelector; @@ -311,10 +314,12 @@ export class GitLabCli extends Context.Service< readonly getDefaultBranch: (input: { readonly cwd: string; + readonly host?: string | undefined; }) => Effect.Effect; readonly checkoutMergeRequest: (input: { readonly cwd: string; + readonly host?: string | undefined; readonly reference: string; readonly force?: boolean; }) => Effect.Effect; @@ -460,6 +465,7 @@ export const make = Effect.gen(function* () { const executeMergeRequest = (input: { readonly cwd: string; + readonly host?: string | undefined; readonly reference: string; readonly args: ReadonlyArray; }) => @@ -480,6 +486,7 @@ export const make = Effect.gen(function* () { listMergeRequests: Effect.fn("GitLabCli.listMergeRequests")(function (input) { return execute({ cwd: input.cwd, + host: input.host, args: [ "mr", "list", @@ -518,6 +525,7 @@ export const make = Effect.gen(function* () { getMergeRequest: Effect.fn("GitLabCli.getMergeRequest")(function (input) { return executeMergeRequest({ cwd: input.cwd, + host: input.host, reference: input.reference, args: ["mr", "view", "--output", "json", "--", input.reference], }).pipe( @@ -635,6 +643,7 @@ export const make = Effect.gen(function* () { const sourceProject = sourceProjectIdentifier(input.source); return execute({ cwd: input.cwd, + host: input.host, args: [ "api", "--method", @@ -655,6 +664,7 @@ export const make = Effect.gen(function* () { getDefaultBranch: Effect.fn("GitLabCli.getDefaultBranch")(function (input) { return execute({ cwd: input.cwd, + host: input.host, args: ["api", "projects/:fullpath"], }).pipe( Effect.map((result) => result.stdout.trim()), @@ -677,6 +687,7 @@ export const make = Effect.gen(function* () { checkoutMergeRequest: Effect.fn("GitLabCli.checkoutMergeRequest")(function (input) { return executeMergeRequest({ cwd: input.cwd, + host: input.host, reference: input.reference, args: ["mr", "checkout", "--", input.reference], }).pipe(Effect.asVoid); diff --git a/packages/source-control-gitlab/src/server/GitLabSourceControlProvider.test.ts b/packages/source-control-gitlab/src/server/GitLabSourceControlProvider.test.ts index 6ef52973ffe70..b039ee87108c6 100644 --- a/packages/source-control-gitlab/src/server/GitLabSourceControlProvider.test.ts +++ b/packages/source-control-gitlab/src/server/GitLabSourceControlProvider.test.ts @@ -281,3 +281,58 @@ it.effect.each(["read", "decode"] as const)( else assert.propertyVal(error.cause, "_tag", "SchemaError"); }), ); + +it.effect("sends merge request calls to the bound remote's host", () => + Effect.gen(function* () { + const hosts: Array = []; + const provider = yield* GitLabSourceControlProvider.make.pipe( + Effect.provide( + GitLabCli.layer.pipe( + Layer.provideMerge( + TestSourceControlHost.layer({ + process: { + run: (input) => { + hosts.push(input.env?.GITLAB_HOST); + return Effect.succeed( + processOutput(input.args[0] === "mr" ? "[]" : '{"default_branch":"main"}'), + ); + }, + }, + }), + ), + ), + ), + ); + const context = { + provider: { + kind: SourceControlProviderKind.make("gitlab"), + name: "GitLab Self-Hosted", + baseUrl: "https://gitlab.example.test", + }, + remoteName: "work", + remoteUrl: "git@gitlab.example.test:group/project.git", + }; + + yield* provider.listChangeRequests({ + cwd: "/repo", + context, + headSelector: "feature", + state: "open", + }); + yield* provider.getDefaultBranch({ cwd: "/repo", context }); + yield* provider.createChangeRequest({ + cwd: "/repo", + context, + baseRefName: "main", + headSelector: "feature", + title: "Feature", + bodyFile: "/tmp/body.md", + }); + + assert.deepStrictEqual(hosts, [ + "gitlab.example.test", + "gitlab.example.test", + "gitlab.example.test", + ]); + }), +); diff --git a/packages/source-control-gitlab/src/server/GitLabSourceControlProvider.ts b/packages/source-control-gitlab/src/server/GitLabSourceControlProvider.ts index 9f599794057fc..782e5e8edb491 100644 --- a/packages/source-control-gitlab/src/server/GitLabSourceControlProvider.ts +++ b/packages/source-control-gitlab/src/server/GitLabSourceControlProvider.ts @@ -166,6 +166,9 @@ export const discovery = { "Install the GitLab command-line tool (`glab`) from https://gitlab.com/gitlab-org/cli or your package manager (for example `brew install glab`).", } satisfies SourceControlCliDiscoverySpec; +const contextHost = (context: SourceControlProvider.SourceControlProviderContext | undefined) => + context === undefined ? undefined : new URL(context.provider.baseUrl).host; + export const make = Effect.gen(function* () { const gitlab = yield* GitLabCli.GitLabCli; const { git } = yield* SourceControlHost.SourceControlHost; @@ -234,6 +237,7 @@ export const make = Effect.gen(function* () { return gitlab .listMergeRequests({ cwd: input.cwd, + host: contextHost(input.context), headSelector: input.headSelector, ...(source ? { source } : {}), state: input.state, @@ -259,7 +263,7 @@ export const make = Effect.gen(function* () { }, ), getChangeRequest: Effect.fn("GitLabSourceControlProvider.getChangeRequest")(function (input) { - return gitlab.getMergeRequest(input).pipe( + return gitlab.getMergeRequest({ ...input, host: contextHost(input.context) }).pipe( Effect.map(toChangeRequest), Effect.mapError( (error) => @@ -283,6 +287,7 @@ export const make = Effect.gen(function* () { return gitlab .createMergeRequest({ cwd: input.cwd, + host: contextHost(input.context), baseBranch: input.baseRefName, headSelector: input.headSelector, ...(source ? { source } : {}), @@ -347,7 +352,7 @@ export const make = Effect.gen(function* () { ); }), getDefaultBranch: Effect.fn("GitLabSourceControlProvider.getDefaultBranch")(function (input) { - return gitlab.getDefaultBranch(input).pipe( + return gitlab.getDefaultBranch({ ...input, host: contextHost(input.context) }).pipe( Effect.mapError( (error) => new SourceControlProviderError({ @@ -363,7 +368,7 @@ export const make = Effect.gen(function* () { }), checkoutChangeRequest: Effect.fn("GitLabSourceControlProvider.checkoutChangeRequest")( function (input) { - return gitlab.checkoutMergeRequest(input).pipe( + return gitlab.checkoutMergeRequest({ ...input, host: contextHost(input.context) }).pipe( Effect.mapError( (error) => new SourceControlProviderError({