From 13e47489f467b2deeedf92aca02795366ee7030b Mon Sep 17 00:00:00 2001 From: bogini Date: Fri, 5 Sep 2025 15:06:00 -0700 Subject: [PATCH] feat: add repository_dispatch event support (#546) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: add repository_dispatch event support Add support for repository_dispatch events in GitHub context parsing system. This enables the action to handle custom API-triggered events properly. Changes: - Add RepositoryDispatchEvent type definition - Include repository_dispatch in automation event names - Update context parsing to handle repository_dispatch events - Update documentation to reflect repository_dispatch availability 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude * style: format code with prettier 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude * test: add comprehensive repository_dispatch event test coverage - Add mockRepositoryDispatchContext with realistic payload structure - Add repository_dispatch mode detection tests in registry.test.ts - Add repository_dispatch trigger tests in agent.test.ts - Ensure repository_dispatch events are properly handled as automation events - Verify agent mode trigger behavior with and without prompts - All 394 tests passing with new coverage 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude * style: format test files with prettier 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --------- Co-authored-by: Claude --- docs/custom-automations.md | 2 +- src/github/context.ts | 30 ++++++++++++++++++++++++++++-- test/mockContext.ts | 28 ++++++++++++++++++++++++++++ test/modes/agent.test.ts | 10 +++++++++- test/modes/registry.test.ts | 34 +++++++++++++++++++++++++++++++++- 5 files changed, 99 insertions(+), 5 deletions(-) diff --git a/docs/custom-automations.md b/docs/custom-automations.md index ae5ff36..47fe9d7 100644 --- a/docs/custom-automations.md +++ b/docs/custom-automations.md @@ -21,7 +21,7 @@ This action supports the following GitHub events ([learn more GitHub event trigg - `issues` - When issues are opened or assigned - `pull_request_review` - When PR reviews are submitted - `pull_request_review_comment` - When comments are made on PR reviews -- `repository_dispatch` - Custom events triggered via API (coming soon) +- `repository_dispatch` - Custom events triggered via API - `workflow_dispatch` - Manual workflow triggers (coming soon) ## Automated Documentation Updates diff --git a/src/github/context.ts b/src/github/context.ts index 94ef4f8..de4dd08 100644 --- a/src/github/context.ts +++ b/src/github/context.ts @@ -26,6 +26,20 @@ export type WorkflowDispatchEvent = { workflow: string; }; +export type RepositoryDispatchEvent = { + action: string; + client_payload?: Record; + repository: { + name: string; + owner: { + login: string; + }; + }; + sender: { + login: string; + }; +}; + export type ScheduleEvent = { action?: never; schedule?: string; @@ -48,6 +62,7 @@ const ENTITY_EVENT_NAMES = [ const AUTOMATION_EVENT_NAMES = [ "workflow_dispatch", + "repository_dispatch", "schedule", "workflow_run", ] as const; @@ -95,10 +110,14 @@ export type ParsedGitHubContext = BaseContext & { isPR: boolean; }; -// Context for automation events (workflow_dispatch, schedule, workflow_run) +// Context for automation events (workflow_dispatch, repository_dispatch, schedule, workflow_run) export type AutomationContext = BaseContext & { eventName: AutomationEventName; - payload: WorkflowDispatchEvent | ScheduleEvent | WorkflowRunEvent; + payload: + | WorkflowDispatchEvent + | RepositoryDispatchEvent + | ScheduleEvent + | WorkflowRunEvent; }; // Union type for all contexts @@ -190,6 +209,13 @@ export function parseGitHubContext(): GitHubContext { payload: context.payload as unknown as WorkflowDispatchEvent, }; } + case "repository_dispatch": { + return { + ...commonFields, + eventName: "repository_dispatch", + payload: context.payload as unknown as RepositoryDispatchEvent, + }; + } case "schedule": { return { ...commonFields, diff --git a/test/mockContext.ts b/test/mockContext.ts index 57716da..c375f18 100644 --- a/test/mockContext.ts +++ b/test/mockContext.ts @@ -1,6 +1,7 @@ import type { ParsedGitHubContext, AutomationContext, + RepositoryDispatchEvent, } from "../src/github/context"; import type { IssuesEvent, @@ -81,6 +82,33 @@ export const createMockAutomationContext = ( return { ...baseContext, ...overrides, inputs: mergedInputs }; }; +export const mockRepositoryDispatchContext: AutomationContext = { + runId: "1234567890", + eventName: "repository_dispatch", + eventAction: undefined, + repository: defaultRepository, + actor: "automation-user", + payload: { + action: "trigger-analysis", + client_payload: { + source: "issue-detective", + issue_number: 42, + repository_name: "test-owner/test-repo", + analysis_type: "bug-report", + }, + repository: { + name: "test-repo", + owner: { + login: "test-owner", + }, + }, + sender: { + login: "automation-user", + }, + } as RepositoryDispatchEvent, + inputs: defaultInputs, +}; + export const mockIssueOpenedContext: ParsedGitHubContext = { runId: "1234567890", eventName: "issues", diff --git a/test/modes/agent.test.ts b/test/modes/agent.test.ts index 9a67e1c..9811707 100644 --- a/test/modes/agent.test.ts +++ b/test/modes/agent.test.ts @@ -76,6 +76,11 @@ describe("Agent Mode", () => { }); expect(agentMode.shouldTrigger(scheduleContext)).toBe(false); + const repositoryDispatchContext = createMockAutomationContext({ + eventName: "repository_dispatch", + }); + expect(agentMode.shouldTrigger(repositoryDispatchContext)).toBe(false); + // Should NOT trigger for entity events without prompt const entityEvents = [ "issue_comment", @@ -92,6 +97,7 @@ describe("Agent Mode", () => { // Should trigger for ANY event when prompt is provided const allEvents = [ "workflow_dispatch", + "repository_dispatch", "schedule", "issue_comment", "pull_request", @@ -101,7 +107,9 @@ describe("Agent Mode", () => { allEvents.forEach((eventName) => { const contextWithPrompt = - eventName === "workflow_dispatch" || eventName === "schedule" + eventName === "workflow_dispatch" || + eventName === "repository_dispatch" || + eventName === "schedule" ? createMockAutomationContext({ eventName, inputs: { prompt: "Do something" }, diff --git a/test/modes/registry.test.ts b/test/modes/registry.test.ts index bdeac27..7c585b2 100644 --- a/test/modes/registry.test.ts +++ b/test/modes/registry.test.ts @@ -2,7 +2,11 @@ import { describe, test, expect } from "bun:test"; import { getMode, isValidMode } from "../../src/modes/registry"; import { agentMode } from "../../src/modes/agent"; import { tagMode } from "../../src/modes/tag"; -import { createMockContext, createMockAutomationContext } from "../mockContext"; +import { + createMockContext, + createMockAutomationContext, + mockRepositoryDispatchContext, +} from "../mockContext"; describe("Mode Registry", () => { const mockContext = createMockContext({ @@ -50,6 +54,34 @@ describe("Mode Registry", () => { expect(mode.name).toBe("agent"); }); + test("getMode auto-detects agent for repository_dispatch event", () => { + const mode = getMode(mockRepositoryDispatchContext); + expect(mode).toBe(agentMode); + expect(mode.name).toBe("agent"); + }); + + test("getMode auto-detects agent for repository_dispatch with client_payload", () => { + const contextWithPayload = createMockAutomationContext({ + eventName: "repository_dispatch", + payload: { + action: "trigger-analysis", + client_payload: { + source: "external-system", + metadata: { priority: "high" }, + }, + repository: { + name: "test-repo", + owner: { login: "test-owner" }, + }, + sender: { login: "automation-user" }, + }, + }); + + const mode = getMode(contextWithPayload); + expect(mode).toBe(agentMode); + expect(mode.name).toBe("agent"); + }); + // Removed test - legacy mode names no longer supported in v1.0 test("getMode auto-detects agent mode for PR opened", () => {