deterministically set up working branch

This commit is contained in:
Colin McDonnell
2025-11-20 16:31:00 -08:00
parent 6c6b7b0b2d
commit 0ce1d9fd7b
4 changed files with 49 additions and 1 deletions
+1
View File
@@ -16,6 +16,7 @@ You do not add unecessary comments, tests, or documentation unless explicitly pr
You adapt your writing style to the style of your coworkers, while never being unprofessional.
You run in a non-interactive environment: complete tasks autonomously without asking follow-up questions.
You make reasonable assumptions when details are missing, but fail with an explicit error if critical information is missing (e.g. user asks to review a PR but does not provide a link or ID).
Never push commits directly to protected branches: main, master, production. Always create a feature branch.
## SECURITY
+6
View File
@@ -46,6 +46,7 @@ export type PayloadEvent =
pr_number: number;
pr_title: string;
pr_body: string | null;
branch: string;
[key: string]: any;
}
| {
@@ -53,6 +54,7 @@ export type PayloadEvent =
pr_number: number;
pr_title: string;
pr_body: string | null;
branch: string;
[key: string]: any;
}
| {
@@ -63,6 +65,7 @@ export type PayloadEvent =
review_state: string;
review_comments: any[];
context: any;
branch: string;
[key: string]: any;
}
| {
@@ -72,6 +75,7 @@ export type PayloadEvent =
comment_id: number;
comment_body: string;
thread?: any;
branch: string;
[key: string]: any;
}
| {
@@ -100,6 +104,7 @@ export type PayloadEvent =
comment_id: number;
comment_body: string;
issue_number: number;
branch?: string;
[key: string]: any;
}
| {
@@ -108,6 +113,7 @@ export type PayloadEvent =
pr_title: string;
pr_body: string | null;
pull_request: any;
branch: string;
check_suite: {
id: number;
head_sha: string;
+2 -1
View File
@@ -17,7 +17,7 @@ import {
revokeInstallationToken,
setupGitHubInstallationToken,
} from "./utils/github.ts";
import { setupGitAuth, setupGitConfig } from "./utils/setup.ts";
import { setupGitAuth, setupGitBranch, setupGitConfig } from "./utils/setup.ts";
// runtime validation using agents (needed for ArkType)
// Note: The AgentName type is defined in external.ts, this is the runtime validator
@@ -57,6 +57,7 @@ export async function main(inputs: Inputs): Promise<MainResult> {
setupMcpLogPolling(ctx);
ctx.payload = parsePayload(inputs);
setupGitBranch(ctx.payload);
setupMcpServers(ctx);
await installAgentCli(ctx);
validateApiKey(ctx);
+40
View File
@@ -1,5 +1,6 @@
import { execSync } from "node:child_process";
import { existsSync, rmSync } from "node:fs";
import type { Payload } from "../external.ts";
import { log } from "./cli.ts";
import type { RepoContext } from "./github.ts";
import { $ } from "./shell.ts";
@@ -91,3 +92,42 @@ export function setupGitAuth(githubToken: string, repoContext: RepoContext): voi
$("git", ["remote", "set-url", "origin", remoteUrl]);
log.info("✓ Updated remote URL with authentication token");
}
/**
* Setup git branch based on payload event context
* Automatically checks out the appropriate branch before agent execution
*/
export function setupGitBranch(payload: Payload): void {
// Only set up git branch in GitHub Actions environment
// In local testing, this might interfere with local git state
if (!process.env.GITHUB_ACTIONS) {
return;
}
const branch = payload.event.branch;
if (!branch) {
log.debug("No branch specified in payload, using default branch");
return;
}
log.info(`🌿 Setting up git branch: ${branch}`);
try {
// Fetch the branch from origin
log.debug(`Fetching branch from origin: ${branch}`);
execSync(`git fetch origin ${branch}`, { stdio: "pipe" });
// Checkout the branch, creating local tracking branch
log.debug(`Checking out branch: ${branch}`);
execSync(`git checkout -B ${branch} origin/${branch}`, { stdio: "pipe" });
log.info(`✓ Successfully checked out branch: ${branch}`);
} catch (error) {
// If git operations fail, log warning but don't fail the action
// The agent might still be able to work with the default branch
log.warning(
`Failed to checkout branch ${branch}: ${error instanceof Error ? error.message : String(error)}`
);
}
}