mirror of
https://github.com/anthropics/claude-code-action.git
synced 2026-01-22 22:44:13 +08:00
Add description template variable
This commit is contained in:
@@ -24,7 +24,7 @@ inputs:
|
|||||||
required: false
|
required: false
|
||||||
default: "claude/"
|
default: "claude/"
|
||||||
branch_name_template:
|
branch_name_template:
|
||||||
description: "Template for branch naming. Available variables: {{prefix}}, {{entityType}}, {{entityNumber}}, {{timestamp}}, {{year}}, {{month}}, {{day}}, {{hour}}, {{minute}}, {{sha}}, {{label}}. The {{label}} variable uses the first label from the issue/PR, falling back to {{entityType}} if no labels exist. Default: '{{prefix}}{{entityType}}-{{entityNumber}}-{{timestamp}}'"
|
description: "Template for branch naming. Available variables: {{prefix}}, {{entityType}}, {{entityNumber}}, {{timestamp}}, {{year}}, {{month}}, {{day}}, {{hour}}, {{minute}}, {{sha}}, {{label}}, {{description}}. The {{label}} variable uses the first label from the issue/PR, falling back to {{entityType}} if no labels exist. The {{description}} variable uses the first 3 words of the issue/PR title converted to kebab-case. Default: '{{prefix}}{{entityType}}-{{entityNumber}}-{{timestamp}}'"
|
||||||
required: false
|
required: false
|
||||||
default: ""
|
default: ""
|
||||||
allowed_bots:
|
allowed_bots:
|
||||||
|
|||||||
@@ -113,6 +113,9 @@ export async function setupBranch(
|
|||||||
// Extract first label from GitHub data
|
// Extract first label from GitHub data
|
||||||
const firstLabel = extractFirstLabel(githubData);
|
const firstLabel = extractFirstLabel(githubData);
|
||||||
|
|
||||||
|
// Extract title from GitHub data
|
||||||
|
const title = githubData.contextData.title;
|
||||||
|
|
||||||
// Generate branch name using template or default format
|
// Generate branch name using template or default format
|
||||||
const newBranch = generateBranchName(
|
const newBranch = generateBranchName(
|
||||||
branchNameTemplate,
|
branchNameTemplate,
|
||||||
@@ -121,6 +124,7 @@ export async function setupBranch(
|
|||||||
entityNumber,
|
entityNumber,
|
||||||
sourceSHA,
|
sourceSHA,
|
||||||
firstLabel,
|
firstLabel,
|
||||||
|
title,
|
||||||
);
|
);
|
||||||
|
|
||||||
// For commit signing, defer branch creation to the file ops server
|
// For commit signing, defer branch creation to the file ops server
|
||||||
|
|||||||
@@ -4,6 +4,25 @@
|
|||||||
* Branch name template parsing and variable substitution utilities
|
* Branch name template parsing and variable substitution utilities
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts the first three words from a title and converts them to kebab-case
|
||||||
|
*/
|
||||||
|
function extractDescription(title: string): string {
|
||||||
|
if (!title || title.trim() === "") {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return title
|
||||||
|
.trim() // Remove leading/trailing whitespace
|
||||||
|
.split(/\s+/) // Split on whitespace
|
||||||
|
.slice(0, 3) // Take first 3 words
|
||||||
|
.join("-") // Join with hyphens
|
||||||
|
.toLowerCase() // Convert to lowercase
|
||||||
|
.replace(/[^a-z0-9-]/g, "") // Remove non-alphanumeric except hyphens
|
||||||
|
.replace(/-+/g, "-") // Replace multiple hyphens with single
|
||||||
|
.replace(/^-|-$/g, ""); // Remove leading/trailing hyphens
|
||||||
|
}
|
||||||
|
|
||||||
export interface BranchTemplateVariables {
|
export interface BranchTemplateVariables {
|
||||||
prefix: string;
|
prefix: string;
|
||||||
entityType: string;
|
entityType: string;
|
||||||
@@ -16,6 +35,7 @@ export interface BranchTemplateVariables {
|
|||||||
minute: string;
|
minute: string;
|
||||||
sha?: string;
|
sha?: string;
|
||||||
label?: string;
|
label?: string;
|
||||||
|
description?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -48,6 +68,7 @@ export function createBranchTemplateVariables(
|
|||||||
entityNumber: number,
|
entityNumber: number,
|
||||||
sha?: string,
|
sha?: string,
|
||||||
label?: string,
|
label?: string,
|
||||||
|
title?: string,
|
||||||
): BranchTemplateVariables {
|
): BranchTemplateVariables {
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
|
|
||||||
@@ -63,6 +84,7 @@ export function createBranchTemplateVariables(
|
|||||||
minute: String(now.getMinutes()).padStart(2, "0"),
|
minute: String(now.getMinutes()).padStart(2, "0"),
|
||||||
sha: sha?.substring(0, 8), // First 8 characters of SHA
|
sha: sha?.substring(0, 8), // First 8 characters of SHA
|
||||||
label: label || entityType, // Fall back to entityType if no label
|
label: label || entityType, // Fall back to entityType if no label
|
||||||
|
description: title !== undefined ? extractDescription(title) : undefined,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,6 +98,7 @@ export function generateBranchName(
|
|||||||
entityNumber: number,
|
entityNumber: number,
|
||||||
sha?: string,
|
sha?: string,
|
||||||
label?: string,
|
label?: string,
|
||||||
|
title?: string,
|
||||||
): string {
|
): string {
|
||||||
const variables = createBranchTemplateVariables(
|
const variables = createBranchTemplateVariables(
|
||||||
branchPrefix,
|
branchPrefix,
|
||||||
@@ -83,6 +106,7 @@ export function generateBranchName(
|
|||||||
entityNumber,
|
entityNumber,
|
||||||
sha,
|
sha,
|
||||||
label,
|
label,
|
||||||
|
title,
|
||||||
);
|
);
|
||||||
|
|
||||||
let branchName: string;
|
let branchName: string;
|
||||||
|
|||||||
@@ -131,6 +131,83 @@ describe("branch template utilities", () => {
|
|||||||
);
|
);
|
||||||
expect(result.label).toBe("issue");
|
expect(result.label).toBe("issue");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should extract description from title when provided", () => {
|
||||||
|
const result = createBranchTemplateVariables(
|
||||||
|
"test/",
|
||||||
|
"issue",
|
||||||
|
123,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
"Fix login bug with OAuth",
|
||||||
|
);
|
||||||
|
expect(result.description).toBe("fix-login-bug");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle title with special characters", () => {
|
||||||
|
const result = createBranchTemplateVariables(
|
||||||
|
"test/",
|
||||||
|
"issue",
|
||||||
|
456,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
"Add: User Registration & Email Validation",
|
||||||
|
);
|
||||||
|
expect(result.description).toBe("add-user-registration");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle title with fewer than 3 words", () => {
|
||||||
|
const result = createBranchTemplateVariables(
|
||||||
|
"test/",
|
||||||
|
"issue",
|
||||||
|
789,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
"Bug fix",
|
||||||
|
);
|
||||||
|
expect(result.description).toBe("bug-fix");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle single word title", () => {
|
||||||
|
const result = createBranchTemplateVariables(
|
||||||
|
"test/",
|
||||||
|
"issue",
|
||||||
|
101,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
"Refactoring",
|
||||||
|
);
|
||||||
|
expect(result.description).toBe("refactoring");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle empty title", () => {
|
||||||
|
const result = createBranchTemplateVariables(
|
||||||
|
"test/",
|
||||||
|
"issue",
|
||||||
|
202,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
"",
|
||||||
|
);
|
||||||
|
expect(result.description).toBe("");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle title with extra whitespace", () => {
|
||||||
|
const result = createBranchTemplateVariables(
|
||||||
|
"test/",
|
||||||
|
"issue",
|
||||||
|
303,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
" Update README documentation ",
|
||||||
|
);
|
||||||
|
expect(result.description).toBe("update-readme-documentation");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not set description when title is not provided", () => {
|
||||||
|
const result = createBranchTemplateVariables("test/", "issue", 404);
|
||||||
|
expect(result.description).toBeUndefined();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("generateBranchName", () => {
|
describe("generateBranchName", () => {
|
||||||
@@ -216,5 +293,66 @@ describe("branch template utilities", () => {
|
|||||||
|
|
||||||
expect(result).toBe("dev/enhancement-issue_789");
|
expect(result).toBe("dev/enhancement-issue_789");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should use description in template when provided", () => {
|
||||||
|
const template = "{{prefix}}{{description}}/{{entityNumber}}";
|
||||||
|
const result = generateBranchName(
|
||||||
|
template,
|
||||||
|
"feature/",
|
||||||
|
"issue",
|
||||||
|
123,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
"Fix login bug with OAuth",
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result).toBe("feature/fix-login-bug/123");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle template with multiple variables including description", () => {
|
||||||
|
const template =
|
||||||
|
"{{prefix}}{{label}}/{{description}}-{{entityType}}_{{entityNumber}}";
|
||||||
|
const result = generateBranchName(
|
||||||
|
template,
|
||||||
|
"dev/",
|
||||||
|
"issue",
|
||||||
|
456,
|
||||||
|
undefined,
|
||||||
|
"bug",
|
||||||
|
"User authentication fails completely",
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result).toBe("dev/bug/user-authentication-fails-issue_456");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle description with special characters in template", () => {
|
||||||
|
const template = "{{prefix}}{{description}}-{{entityNumber}}";
|
||||||
|
const result = generateBranchName(
|
||||||
|
template,
|
||||||
|
"fix/",
|
||||||
|
"pr",
|
||||||
|
789,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
"Add: User Registration & Email Validation",
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result).toBe("fix/add-user-registration-789");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle empty description in template", () => {
|
||||||
|
const template = "{{prefix}}{{description}}-{{entityNumber}}";
|
||||||
|
const result = generateBranchName(
|
||||||
|
template,
|
||||||
|
"test/",
|
||||||
|
"issue",
|
||||||
|
101,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
"",
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result).toBe("test/-101");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user