mirror of
https://github.com/anthropics/claude-code-action.git
synced 2026-01-22 22:44:13 +08:00
ensure tag mode can't work with workflow dispatch and schedule tasks
This commit is contained in:
@@ -449,12 +449,11 @@ export function getEventTypeAndContext(envVars: PreparedContext): {
|
||||
|
||||
function getCommitInstructions(
|
||||
eventData: EventData,
|
||||
githubData: FetchDataResult | null,
|
||||
githubData: FetchDataResult,
|
||||
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>`
|
||||
: "";
|
||||
@@ -509,26 +508,8 @@ function getCommitInstructions(
|
||||
function substitutePromptVariables(
|
||||
template: string,
|
||||
context: PreparedContext,
|
||||
githubData: FetchDataResult | null,
|
||||
githubData: FetchDataResult,
|
||||
): 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;
|
||||
|
||||
@@ -589,7 +570,7 @@ function substitutePromptVariables(
|
||||
|
||||
export function generatePrompt(
|
||||
context: PreparedContext,
|
||||
githubData: FetchDataResult | null,
|
||||
githubData: FetchDataResult,
|
||||
useCommitSigning: boolean,
|
||||
): string {
|
||||
if (context.overridePrompt) {
|
||||
@@ -601,58 +582,6 @@ 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,
|
||||
@@ -663,7 +592,7 @@ ${context.customInstructions || ""}`;
|
||||
|
||||
const { eventType, triggerContext } = getEventTypeAndContext(context);
|
||||
|
||||
const formattedContext = formatContext(contextData, eventData.isPR ?? false);
|
||||
const formattedContext = formatContext(contextData, eventData.isPR!);
|
||||
const formattedComments = formatComments(comments, imageUrlMap);
|
||||
const formattedReviewComments = eventData.isPR
|
||||
? formatReviewComments(reviewData, imageUrlMap)
|
||||
@@ -709,7 +638,7 @@ ${eventData.isPR ? formattedChangedFiles || "No files changed" : ""}
|
||||
</changed_files>${imagesInfo}
|
||||
|
||||
<event_type>${eventType}</event_type>
|
||||
<is_pr>${(eventData.isPR ?? false) ? "true" : "false"}</is_pr>
|
||||
<is_pr>${eventData.isPR ? "true" : "false"}</is_pr>
|
||||
<trigger_context>${triggerContext}</trigger_context>
|
||||
<repository>${context.repository}</repository>
|
||||
${getEntityNumberXml(eventData)}
|
||||
@@ -906,7 +835,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 | null,
|
||||
githubData: FetchDataResult,
|
||||
context: ParsedGitHubContext,
|
||||
) {
|
||||
try {
|
||||
|
||||
@@ -53,6 +53,17 @@ export const tagMode: Mode = {
|
||||
}: ModeOptions): Promise<ModeResult> {
|
||||
// Tag mode handles entity-based events (issues, PRs, comments)
|
||||
|
||||
// Validate this mode can handle the event
|
||||
if (
|
||||
context.eventName === "workflow_dispatch" ||
|
||||
context.eventName === "schedule"
|
||||
) {
|
||||
throw new Error(
|
||||
`Tag mode cannot handle ${context.eventName} events. ` +
|
||||
`Use 'agent' mode for automation events.`,
|
||||
);
|
||||
}
|
||||
|
||||
// Check if actor is human
|
||||
await checkHumanActor(octokit.rest, context);
|
||||
|
||||
|
||||
@@ -713,78 +713,6 @@ describe("generatePrompt", () => {
|
||||
);
|
||||
});
|
||||
|
||||
test("should generate prompt for workflow_dispatch event with null githubData", () => {
|
||||
const envVars: PreparedContext = {
|
||||
repository: "owner/repo",
|
||||
triggerPhrase: "@claude",
|
||||
eventData: {
|
||||
eventName: "workflow_dispatch",
|
||||
isPR: false,
|
||||
baseBranch: "main",
|
||||
},
|
||||
};
|
||||
|
||||
const prompt = generatePrompt(envVars, null, false);
|
||||
|
||||
expect(prompt).toContain("<event_type>WORKFLOW_DISPATCH</event_type>");
|
||||
expect(prompt).toContain("<is_pr>false</is_pr>");
|
||||
expect(prompt).toContain(
|
||||
"<trigger_context>workflow dispatch event</trigger_context>",
|
||||
);
|
||||
expect(prompt).toContain(
|
||||
"You are running in an automated context without a specific issue or PR",
|
||||
);
|
||||
expect(prompt).not.toContain("<pr_number>");
|
||||
expect(prompt).not.toContain("<issue_number>");
|
||||
});
|
||||
|
||||
test("should generate prompt for schedule event with null githubData", () => {
|
||||
const envVars: PreparedContext = {
|
||||
repository: "owner/repo",
|
||||
triggerPhrase: "@claude",
|
||||
triggerUsername: "github-actions[bot]",
|
||||
eventData: {
|
||||
eventName: "schedule",
|
||||
isPR: false,
|
||||
baseBranch: "main",
|
||||
},
|
||||
};
|
||||
|
||||
const prompt = generatePrompt(envVars, null, false);
|
||||
|
||||
expect(prompt).toContain("<event_type>SCHEDULE</event_type>");
|
||||
expect(prompt).toContain("<is_pr>false</is_pr>");
|
||||
expect(prompt).toContain(
|
||||
"<trigger_context>scheduled automation event</trigger_context>",
|
||||
);
|
||||
expect(prompt).toContain("scheduled automation");
|
||||
expect(prompt).toContain(
|
||||
"<trigger_username>github-actions[bot]</trigger_username>",
|
||||
);
|
||||
});
|
||||
|
||||
test("should include direct prompt for automation events", () => {
|
||||
const envVars: PreparedContext = {
|
||||
repository: "owner/repo",
|
||||
triggerPhrase: "@claude",
|
||||
directPrompt: "Run daily maintenance tasks",
|
||||
eventData: {
|
||||
eventName: "workflow_dispatch",
|
||||
isPR: false,
|
||||
baseBranch: "main",
|
||||
},
|
||||
};
|
||||
|
||||
const prompt = generatePrompt(envVars, null, false);
|
||||
|
||||
expect(prompt).toContain("<direct_prompt>");
|
||||
expect(prompt).toContain("Run daily maintenance tasks");
|
||||
expect(prompt).toContain("</direct_prompt>");
|
||||
expect(prompt).toContain(
|
||||
"IMPORTANT: The following are direct instructions from the automation workflow",
|
||||
);
|
||||
});
|
||||
|
||||
test("should handle pull_request event on closed PR with new branch", () => {
|
||||
const envVars: PreparedContext = {
|
||||
repository: "owner/repo",
|
||||
|
||||
Reference in New Issue
Block a user