mirror of
https://github.com/anthropics/claude-code-action.git
synced 2026-01-23 23:14:13 +08:00
add schedule & workflow dispatch paths. Also make prepare logic conditional
This commit is contained in:
@@ -34,6 +34,16 @@ const BASE_ALLOWED_TOOLS = [
|
||||
];
|
||||
const DISALLOWED_TOOLS = ["WebSearch", "WebFetch"];
|
||||
|
||||
function getEntityNumberXml(eventData: EventData): string {
|
||||
if (eventData.isPR && "prNumber" in eventData) {
|
||||
return `<pr_number>${eventData.prNumber}</pr_number>`;
|
||||
}
|
||||
if ("issueNumber" in eventData) {
|
||||
return `<issue_number>${eventData.issueNumber}</issue_number>`;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
export function buildAllowedToolsString(
|
||||
customAllowedTools?: string[],
|
||||
includeActionsTools: boolean = false,
|
||||
@@ -125,8 +135,10 @@ export function prepareContext(
|
||||
const isPR = context.isPR;
|
||||
|
||||
// Get PR/Issue number from entityNumber
|
||||
const prNumber = isPR ? context.entityNumber.toString() : undefined;
|
||||
const issueNumber = !isPR ? context.entityNumber.toString() : undefined;
|
||||
const prNumber =
|
||||
isPR && context.entityNumber ? context.entityNumber.toString() : undefined;
|
||||
const issueNumber =
|
||||
!isPR && context.entityNumber ? context.entityNumber.toString() : undefined;
|
||||
|
||||
// Extract trigger username and comment data based on event type
|
||||
let triggerUsername: string | undefined;
|
||||
@@ -338,6 +350,24 @@ export function prepareContext(
|
||||
};
|
||||
break;
|
||||
|
||||
case "workflow_dispatch":
|
||||
eventData = {
|
||||
eventName: "workflow_dispatch",
|
||||
isPR: false,
|
||||
...(baseBranch && { baseBranch }),
|
||||
...(claudeBranch && { claudeBranch }),
|
||||
};
|
||||
break;
|
||||
|
||||
case "schedule":
|
||||
eventData = {
|
||||
eventName: "schedule",
|
||||
isPR: false,
|
||||
...(baseBranch && { baseBranch }),
|
||||
...(claudeBranch && { claudeBranch }),
|
||||
};
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error(`Unsupported event type: ${eventName}`);
|
||||
}
|
||||
@@ -400,6 +430,18 @@ export function getEventTypeAndContext(envVars: PreparedContext): {
|
||||
: `pull request event`,
|
||||
};
|
||||
|
||||
case "workflow_dispatch":
|
||||
return {
|
||||
eventType: "WORKFLOW_DISPATCH",
|
||||
triggerContext: `workflow dispatch event`,
|
||||
};
|
||||
|
||||
case "schedule":
|
||||
return {
|
||||
eventType: "SCHEDULE",
|
||||
triggerContext: `scheduled automation event`,
|
||||
};
|
||||
|
||||
default:
|
||||
throw new Error(`Unexpected event type`);
|
||||
}
|
||||
@@ -407,11 +449,12 @@ export function getEventTypeAndContext(envVars: PreparedContext): {
|
||||
|
||||
function getCommitInstructions(
|
||||
eventData: EventData,
|
||||
githubData: FetchDataResult,
|
||||
githubData: FetchDataResult | null,
|
||||
context: PreparedContext,
|
||||
useCommitSigning: boolean,
|
||||
): string {
|
||||
const coAuthorLine =
|
||||
githubData &&
|
||||
(githubData.triggerDisplayName ?? context.triggerUsername !== "Unknown")
|
||||
? `Co-authored-by: ${githubData.triggerDisplayName ?? context.triggerUsername} <${context.triggerUsername}@users.noreply.github.com>`
|
||||
: "";
|
||||
@@ -466,8 +509,26 @@ function getCommitInstructions(
|
||||
function substitutePromptVariables(
|
||||
template: string,
|
||||
context: PreparedContext,
|
||||
githubData: FetchDataResult,
|
||||
githubData: FetchDataResult | null,
|
||||
): string {
|
||||
// Handle automation events without GitHub data
|
||||
if (!githubData) {
|
||||
const { eventData } = context;
|
||||
const variables: Record<string, string> = {
|
||||
EVENT_TYPE: eventData.eventName,
|
||||
REPOSITORY: context.repository,
|
||||
TRIGGER_USERNAME: context.triggerUsername ?? "automation",
|
||||
CURRENT_BRANCH: eventData.claudeBranch || eventData.baseBranch || "main",
|
||||
BASE_BRANCH: eventData.baseBranch || "main",
|
||||
};
|
||||
|
||||
return Object.entries(variables).reduce(
|
||||
(prompt, [key, value]) =>
|
||||
prompt.replace(new RegExp(`{{${key}}}`, "g"), value),
|
||||
template,
|
||||
);
|
||||
}
|
||||
|
||||
const { contextData, comments, reviewData, changedFilesWithSHA } = githubData;
|
||||
const { eventData } = context;
|
||||
|
||||
@@ -528,7 +589,7 @@ function substitutePromptVariables(
|
||||
|
||||
export function generatePrompt(
|
||||
context: PreparedContext,
|
||||
githubData: FetchDataResult,
|
||||
githubData: FetchDataResult | null,
|
||||
useCommitSigning: boolean,
|
||||
): string {
|
||||
if (context.overridePrompt) {
|
||||
@@ -539,6 +600,59 @@ export function generatePrompt(
|
||||
);
|
||||
}
|
||||
|
||||
const { eventData } = context;
|
||||
|
||||
// Handle automation events that don't have GitHub data
|
||||
if (!githubData) {
|
||||
// For automation events, we have minimal context
|
||||
const { eventType, triggerContext } = getEventTypeAndContext(context);
|
||||
|
||||
let promptContent = `You are Claude, an AI assistant designed to help with GitHub ${eventData.eventName === "workflow_dispatch" ? "workflow dispatch" : "scheduled automation"} tasks. Think carefully as you analyze the context and respond appropriately. Here's the context for your current task:
|
||||
|
||||
<formatted_context>
|
||||
Repository: ${context.repository}
|
||||
Event Type: ${eventData.eventName}
|
||||
Current Branch: ${eventData.claudeBranch || eventData.baseBranch || "main"}
|
||||
Base Branch: ${eventData.baseBranch || "main"}
|
||||
Actor: ${context.triggerUsername ?? "automation"}
|
||||
</formatted_context>
|
||||
|
||||
<event_type>${eventType}</event_type>
|
||||
<is_pr>false</is_pr>
|
||||
<trigger_context>${triggerContext}</trigger_context>
|
||||
<repository>${context.repository}</repository>
|
||||
<trigger_username>${context.triggerUsername ?? "automation"}</trigger_username>
|
||||
${
|
||||
context.directPrompt
|
||||
? `<direct_prompt>
|
||||
IMPORTANT: The following are direct instructions from the automation workflow:
|
||||
|
||||
${sanitizeContent(context.directPrompt)}
|
||||
</direct_prompt>`
|
||||
: ""
|
||||
}
|
||||
|
||||
<instructions>
|
||||
You have been triggered by an automated workflow. Follow these guidelines:
|
||||
|
||||
1. **Context**: You are running in an automated context without a specific issue or PR.
|
||||
2. **Branch**: You are currently on the ${eventData.claudeBranch || eventData.baseBranch || "main"} branch.
|
||||
3. **Tools**: You have access to file system and Git tools to make changes.
|
||||
${
|
||||
useCommitSigning
|
||||
? "4. **Commits**: Use the MCP file operations server for signed commits."
|
||||
: "4. **Commits**: You can commit changes directly using Git."
|
||||
}
|
||||
5. **Scope**: Focus on the task described${context.directPrompt ? " in the direct_prompt above" : ""}.
|
||||
|
||||
Please proceed with the automated task.
|
||||
</instructions>
|
||||
|
||||
${context.customInstructions || ""}`;
|
||||
|
||||
return promptContent;
|
||||
}
|
||||
|
||||
const {
|
||||
contextData,
|
||||
comments,
|
||||
@@ -546,11 +660,10 @@ export function generatePrompt(
|
||||
reviewData,
|
||||
imageUrlMap,
|
||||
} = githubData;
|
||||
const { eventData } = context;
|
||||
|
||||
const { eventType, triggerContext } = getEventTypeAndContext(context);
|
||||
|
||||
const formattedContext = formatContext(contextData, eventData.isPR);
|
||||
const formattedContext = formatContext(contextData, eventData.isPR ?? false);
|
||||
const formattedComments = formatComments(comments, imageUrlMap);
|
||||
const formattedReviewComments = eventData.isPR
|
||||
? formatReviewComments(reviewData, imageUrlMap)
|
||||
@@ -596,17 +709,13 @@ ${eventData.isPR ? formattedChangedFiles || "No files changed" : ""}
|
||||
</changed_files>${imagesInfo}
|
||||
|
||||
<event_type>${eventType}</event_type>
|
||||
<is_pr>${eventData.isPR ? "true" : "false"}</is_pr>
|
||||
<is_pr>${(eventData.isPR ?? false) ? "true" : "false"}</is_pr>
|
||||
<trigger_context>${triggerContext}</trigger_context>
|
||||
<repository>${context.repository}</repository>
|
||||
${
|
||||
eventData.isPR
|
||||
? `<pr_number>${eventData.prNumber}</pr_number>`
|
||||
: `<issue_number>${eventData.issueNumber ?? ""}</issue_number>`
|
||||
}
|
||||
${getEntityNumberXml(eventData)}
|
||||
<claude_comment_id>${context.claudeCommentId}</claude_comment_id>
|
||||
<trigger_username>${context.triggerUsername ?? "Unknown"}</trigger_username>
|
||||
<trigger_display_name>${githubData.triggerDisplayName ?? context.triggerUsername ?? "Unknown"}</trigger_display_name>
|
||||
<trigger_display_name>${githubData?.triggerDisplayName ?? context.triggerUsername ?? "Unknown"}</trigger_display_name>
|
||||
<trigger_phrase>${context.triggerPhrase}</trigger_phrase>
|
||||
${
|
||||
(eventData.eventName === "issue_comment" ||
|
||||
@@ -797,7 +906,7 @@ f. If you are unable to complete certain steps, such as running a linter or test
|
||||
export async function createPrompt(
|
||||
mode: Mode,
|
||||
modeContext: ModeContext,
|
||||
githubData: FetchDataResult,
|
||||
githubData: FetchDataResult | null,
|
||||
context: ParsedGitHubContext,
|
||||
) {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user