mirror of
https://github.com/anthropics/claude-code-action.git
synced 2026-01-23 06:54:13 +08:00
Add label to template variables
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}}. Default: '{{prefix}}{{entityType}}-{{entityNumber}}-{{timestamp}}'"
|
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}}'"
|
||||||
required: false
|
required: false
|
||||||
default: ""
|
default: ""
|
||||||
allowed_bots:
|
allowed_bots:
|
||||||
|
|||||||
@@ -16,6 +16,11 @@ export const PR_QUERY = `
|
|||||||
additions
|
additions
|
||||||
deletions
|
deletions
|
||||||
state
|
state
|
||||||
|
labels(first: 10) {
|
||||||
|
nodes {
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
commits(first: 100) {
|
commits(first: 100) {
|
||||||
totalCount
|
totalCount
|
||||||
nodes {
|
nodes {
|
||||||
@@ -97,6 +102,11 @@ export const ISSUE_QUERY = `
|
|||||||
}
|
}
|
||||||
createdAt
|
createdAt
|
||||||
state
|
state
|
||||||
|
labels(first: 10) {
|
||||||
|
nodes {
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
comments(first: 100) {
|
comments(first: 100) {
|
||||||
nodes {
|
nodes {
|
||||||
id
|
id
|
||||||
|
|||||||
@@ -14,6 +14,14 @@ import type { Octokits } from "../api/client";
|
|||||||
import type { FetchDataResult } from "../data/fetcher";
|
import type { FetchDataResult } from "../data/fetcher";
|
||||||
import { generateBranchName } from "../../utils/branch-template";
|
import { generateBranchName } from "../../utils/branch-template";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts the first label from GitHub data, or returns undefined if no labels exist
|
||||||
|
*/
|
||||||
|
function extractFirstLabel(githubData: FetchDataResult): string | undefined {
|
||||||
|
const labels = githubData.contextData.labels?.nodes;
|
||||||
|
return labels && labels.length > 0 ? labels[0]?.name : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
export type BranchInfo = {
|
export type BranchInfo = {
|
||||||
baseBranch: string;
|
baseBranch: string;
|
||||||
claudeBranch?: string;
|
claudeBranch?: string;
|
||||||
@@ -102,6 +110,9 @@ export async function setupBranch(
|
|||||||
sourceSHA = sourceBranchRef.data.object.sha;
|
sourceSHA = sourceBranchRef.data.object.sha;
|
||||||
console.log(`Source branch SHA: ${sourceSHA}`);
|
console.log(`Source branch SHA: ${sourceSHA}`);
|
||||||
|
|
||||||
|
// Extract first label from GitHub data
|
||||||
|
const firstLabel = extractFirstLabel(githubData);
|
||||||
|
|
||||||
// Generate branch name using template or default format
|
// Generate branch name using template or default format
|
||||||
const newBranch = generateBranchName(
|
const newBranch = generateBranchName(
|
||||||
branchNameTemplate,
|
branchNameTemplate,
|
||||||
@@ -109,6 +120,7 @@ export async function setupBranch(
|
|||||||
entityType,
|
entityType,
|
||||||
entityNumber,
|
entityNumber,
|
||||||
sourceSHA,
|
sourceSHA,
|
||||||
|
firstLabel,
|
||||||
);
|
);
|
||||||
|
|
||||||
// For commit signing, defer branch creation to the file ops server
|
// For commit signing, defer branch creation to the file ops server
|
||||||
|
|||||||
@@ -61,6 +61,11 @@ export type GitHubPullRequest = {
|
|||||||
additions: number;
|
additions: number;
|
||||||
deletions: number;
|
deletions: number;
|
||||||
state: string;
|
state: string;
|
||||||
|
labels: {
|
||||||
|
nodes: Array<{
|
||||||
|
name: string;
|
||||||
|
}>;
|
||||||
|
};
|
||||||
commits: {
|
commits: {
|
||||||
totalCount: number;
|
totalCount: number;
|
||||||
nodes: Array<{
|
nodes: Array<{
|
||||||
@@ -84,6 +89,11 @@ export type GitHubIssue = {
|
|||||||
author: GitHubAuthor;
|
author: GitHubAuthor;
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
state: string;
|
state: string;
|
||||||
|
labels: {
|
||||||
|
nodes: Array<{
|
||||||
|
name: string;
|
||||||
|
}>;
|
||||||
|
};
|
||||||
comments: {
|
comments: {
|
||||||
nodes: GitHubComment[];
|
nodes: GitHubComment[];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ export interface BranchTemplateVariables {
|
|||||||
hour: string;
|
hour: string;
|
||||||
minute: string;
|
minute: string;
|
||||||
sha?: string;
|
sha?: string;
|
||||||
|
label?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -46,6 +47,7 @@ export function createBranchTemplateVariables(
|
|||||||
entityType: string,
|
entityType: string,
|
||||||
entityNumber: number,
|
entityNumber: number,
|
||||||
sha?: string,
|
sha?: string,
|
||||||
|
label?: string,
|
||||||
): BranchTemplateVariables {
|
): BranchTemplateVariables {
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
|
|
||||||
@@ -60,6 +62,7 @@ export function createBranchTemplateVariables(
|
|||||||
hour: String(now.getHours()).padStart(2, "0"),
|
hour: String(now.getHours()).padStart(2, "0"),
|
||||||
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
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,12 +75,14 @@ export function generateBranchName(
|
|||||||
entityType: string,
|
entityType: string,
|
||||||
entityNumber: number,
|
entityNumber: number,
|
||||||
sha?: string,
|
sha?: string,
|
||||||
|
label?: string,
|
||||||
): string {
|
): string {
|
||||||
const variables = createBranchTemplateVariables(
|
const variables = createBranchTemplateVariables(
|
||||||
branchPrefix,
|
branchPrefix,
|
||||||
entityType,
|
entityType,
|
||||||
entityNumber,
|
entityNumber,
|
||||||
sha,
|
sha,
|
||||||
|
label,
|
||||||
);
|
);
|
||||||
|
|
||||||
let branchName: string;
|
let branchName: string;
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ describe("branch template utilities", () => {
|
|||||||
expect(result.entityType).toBe("issue");
|
expect(result.entityType).toBe("issue");
|
||||||
expect(result.entityNumber).toBe(123);
|
expect(result.entityNumber).toBe(123);
|
||||||
expect(result.sha).toBe("abcdef12");
|
expect(result.sha).toBe("abcdef12");
|
||||||
|
expect(result.label).toBe("issue"); // fallback to entityType
|
||||||
expect(result.timestamp).toMatch(/^\d{8}-\d{4}$/);
|
expect(result.timestamp).toMatch(/^\d{8}-\d{4}$/);
|
||||||
expect(result.year).toMatch(/^\d{4}$/);
|
expect(result.year).toMatch(/^\d{4}$/);
|
||||||
expect(result.month).toMatch(/^\d{2}$/);
|
expect(result.month).toMatch(/^\d{2}$/);
|
||||||
@@ -103,6 +104,33 @@ describe("branch template utilities", () => {
|
|||||||
const result = createBranchTemplateVariables("test/", "pr", 456);
|
const result = createBranchTemplateVariables("test/", "pr", 456);
|
||||||
expect(result.sha).toBeUndefined();
|
expect(result.sha).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should use provided label when available", () => {
|
||||||
|
const result = createBranchTemplateVariables(
|
||||||
|
"test/",
|
||||||
|
"issue",
|
||||||
|
123,
|
||||||
|
undefined,
|
||||||
|
"bug",
|
||||||
|
);
|
||||||
|
expect(result.label).toBe("bug");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should fallback to entityType when label is not provided", () => {
|
||||||
|
const result = createBranchTemplateVariables("test/", "pr", 456);
|
||||||
|
expect(result.label).toBe("pr");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should fallback to entityType when label is empty string", () => {
|
||||||
|
const result = createBranchTemplateVariables(
|
||||||
|
"test/",
|
||||||
|
"issue",
|
||||||
|
789,
|
||||||
|
undefined,
|
||||||
|
"",
|
||||||
|
);
|
||||||
|
expect(result.label).toBe("issue");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("generateBranchName", () => {
|
describe("generateBranchName", () => {
|
||||||
@@ -153,5 +181,40 @@ describe("branch template utilities", () => {
|
|||||||
|
|
||||||
expect(result).toBe("fix/pr-789-abcdef12");
|
expect(result).toBe("fix/pr-789-abcdef12");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should use label in template when provided", () => {
|
||||||
|
const template = "{{prefix}}{{label}}/{{entityNumber}}";
|
||||||
|
const result = generateBranchName(
|
||||||
|
template,
|
||||||
|
"feature/",
|
||||||
|
"issue",
|
||||||
|
123,
|
||||||
|
undefined,
|
||||||
|
"bug",
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result).toBe("feature/bug/123");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should fallback to entityType when label template is used but no label provided", () => {
|
||||||
|
const template = "{{prefix}}{{label}}-{{entityNumber}}";
|
||||||
|
const result = generateBranchName(template, "fix/", "pr", 456);
|
||||||
|
|
||||||
|
expect(result).toBe("fix/pr-456");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle template with both label and entityType", () => {
|
||||||
|
const template = "{{prefix}}{{label}}-{{entityType}}_{{entityNumber}}";
|
||||||
|
const result = generateBranchName(
|
||||||
|
template,
|
||||||
|
"dev/",
|
||||||
|
"issue",
|
||||||
|
789,
|
||||||
|
undefined,
|
||||||
|
"enhancement",
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result).toBe("dev/enhancement-issue_789");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ describe("generatePrompt", () => {
|
|||||||
body: "This is a test PR",
|
body: "This is a test PR",
|
||||||
author: { login: "testuser" },
|
author: { login: "testuser" },
|
||||||
state: "OPEN",
|
state: "OPEN",
|
||||||
|
labels: { nodes: [] },
|
||||||
createdAt: "2023-01-01T00:00:00Z",
|
createdAt: "2023-01-01T00:00:00Z",
|
||||||
additions: 15,
|
additions: 15,
|
||||||
deletions: 5,
|
deletions: 5,
|
||||||
@@ -475,6 +476,7 @@ describe("generatePrompt", () => {
|
|||||||
body: "The login form is not working",
|
body: "The login form is not working",
|
||||||
author: { login: "testuser" },
|
author: { login: "testuser" },
|
||||||
state: "OPEN",
|
state: "OPEN",
|
||||||
|
labels: { nodes: [] },
|
||||||
createdAt: "2023-01-01T00:00:00Z",
|
createdAt: "2023-01-01T00:00:00Z",
|
||||||
comments: {
|
comments: {
|
||||||
nodes: [],
|
nodes: [],
|
||||||
|
|||||||
@@ -28,6 +28,9 @@ describe("formatContext", () => {
|
|||||||
additions: 50,
|
additions: 50,
|
||||||
deletions: 30,
|
deletions: 30,
|
||||||
state: "OPEN",
|
state: "OPEN",
|
||||||
|
labels: {
|
||||||
|
nodes: [],
|
||||||
|
},
|
||||||
commits: {
|
commits: {
|
||||||
totalCount: 3,
|
totalCount: 3,
|
||||||
nodes: [],
|
nodes: [],
|
||||||
@@ -63,6 +66,9 @@ Changed Files: 2 files`,
|
|||||||
author: { login: "test-user" },
|
author: { login: "test-user" },
|
||||||
createdAt: "2023-01-01T00:00:00Z",
|
createdAt: "2023-01-01T00:00:00Z",
|
||||||
state: "OPEN",
|
state: "OPEN",
|
||||||
|
labels: {
|
||||||
|
nodes: [],
|
||||||
|
},
|
||||||
comments: {
|
comments: {
|
||||||
nodes: [],
|
nodes: [],
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user