mirror of
https://github.com/anthropics/claude-code-action.git
synced 2026-01-23 15:04:13 +08:00
refactor: improve discriminated union implementation based on review feedback
- Use eventName checks instead of 'in' operator for more robust type guards - Remove unnecessary type assertions - TypeScript's control flow analysis works correctly - Remove redundant runtime checks for entityNumber and isPR - Simplify code by using context directly after type guard Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -10,7 +10,6 @@ import {
|
|||||||
parseGitHubContext,
|
parseGitHubContext,
|
||||||
isPullRequestReviewCommentEvent,
|
isPullRequestReviewCommentEvent,
|
||||||
isEntityContext,
|
isEntityContext,
|
||||||
type ParsedGitHubContext,
|
|
||||||
} from "../github/context";
|
} from "../github/context";
|
||||||
import { GITHUB_SERVER_URL } from "../github/api/config";
|
import { GITHUB_SERVER_URL } from "../github/api/config";
|
||||||
import { checkAndCommitOrDeleteBranch } from "../github/operations/branch-cleanup";
|
import { checkAndCommitOrDeleteBranch } from "../github/operations/branch-cleanup";
|
||||||
@@ -31,9 +30,7 @@ async function run() {
|
|||||||
throw new Error("update-comment-link requires an entity context");
|
throw new Error("update-comment-link requires an entity context");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TypeScript needs a type assertion here due to control flow limitations
|
const { owner, repo } = context.repository;
|
||||||
const entityContext = context as ParsedGitHubContext;
|
|
||||||
const { owner, repo } = entityContext.repository;
|
|
||||||
|
|
||||||
const octokit = createOctokit(githubToken);
|
const octokit = createOctokit(githubToken);
|
||||||
|
|
||||||
@@ -46,7 +43,7 @@ async function run() {
|
|||||||
try {
|
try {
|
||||||
// GitHub has separate ID namespaces for review comments and issue comments
|
// GitHub has separate ID namespaces for review comments and issue comments
|
||||||
// We need to use the correct API based on the event type
|
// We need to use the correct API based on the event type
|
||||||
if (isPullRequestReviewCommentEvent(entityContext)) {
|
if (isPullRequestReviewCommentEvent(context)) {
|
||||||
// For PR review comments, use the pulls API
|
// For PR review comments, use the pulls API
|
||||||
console.log(`Fetching PR review comment ${commentId}`);
|
console.log(`Fetching PR review comment ${commentId}`);
|
||||||
const { data: prComment } = await octokit.rest.pulls.getReviewComment({
|
const { data: prComment } = await octokit.rest.pulls.getReviewComment({
|
||||||
@@ -75,16 +72,16 @@ async function run() {
|
|||||||
// If all attempts fail, try to determine more information about the comment
|
// If all attempts fail, try to determine more information about the comment
|
||||||
console.error("Failed to fetch comment. Debug info:");
|
console.error("Failed to fetch comment. Debug info:");
|
||||||
console.error(`Comment ID: ${commentId}`);
|
console.error(`Comment ID: ${commentId}`);
|
||||||
console.error(`Event name: ${entityContext.eventName}`);
|
console.error(`Event name: ${context.eventName}`);
|
||||||
console.error(`Entity number: ${entityContext.entityNumber}`);
|
console.error(`Entity number: ${context.entityNumber}`);
|
||||||
console.error(`Repository: ${entityContext.repository.full_name}`);
|
console.error(`Repository: ${context.repository.full_name}`);
|
||||||
|
|
||||||
// Try to get the PR info to understand the comment structure
|
// Try to get the PR info to understand the comment structure
|
||||||
try {
|
try {
|
||||||
const { data: pr } = await octokit.rest.pulls.get({
|
const { data: pr } = await octokit.rest.pulls.get({
|
||||||
owner,
|
owner,
|
||||||
repo,
|
repo,
|
||||||
pull_number: entityContext.entityNumber,
|
pull_number: context.entityNumber,
|
||||||
});
|
});
|
||||||
console.log(`PR state: ${pr.state}`);
|
console.log(`PR state: ${pr.state}`);
|
||||||
console.log(`PR comments count: ${pr.comments}`);
|
console.log(`PR comments count: ${pr.comments}`);
|
||||||
@@ -136,12 +133,12 @@ async function run() {
|
|||||||
comparison.total_commits > 0 ||
|
comparison.total_commits > 0 ||
|
||||||
(comparison.files && comparison.files.length > 0)
|
(comparison.files && comparison.files.length > 0)
|
||||||
) {
|
) {
|
||||||
const entityType = entityContext.isPR ? "PR" : "Issue";
|
const entityType = context.isPR ? "PR" : "Issue";
|
||||||
const prTitle = encodeURIComponent(
|
const prTitle = encodeURIComponent(
|
||||||
`${entityType} #${entityContext.entityNumber}: Changes from Claude`,
|
`${entityType} #${context.entityNumber}: Changes from Claude`,
|
||||||
);
|
);
|
||||||
const prBody = encodeURIComponent(
|
const prBody = encodeURIComponent(
|
||||||
`This PR addresses ${entityType.toLowerCase()} #${entityContext.entityNumber}\n\nGenerated with [Claude Code](https://claude.ai/code)`,
|
`This PR addresses ${entityType.toLowerCase()} #${context.entityNumber}\n\nGenerated with [Claude Code](https://claude.ai/code)`,
|
||||||
);
|
);
|
||||||
const prUrl = `${serverUrl}/${owner}/${repo}/compare/${baseBranch}...${claudeBranch}?quick_pull=1&title=${prTitle}&body=${prBody}`;
|
const prUrl = `${serverUrl}/${owner}/${repo}/compare/${baseBranch}...${claudeBranch}?quick_pull=1&title=${prTitle}&body=${prBody}`;
|
||||||
prLink = `\n[Create a PR](${prUrl})`;
|
prLink = `\n[Create a PR](${prUrl})`;
|
||||||
|
|||||||
@@ -8,10 +8,7 @@ import { configureGitAuth } from "../../github/operations/git-config";
|
|||||||
import { prepareMcpConfig } from "../../mcp/install-mcp-server";
|
import { prepareMcpConfig } from "../../mcp/install-mcp-server";
|
||||||
import { fetchGitHubData } from "../../github/data/fetcher";
|
import { fetchGitHubData } from "../../github/data/fetcher";
|
||||||
import { createPrompt } from "../../create-prompt";
|
import { createPrompt } from "../../create-prompt";
|
||||||
import {
|
import { isEntityContext } from "../../github/context";
|
||||||
isEntityContext,
|
|
||||||
type ParsedGitHubContext,
|
|
||||||
} from "../../github/context";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tag mode implementation.
|
* Tag mode implementation.
|
||||||
@@ -59,37 +56,33 @@ export const tagMode: Mode = {
|
|||||||
octokit,
|
octokit,
|
||||||
githubToken,
|
githubToken,
|
||||||
}: ModeOptions): Promise<ModeResult> {
|
}: ModeOptions): Promise<ModeResult> {
|
||||||
// Tag mode handles entity-based events (issues, PRs, comments)
|
// Tag mode only handles entity-based events
|
||||||
// We know context is ParsedGitHubContext for tag mode
|
if (!isEntityContext(context)) {
|
||||||
const entityContext = context as ParsedGitHubContext;
|
throw new Error("Tag mode requires entity context");
|
||||||
|
}
|
||||||
|
|
||||||
// Check if actor is human
|
// Check if actor is human
|
||||||
await checkHumanActor(octokit.rest, entityContext);
|
await checkHumanActor(octokit.rest, context);
|
||||||
|
|
||||||
// Create initial tracking comment
|
// Create initial tracking comment
|
||||||
const commentData = await createInitialComment(octokit.rest, entityContext);
|
const commentData = await createInitialComment(octokit.rest, context);
|
||||||
const commentId = commentData.id;
|
const commentId = commentData.id;
|
||||||
|
|
||||||
// Fetch GitHub data - entity events always have entityNumber and isPR
|
|
||||||
if (!entityContext.entityNumber || entityContext.isPR === undefined) {
|
|
||||||
throw new Error("Entity events must have entityNumber and isPR defined");
|
|
||||||
}
|
|
||||||
|
|
||||||
const githubData = await fetchGitHubData({
|
const githubData = await fetchGitHubData({
|
||||||
octokits: octokit,
|
octokits: octokit,
|
||||||
repository: `${entityContext.repository.owner}/${entityContext.repository.repo}`,
|
repository: `${context.repository.owner}/${context.repository.repo}`,
|
||||||
prNumber: entityContext.entityNumber.toString(),
|
prNumber: context.entityNumber.toString(),
|
||||||
isPR: entityContext.isPR,
|
isPR: context.isPR,
|
||||||
triggerUsername: entityContext.actor,
|
triggerUsername: context.actor,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Setup branch
|
// Setup branch
|
||||||
const branchInfo = await setupBranch(octokit, githubData, entityContext);
|
const branchInfo = await setupBranch(octokit, githubData, context);
|
||||||
|
|
||||||
// Configure git authentication if not using commit signing
|
// Configure git authentication if not using commit signing
|
||||||
if (!context.inputs.useCommitSigning) {
|
if (!context.inputs.useCommitSigning) {
|
||||||
try {
|
try {
|
||||||
await configureGitAuth(githubToken, entityContext, commentData.user);
|
await configureGitAuth(githubToken, context, commentData.user);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to configure git authentication:", error);
|
console.error("Failed to configure git authentication:", error);
|
||||||
throw error;
|
throw error;
|
||||||
@@ -97,26 +90,26 @@ export const tagMode: Mode = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create prompt file
|
// Create prompt file
|
||||||
const modeContext = this.prepareContext(entityContext, {
|
const modeContext = this.prepareContext(context, {
|
||||||
commentId,
|
commentId,
|
||||||
baseBranch: branchInfo.baseBranch,
|
baseBranch: branchInfo.baseBranch,
|
||||||
claudeBranch: branchInfo.claudeBranch,
|
claudeBranch: branchInfo.claudeBranch,
|
||||||
});
|
});
|
||||||
|
|
||||||
await createPrompt(tagMode, modeContext, githubData, entityContext);
|
await createPrompt(tagMode, modeContext, githubData, context);
|
||||||
|
|
||||||
// Get MCP configuration
|
// Get MCP configuration
|
||||||
const additionalMcpConfig = process.env.MCP_CONFIG || "";
|
const additionalMcpConfig = process.env.MCP_CONFIG || "";
|
||||||
const mcpConfig = await prepareMcpConfig({
|
const mcpConfig = await prepareMcpConfig({
|
||||||
githubToken,
|
githubToken,
|
||||||
owner: entityContext.repository.owner,
|
owner: context.repository.owner,
|
||||||
repo: entityContext.repository.repo,
|
repo: context.repository.repo,
|
||||||
branch: branchInfo.claudeBranch || branchInfo.currentBranch,
|
branch: branchInfo.claudeBranch || branchInfo.currentBranch,
|
||||||
baseBranch: branchInfo.baseBranch,
|
baseBranch: branchInfo.baseBranch,
|
||||||
additionalMcpConfig,
|
additionalMcpConfig,
|
||||||
claudeCommentId: commentId.toString(),
|
claudeCommentId: commentId.toString(),
|
||||||
allowedTools: entityContext.inputs.allowedTools,
|
allowedTools: context.inputs.allowedTools,
|
||||||
context: entityContext,
|
context,
|
||||||
});
|
});
|
||||||
|
|
||||||
core.setOutput("mcp_config", mcpConfig);
|
core.setOutput("mcp_config", mcpConfig);
|
||||||
|
|||||||
Reference in New Issue
Block a user