| author | |
| committer | |
| log | 30be31195883635aba96031a8d79c255fb28b438 |
| tree | 7797945e2f8dfdb3008033567b1609ce0d7d7e93 |
| parent | 4e169df1dd12e0ed960dcb310e9460897759a55e |
| signature | Signed by PGP key B5690EEEBB952194 |
4 files changed, 68 insertions(+), 0 deletions(-)
apps/server/src/git/GitManager.test.ts+51| ... | ... | @@ -2404,6 +2404,57 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { |
| 2404 | 2404 | }), |
| 2405 | 2405 | ); |
| 2406 | 2406 | |
| 2407 | it.effect("create_pr targets the remote default branch when it is not main", () => | |
| 2408 | Effect.gen(function* () { | |
| 2409 | const repoDir = yield* makeTempDir("t3code-git-manager-"); | |
| 2410 | yield* initRepo(repoDir); | |
| 2411 | const remoteDir = yield* createBareRemote(); | |
| 2412 | yield* runGit(repoDir, ["remote", "add", "origin", remoteDir]); | |
| 2413 | // A repository whose default branch is master, with no main anywhere. | |
| 2414 | yield* runGit(repoDir, ["push", "origin", "HEAD:master"]); | |
| 2415 | yield* runGit(repoDir, ["fetch", "origin"]); | |
| 2416 | yield* runGit(repoDir, ["remote", "set-head", "origin", "master"]); | |
| 2417 | ||
| 2418 | yield* runGit(repoDir, ["checkout", "-b", "feature/master-default"]); | |
| 2419 | NodeFS.writeFileSync(NodePath.join(repoDir, "master-default.txt"), "master default\n"); | |
| 2420 | yield* runGit(repoDir, ["add", "master-default.txt"]); | |
| 2421 | yield* runGit(repoDir, ["commit", "-m", "Master default"]); | |
| 2422 | ||
| 2423 | const { manager, ghCalls } = yield* makeManager({ | |
| 2424 | ghScenario: { | |
| 2425 | // Mirrors a provider that cannot report a default branch, as the Azure | |
| 2426 | // DevOps CLI does when it cannot detect the repository. | |
| 2427 | defaultBranch: "", | |
| 2428 | prListSequence: [ | |
| 2429 | "[]", | |
| 2430 | // @effect-diagnostics-next-line preferSchemaOverJson:off | |
| 2431 | JSON.stringify([ | |
| 2432 | { | |
| 2433 | number: 505, | |
| 2434 | title: "Master default", | |
| 2435 | url: "https://github.com/pingdotgg/codething-mvp/pull/505", | |
| 2436 | baseRefName: "master", | |
| 2437 | headRefName: "feature/master-default", | |
| 2438 | }, | |
| 2439 | ]), | |
| 2440 | ], | |
| 2441 | }, | |
| 2442 | }); | |
| 2443 | ||
| 2444 | const result = yield* runStackedAction(manager, { | |
| 2445 | cwd: repoDir, | |
| 2446 | action: "create_pr", | |
| 2447 | }); | |
| 2448 | ||
| 2449 | expect(result.pr.status).toBe("created"); | |
| 2450 | expect( | |
| 2451 | ghCalls.some((call) => | |
| 2452 | call.includes("pr create --base master --head feature/master-default"), | |
| 2453 | ), | |
| 2454 | ).toBe(true); | |
| 2455 | }), | |
| 2456 | ); | |
| 2457 | ||
| 2407 | 2458 | it.effect("returns existing PR metadata for commit/push/pr action", () => |
| 2408 | 2459 | Effect.gen(function* () { |
| 2409 | 2460 | const repoDir = yield* makeTempDir("t3code-git-manager-"); |
apps/server/src/git/GitManager.ts+12| ... | ... | @@ -1489,6 +1489,18 @@ export const make = Effect.gen(function* () { |
| 1489 | 1489 | return defaultFromProvider; |
| 1490 | 1490 | } |
| 1491 | 1491 | |
| 1492 | // The provider lookup can fail for reasons unrelated to the branch, so fall | |
| 1493 | // back to what the remote itself records before assuming a name. A repository | |
| 1494 | // whose default branch is master would otherwise get a base branch that does | |
| 1495 | // not exist. | |
| 1496 | const defaultFromRemote = yield* gitCore.resolvePrimaryRemoteName(cwd).pipe( | |
| 1497 | Effect.flatMap((remoteName) => gitCore.resolveDefaultBranchName(cwd, remoteName)), | |
| 1498 | Effect.orElseSucceed(() => null), | |
| 1499 | ); | |
| 1500 | if (defaultFromRemote) { | |
| 1501 | return defaultFromRemote; | |
| 1502 | } | |
| 1503 | ||
| 1492 | 1504 | return "main"; |
| 1493 | 1505 | }); |
| 1494 | 1506 |
apps/server/src/vcs/GitVcsDriver.ts+4| ... | ... | @@ -289,6 +289,10 @@ export class GitVcsDriver extends Context.Service< |
| 289 | 289 | ) => Effect.Effect<GitRefreshCheckedOutBranchResult, GitCommandError>; |
| 290 | 290 | readonly ensureRemote: (input: GitEnsureRemoteInput) => Effect.Effect<string, GitCommandError>; |
| 291 | 291 | readonly resolvePrimaryRemoteName: (cwd: string) => Effect.Effect<string, GitCommandError>; |
| 292 | readonly resolveDefaultBranchName: ( | |
| 293 | cwd: string, | |
| 294 | remoteName: string, | |
| 295 | ) => Effect.Effect<string | null, GitCommandError>; | |
| 292 | 296 | readonly fetchRemote: (input: GitFetchRemoteInput) => Effect.Effect<void, GitCommandError>; |
| 293 | 297 | readonly remoteExists: (input: GitRemoteExistsInput) => Effect.Effect<boolean, GitCommandError>; |
| 294 | 298 | readonly resolveRemoteTrackingCommit: ( |
apps/server/src/vcs/GitVcsDriverCore.ts+1| ... | ... | @@ -3189,6 +3189,7 @@ export const makeGitVcsDriverCore = Effect.fn("makeGitVcsDriverCore")(function* |
| 3189 | 3189 | withListRefsInvalidation(input.cwd, refreshCheckedOutBranch(input)), |
| 3190 | 3190 | ensureRemote: (input) => withListRefsInvalidation(input.cwd, ensureRemote(input)), |
| 3191 | 3191 | resolvePrimaryRemoteName, |
| 3192 | resolveDefaultBranchName, | |
| 3192 | 3193 | fetchRemote: (input) => withListRefsInvalidation(input.cwd, fetchRemote(input)), |
| 3193 | 3194 | remoteExists, |
| 3194 | 3195 | resolveRemoteTrackingCommit, |