Compare commits

...

3 Commits

Author SHA1 Message Date
Pullfrog Action 85731f8360 fix action cwd 2025-10-23 16:18:55 -04:00
David Blass 1922352d86 fix git push auth 2025-10-23 16:12:15 -04:00
David Blass c0f31415a3 try setting cwd 2025-10-23 15:43:50 -04:00
8 changed files with 45 additions and 25 deletions
+3 -2
View File
@@ -32,9 +32,10 @@ runs:
shell: bash shell: bash
working-directory: ${{ github.action_path }} working-directory: ${{ github.action_path }}
- name: Run agent - name: Run agent
run: node entry.ts run: |
cd $GITHUB_WORKSPACE
node ${{ github.action_path }}/entry.ts
shell: bash shell: bash
working-directory: ${{ github.action_path }}
env: env:
INPUTS_JSON: ${{ toJSON(inputs) }} INPUTS_JSON: ${{ toJSON(inputs) }}
+1 -2
View File
@@ -77,7 +77,6 @@ export class ClaudeAgent implements Agent {
const env = { const env = {
ANTHROPIC_API_KEY: this.apiKey, ANTHROPIC_API_KEY: this.apiKey,
GITHUB_TOKEN: this.githubInstallationToken,
}; };
console.log(boxString(prompt, { title: "Prompt" })); console.log(boxString(prompt, { title: "Prompt" }));
@@ -172,7 +171,7 @@ function processJSONChunk(chunk: string, agent?: ClaudeAgent): void {
console.log(chunk); console.log(chunk);
return; return;
} }
console.log(chunk); console.log(chunk);
const parsedChunk = JSON.parse(trimmedChunk); const parsedChunk = JSON.parse(trimmedChunk);
+7 -2
View File
@@ -1,7 +1,8 @@
import * as core from "@actions/core"; import * as core from "@actions/core";
import { type } from "arktype"; import { type } from "arktype";
import { ClaudeAgent } from "./agents/claude.ts"; import { ClaudeAgent } from "./agents/claude.ts";
import { setupGitHubInstallationToken } from "./utils/github.ts"; import { setupGitHubInstallationToken, parseRepoContext } from "./utils/github.ts";
import { setupGitConfig, setupGitAuth } from "./utils/setup.ts";
export const Inputs = type({ export const Inputs = type({
prompt: "string", prompt: "string",
@@ -20,8 +21,12 @@ export async function main(inputs: Inputs): Promise<MainResult> {
try { try {
core.info(`→ Starting agent run with Claude Code`); core.info(`→ Starting agent run with Claude Code`);
// Setup GitHub installation token setupGitConfig();
const githubInstallationToken = await setupGitHubInstallationToken(); const githubInstallationToken = await setupGitHubInstallationToken();
const repoContext = parseRepoContext();
setupGitAuth(githubInstallationToken, repoContext);
const agent = new ClaudeAgent({ const agent = new ClaudeAgent({
apiKey: inputs.anthropic_api_key!, apiKey: inputs.anthropic_api_key!,
+3 -6
View File
@@ -2,18 +2,15 @@
* Simple MCP configuration helper for adding our minimal GitHub comment server * Simple MCP configuration helper for adding our minimal GitHub comment server
*/ */
import { fromHere } from "@ark/fs"; import { fromHere } from "@ark/fs";
import { parseRepoContext } from "../utils/github.ts";
const actionPath = fromHere(".."); const actionPath = fromHere("..");
export const mcpServerName = "gh-pullfrog"; export const mcpServerName = "gh-pullfrog";
export function createMcpConfig(githubInstallationToken: string) { export function createMcpConfig(githubInstallationToken: string) {
const githubRepository = process.env.GITHUB_REPOSITORY; const repoContext = parseRepoContext();
if (!githubRepository) { const githubRepository = `${repoContext.owner}/${repoContext.name}`;
throw new Error(
"GITHUB_REPOSITORY environment variable is required for MCP GitHub integration"
);
}
return JSON.stringify( return JSON.stringify(
{ {
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@pullfrog/action", "name": "@pullfrog/action",
"version": "0.0.55", "version": "0.0.58",
"type": "module", "type": "module",
"files": [ "files": [
"index.js", "index.js",
+1 -4
View File
@@ -3,7 +3,7 @@ import { existsSync } from "node:fs";
import { dirname, join } from "node:path"; import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url"; import { fileURLToPath } from "node:url";
import { config } from "dotenv"; import { config } from "dotenv";
import { buildAction, setupTestRepo } from "./setup.ts"; import { setupTestRepo } from "./setup.ts";
const __filename = fileURLToPath(import.meta.url); const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename); const __dirname = dirname(__filename);
@@ -19,8 +19,6 @@ export function runAct(prompt: string): void {
config({ path: envPath }); config({ path: envPath });
buildAction(actionPath);
const workflowPath = join(tempDir, ".github", "workflows", "pullfrog.yml"); const workflowPath = join(tempDir, ".github", "workflows", "pullfrog.yml");
const distPath = join(actionPath, ".act-dist"); const distPath = join(actionPath, ".act-dist");
@@ -54,7 +52,6 @@ export function runAct(prompt: string): void {
} }
}); });
const actCommand = actCommandParts.join(" "); const actCommand = actCommandParts.join(" ");
console.log("🚀 Running act with prompt:"); console.log("🚀 Running act with prompt:");
+26 -7
View File
@@ -1,5 +1,6 @@
import { execSync } from "node:child_process"; import { execSync } from "node:child_process";
import { existsSync, rmSync } from "node:fs"; import { existsSync, rmSync } from "node:fs";
import type { RepoContext } from "./github.ts";
export interface SetupOptions { export interface SetupOptions {
tempDir: string; tempDir: string;
@@ -38,12 +39,30 @@ export function setupTestRepo(options: SetupOptions): void {
} }
/** /**
* Build the action bundles * Setup git configuration to avoid identity errors
*/ */
export function buildAction(actionPath: string): void { export function setupGitConfig(): void {
console.log("🔨 Building fresh bundles with esbuild..."); console.log("🔧 Setting up git configuration...");
execSync("node esbuild.config.js", { execSync('git config --global user.email "action@pullfrog.ai"', { stdio: "inherit" });
cwd: actionPath, execSync('git config --global user.name "Pullfrog Action"', { stdio: "inherit" });
stdio: "inherit", }
});
/**
* Setup git authentication using GitHub token
*/
export function setupGitAuth(githubToken: string, repoContext: RepoContext): void {
console.log("🔐 Setting up git authentication...");
// Remove existing git auth headers that actions/checkout might have set
try {
execSync("git config --unset-all http.https://github.com/.extraheader", { stdio: "inherit" });
console.log("✓ Removed existing authentication headers");
} catch {
console.log("No existing authentication headers to remove");
}
// Update remote URL to embed the token
const remoteUrl = `https://x-access-token:${githubToken}@github.com/${repoContext.owner}/${repoContext.name}.git`;
execSync(`git remote set-url origin "${remoteUrl}"`, { stdio: "inherit" });
console.log("✓ Updated remote URL with authentication token");
} }
+3 -1
View File
@@ -6,6 +6,7 @@ export interface SpawnOptions {
env?: Record<string, string>; env?: Record<string, string>;
input?: string; input?: string;
timeout?: number; timeout?: number;
cwd?: string;
onStdout?: (chunk: string) => void; onStdout?: (chunk: string) => void;
onStderr?: (chunk: string) => void; onStderr?: (chunk: string) => void;
} }
@@ -21,7 +22,7 @@ export interface SpawnResult {
* Spawn a subprocess with streaming callbacks and buffered results * Spawn a subprocess with streaming callbacks and buffered results
*/ */
export async function spawn(options: SpawnOptions): Promise<SpawnResult> { export async function spawn(options: SpawnOptions): Promise<SpawnResult> {
const { cmd, args, env, input, timeout, onStdout, onStderr } = options; const { cmd, args, env, input, timeout, cwd, onStdout, onStderr } = options;
const startTime = Date.now(); const startTime = Date.now();
let stdoutBuffer = ""; let stdoutBuffer = "";
@@ -31,6 +32,7 @@ export async function spawn(options: SpawnOptions): Promise<SpawnResult> {
const child = nodeSpawn(cmd, args, { const child = nodeSpawn(cmd, args, {
env: env ? { ...process.env, ...env } : process.env, env: env ? { ...process.env, ...env } : process.env,
stdio: ["pipe", "pipe", "pipe"], stdio: ["pipe", "pipe", "pipe"],
cwd: cwd || process.cwd(),
}); });
let timeoutId: NodeJS.Timeout | undefined; let timeoutId: NodeJS.Timeout | undefined;