-
Notifications
You must be signed in to change notification settings - Fork 4.7k
fix(server): normalize full repository URLs in GitLab lookups #7862
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -390,6 +390,34 @@ function toSummaryWithOptionalUpdatedAt( | |
| return Option.isSome(updatedAt) ? { ...summary, updatedAt } : summary; | ||
| } | ||
|
|
||
| /** | ||
| * Accept either a bare `namespace/project` path or a pasted repository URL | ||
| * (any host, since glab resolves against its authenticated default host) and | ||
| * return the project path `glab api projects/<encoded path>` expects. | ||
| */ | ||
| export function normalizeGitLabRepositoryPath(repository: string): string { | ||
| const trimmed = repository.trim(); | ||
| if (!/^https?:\/\//i.test(trimmed)) { | ||
| return trimmed; | ||
| } | ||
|
|
||
| try { | ||
| const url = new URL(trimmed); | ||
| const segments = url.pathname.split("/").filter((segment) => segment.length > 0); | ||
|
Comment on lines
+405
to
+406
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When a user is authenticated to multiple GitLab instances and pastes a URL whose host is not the host selected by Useful? React with 👍 / 👎.
Comment on lines
+405
to
+406
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
For a self-hosted instance configured under a relative URL root, such as Useful? React with 👍 / 👎. |
||
| // Web URLs continue past the project into `/-/tree/main` style sections; | ||
| // everything from the `-` separator on belongs to the UI, not the project. | ||
| const separatorIndex = segments.indexOf("-"); | ||
| const projectSegments = separatorIndex > 0 ? segments.slice(0, separatorIndex) : segments; | ||
| const last = projectSegments.at(-1)?.replace(/\.git$/i, "") ?? ""; | ||
| if (projectSegments.length > 0) { | ||
| projectSegments[projectSegments.length - 1] = last; | ||
| } | ||
| return projectSegments.join("/"); | ||
| } catch { | ||
| return trimmed; | ||
| } | ||
| } | ||
|
|
||
| function parseRepositoryPath(repository: string): { | ||
| readonly namespacePath: string | null; | ||
| readonly projectPath: string; | ||
|
|
@@ -519,7 +547,10 @@ export const make = Effect.gen(function* () { | |
| getRepositoryCloneUrls: (input) => | ||
| execute({ | ||
| cwd: input.cwd, | ||
| args: ["api", `projects/${encodeURIComponent(input.repository)}`], | ||
| args: [ | ||
| "api", | ||
| `projects/${encodeURIComponent(normalizeGitLabRepositoryPath(input.repository))}`, | ||
| ], | ||
| }).pipe( | ||
| Effect.map((result) => result.stdout.trim()), | ||
| Effect.flatMap((raw) => | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🟠 High
sourceControl/GitLabCli.ts:406For a relative-root GitLab installation,
normalizeGitLabRepositoryPathincludes the instance base path in the project identifier:https://example.com/gitlab/group/projectbecomesgitlab/group/projectinstead ofgroup/project, sogetRepositoryCloneUrlsqueries the wrong project. Remove the host's configured GitLab base path before extracting the namespace/project path.🤖 Copy this AI Prompt to have your agent fix this: