diff --git a/CHANGELOG.md b/CHANGELOG.md index 89eb568b7..b2cfd255b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed Ask model selections reverting to a stale default after the model configuration changed during a browser session. [#1710](https://github.com/sourcebot-dev/sourcebot/pull/1710) - Upgraded `next` to `^16.3.8`. [#1709](https://github.com/sourcebot-dev/sourcebot/pull/1709) - Upgraded `seroval` to `^1.6.8`, `proxy-addr` to `^2.0.8`, `shell-quote` to `^1.12.0`, and `@grpc/grpc-js` to `^1.14.6`. [#1713](https://github.com/sourcebot-dev/sourcebot/pull/1713) +- Upgraded `simple-git` to `^4.0.2`. [#1715](https://github.com/sourcebot-dev/sourcebot/pull/1715) - Upgraded `katex` to `^0.18.2` and `postcss-selector-parser` to `^7.1.6`. [#1717](https://github.com/sourcebot-dev/sourcebot/pull/1717) - Upgraded `engine.io` to `^6.6.11`, `source-map-js` to `^1.2.2`, `smol-toml` to `^1.9.0`, `fast-copy` to `^3.1.0`, and `dompurify` to `^3.4.16`. [#1714](https://github.com/sourcebot-dev/sourcebot/pull/1714) - Upgraded `golang.org/x/crypto` to `v0.56.0` and OpenTelemetry-Go exporters and SDK to `v1.45.0` in Zoekt. [#1716](https://github.com/sourcebot-dev/sourcebot/pull/1716) diff --git a/packages/backend/package.json b/packages/backend/package.json index e190cd797..3049f3dfd 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -33,6 +33,7 @@ "@sentry/cli": "^2.42.2", "@sentry/node": "^10.71.0", "@sentry/profiling-node": "^10.71.0", + "@simple-git/argv-parser": "^2.0.1", "@sourcebot/db": "workspace:*", "@sourcebot/schemas": "workspace:*", "@sourcebot/shared": "workspace:*", @@ -57,7 +58,7 @@ "posthog-node": "^5.51.2", "prom-client": "^15.1.3", "redlock": "5.0.0-beta.2", - "simple-git": "^3.36.0", + "simple-git": "^4.0.2", "zod": "^3.25.76" } } diff --git a/packages/backend/src/git.ts b/packages/backend/src/git.ts index 8d2615358..6aaf3ea38 100644 --- a/packages/backend/src/git.ts +++ b/packages/backend/src/git.ts @@ -48,6 +48,28 @@ const createGitClientForPath = ( } const parentPath = resolve(dirname(path)); + const gitEnvironment: NodeJS.ProcessEnv = { + ...process.env, + ...environment, + /** + * @note on some inside-baseball on why this is necessary: The specific + * issue we saw was that a `git clone` would fail without throwing, and + * then a subsequent `git config` command would run, but since the clone + * failed, it wouldn't be running in a git directory. Git would then walk + * up the directory tree until it either found a git directory (in the case + * of the development env) or it would hit a GIT_DISCOVERY_ACROSS_FILESYSTEM + * error when trying to cross a filesystem boundary (in the prod case). + * GIT_CEILING_DIRECTORIES ensures that this walk will be limited to the + * parent directory. + */ + GIT_CEILING_DIRECTORIES: parentPath, + /** + * Disable git credential prompts. This ensures that git operations will fail + * immediately if credentials are not available, rather than prompting for input. + */ + GIT_TERMINAL_PROMPT: '0', + }; + const git = simpleGit({ progress: onProgress, abort: signal, @@ -55,28 +77,17 @@ const createGitClientForPath = ( ...unsafe, ...additionalUnsafe, }, + /** + * simple-git throws when an explicitly supplied git-related env var + * (e.g., GIT_CEILING_DIRECTORIES, GIT_ASKPASS) is not in this allowlist. + * We construct this environment ourselves, so every key is permitted. + * Values that enable unsafe behaviour are still gated by `unsafe` above. + * + * @see https://github.com/steveukx/git-js/releases/tag/simple-git%404.0.0 + */ + allowEnvironment: Object.keys(gitEnvironment), }) - .env({ - ...process.env, - ...environment, - /** - * @note on some inside-baseball on why this is necessary: The specific - * issue we saw was that a `git clone` would fail without throwing, and - * then a subsequent `git config` command would run, but since the clone - * failed, it wouldn't be running in a git directory. Git would then walk - * up the directory tree until it either found a git directory (in the case - * of the development env) or it would hit a GIT_DISCOVERY_ACROSS_FILESYSTEM - * error when trying to cross a filesystem boundary (in the prod case). - * GIT_CEILING_DIRECTORIES ensures that this walk will be limited to the - * parent directory. - */ - GIT_CEILING_DIRECTORIES: parentPath, - /** - * Disable git credential prompts. This ensures that git operations will fail - * immediately if credentials are not available, rather than prompting for input. - */ - GIT_TERMINAL_PROMPT: '0', - }) + .env(gitEnvironment) .cwd({ path, }); diff --git a/packages/web/package.json b/packages/web/package.json index 3f926f5fe..b6c85bd7d 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -193,7 +193,7 @@ "scroll-into-view-if-needed": "^3.1.0", "server-only": "^0.0.1", "sharp": "^0.35.3", - "simple-git": "^3.36.0", + "simple-git": "^4.0.2", "slate": "^0.117.0", "slate-dom": "^0.116.0", "slate-history": "^0.113.1", diff --git a/packages/web/src/features/git/getFileBlameApi.ts b/packages/web/src/features/git/getFileBlameApi.ts index d4b3c81c7..f922bd3f6 100644 --- a/packages/web/src/features/git/getFileBlameApi.ts +++ b/packages/web/src/features/git/getFileBlameApi.ts @@ -3,7 +3,7 @@ import { ServiceError, notFound, fileNotFound, invalidGitRef, unresolvedGitRef, import { withOptionalAuth } from '@/middleware/withAuth'; import { getRepoPath } from '@sourcebot/shared'; import { headers } from 'next/headers'; -import simpleGit from 'simple-git'; +import { simpleGit } from 'simple-git'; import type z from 'zod'; import { isGitRefValid, isPathValid } from './utils'; import { fileBlameRequestSchema, fileBlameResponseSchema } from './schemas'; diff --git a/packages/web/src/features/git/getFileSourceApi.test.ts b/packages/web/src/features/git/getFileSourceApi.test.ts index 9f08200be..0553fa394 100644 --- a/packages/web/src/features/git/getFileSourceApi.test.ts +++ b/packages/web/src/features/git/getFileSourceApi.test.ts @@ -1,12 +1,10 @@ import { describe, it, expect, vi, beforeEach, type Mock } from 'vitest'; // Hoist the mock function so it can be referenced in both the vi.mock factory -// and the test body. The SUT imports simpleGit as a default export; the factory -// maps both default and named exports to the same fn so both resolve identically. +// and the test body. const mockSimpleGit = vi.hoisted(() => vi.fn()); vi.mock('simple-git', () => ({ - default: mockSimpleGit, simpleGit: mockSimpleGit, })); vi.mock('@sourcebot/shared', () => ({ diff --git a/packages/web/src/features/git/getFileSourceApi.ts b/packages/web/src/features/git/getFileSourceApi.ts index 56eedc8ae..ef057362b 100644 --- a/packages/web/src/features/git/getFileSourceApi.ts +++ b/packages/web/src/features/git/getFileSourceApi.ts @@ -9,7 +9,7 @@ import { withOptionalAuth } from '@/middleware/withAuth'; import { env, getRepoPath } from '@sourcebot/shared'; import { Org, PrismaClient } from '@sourcebot/db'; import { headers } from 'next/headers'; -import simpleGit from 'simple-git'; +import { simpleGit } from 'simple-git'; import type z from 'zod'; import { isGitRefValid, isPathValid } from './utils'; import { fileSourceRequestSchema, fileSourceResponseSchema } from './schemas'; diff --git a/packages/web/src/features/git/getFilesApi.ts b/packages/web/src/features/git/getFilesApi.ts index 87aac0e78..ac218d445 100644 --- a/packages/web/src/features/git/getFilesApi.ts +++ b/packages/web/src/features/git/getFilesApi.ts @@ -3,7 +3,7 @@ import { FileTreeItem } from "./types"; import { notFound, ServiceError, unexpectedError } from '@/lib/serviceError'; import { withOptionalAuth } from "@/middleware/withAuth"; import { getRepoPath } from '@sourcebot/shared'; -import simpleGit from 'simple-git'; +import { simpleGit } from 'simple-git'; import type z from 'zod'; import { getFilesRequestSchema, getFilesResponseSchema } from './schemas'; import { logger } from './logger'; diff --git a/packages/web/src/features/git/getFolderContentsApi.ts b/packages/web/src/features/git/getFolderContentsApi.ts index 71b08440b..e2d1180ca 100644 --- a/packages/web/src/features/git/getFolderContentsApi.ts +++ b/packages/web/src/features/git/getFolderContentsApi.ts @@ -3,7 +3,7 @@ import { FileTreeItem } from "./types"; import { notFound, unexpectedError } from '@/lib/serviceError'; import { withOptionalAuth } from "@/middleware/withAuth"; import { getRepoPath } from '@sourcebot/shared'; -import simpleGit from 'simple-git'; +import { simpleGit } from 'simple-git'; import z from 'zod'; import { compareFileTreeItems, isPathValid, normalizePath } from './utils'; import { logger } from './logger'; diff --git a/packages/web/src/features/git/getTreeApi.ts b/packages/web/src/features/git/getTreeApi.ts index fecbb958d..22bcb2e45 100644 --- a/packages/web/src/features/git/getTreeApi.ts +++ b/packages/web/src/features/git/getTreeApi.ts @@ -4,7 +4,7 @@ import { invalidGitRef, notFound, ServiceError, unexpectedError } from '@/lib/se import { withOptionalAuth } from "@/middleware/withAuth"; import { getRepoPath } from '@sourcebot/shared'; import { headers } from 'next/headers'; -import simpleGit from 'simple-git'; +import { simpleGit } from 'simple-git'; import type z from 'zod'; import { getTreeRequestSchema, getTreeResponseSchema } from './schemas'; import { buildFileTree, isGitRefValid, isPathValid, normalizePath } from './utils'; diff --git a/yarn.lock b/yarn.lock index 28ed17d9e..048361f9a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8269,19 +8269,19 @@ __metadata: languageName: node linkType: hard -"@simple-git/args-pathspec@npm:^1.0.3": - version: 1.0.3 - resolution: "@simple-git/args-pathspec@npm:1.0.3" - checksum: 10c0/91bfc99daa956df28e4efd683cd799f60c6d169fce6adf71a9efa80a6b5938fed4b03e55fa929cfd51aed64f3ada5c1e4edad45a3872dbd94d11924b3258b5bc +"@simple-git/args-pathspec@npm:1.0.4, @simple-git/args-pathspec@npm:^1.0.4": + version: 1.0.4 + resolution: "@simple-git/args-pathspec@npm:1.0.4" + checksum: 10c0/f62c09daf6a17734b2a13a186421bf0fdbdbd48782d1ca6d751027b2a9f515f11505da672489609f95335a0541d2fcf6d6fd6c2754919245109e92335e437b1b languageName: node linkType: hard -"@simple-git/argv-parser@npm:^1.1.0": - version: 1.1.1 - resolution: "@simple-git/argv-parser@npm:1.1.1" +"@simple-git/argv-parser@npm:2.0.1, @simple-git/argv-parser@npm:^2.0.1": + version: 2.0.1 + resolution: "@simple-git/argv-parser@npm:2.0.1" dependencies: - "@simple-git/args-pathspec": "npm:^1.0.3" - checksum: 10c0/2c21166f1bb7c4373e7b4e52bd0c7f333e58ea0ff5ac0b6c2d305835f4a2bcad1ef4bcce3cff63312ac55655ea7be3aba4c7c0c41e3ebcb8bee343f65bb92f5e + "@simple-git/args-pathspec": "npm:^1.0.4" + checksum: 10c0/7d2cd9852139ca3b524dcd91f6a887fa505cfb68c8813d7b849005566147365bb1e34f5450411c494fbd714a80c123058e65dc2ffc0b41d059e30bdc98e12223 languageName: node linkType: hard @@ -8846,6 +8846,7 @@ __metadata: "@sentry/cli": "npm:^2.42.2" "@sentry/node": "npm:^10.71.0" "@sentry/profiling-node": "npm:^10.71.0" + "@simple-git/argv-parser": "npm:^2.0.1" "@sourcebot/db": "workspace:*" "@sourcebot/schemas": "workspace:*" "@sourcebot/shared": "workspace:*" @@ -8875,7 +8876,7 @@ __metadata: posthog-node: "npm:^5.51.2" prom-client: "npm:^15.1.3" redlock: "npm:5.0.0-beta.2" - simple-git: "npm:^3.36.0" + simple-git: "npm:^4.0.2" tsc-watch: "npm:^6.2.0" tsx: "npm:^4.21.0" typescript: "npm:^5.6.2" @@ -9179,7 +9180,7 @@ __metadata: scroll-into-view-if-needed: "npm:^3.1.0" server-only: "npm:^0.0.1" sharp: "npm:^0.35.3" - simple-git: "npm:^3.36.0" + simple-git: "npm:^4.0.2" slate: "npm:^0.117.0" slate-dom: "npm:^0.116.0" slate-history: "npm:^0.113.1" @@ -21493,16 +21494,16 @@ __metadata: languageName: node linkType: hard -"simple-git@npm:^3.36.0": - version: 3.36.0 - resolution: "simple-git@npm:3.36.0" +"simple-git@npm:^4.0.2": + version: 4.0.2 + resolution: "simple-git@npm:4.0.2" dependencies: "@kwsites/file-exists": "npm:^1.1.1" "@kwsites/promise-deferred": "npm:^1.1.1" - "@simple-git/args-pathspec": "npm:^1.0.3" - "@simple-git/argv-parser": "npm:^1.1.0" + "@simple-git/args-pathspec": "npm:1.0.4" + "@simple-git/argv-parser": "npm:2.0.1" debug: "npm:^4.4.0" - checksum: 10c0/4c22e57107535168f354e5abbbf6e618a7b39d76491ca225c70588520fbe86891f3b9a5c4f8a3fc0137e669aad2f0e11f6c6e677bfec07169cd18f29bf23cb77 + checksum: 10c0/d028927258fa286d9d8e462f29ec6a37a32398acd7e53cef7fc81e70636c149d7359a542d1a4f8490b342d40d98e341c35c718734aec448fc24fdee88566e981 languageName: node linkType: hard