-
Notifications
You must be signed in to change notification settings - Fork 1.4k
feat: custom branch name templates #571
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
726d580
Add branch-name-template config option
dylancdavis 4991c0c
Logging
dylancdavis b5de2b9
Use branch name template
dylancdavis 9c4bc5d
Add label to template variables
dylancdavis 40c2c1e
Add description template variable
dylancdavis 32e7aee
More concise description for branch_name_template
dylancdavis 6246ecd
Remove more granular time template variables
dylancdavis e758a32
Only fetch first label
dylancdavis 1a49e00
Add check for empty template-generated name
dylancdavis 35c0ca2
Clean up comments, docstrings
dylancdavis ddb3ef0
Merge createBranchTemplateVariables into generateBranchName
dylancdavis 60112e2
Still replace undefined values
dylancdavis b129570
Fall back to default on duplicate branch
dylancdavis 02a1a97
Merge branch 'main' into branch-template
dylancdavis 5b9f718
Parameterize description wordcount
dylancdavis e697aff
Remove some over-explanatory comments
dylancdavis 8c3697b
NUM_DESCRIPTION_WORDS: 3 -> 5
dylancdavis File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,96 @@ | ||
| #!/usr/bin/env bun | ||
|
|
||
| /** | ||
| * Branch name template parsing and variable substitution utilities | ||
| */ | ||
|
|
||
| const NUM_DESCRIPTION_WORDS = 5; | ||
|
|
||
| /** | ||
| * Extracts the first `numWords` words from a title and converts them to kebab-case | ||
| */ | ||
| function extractDescription(title: string, numWords: number = NUM_DESCRIPTION_WORDS): string { | ||
| if (!title || title.trim() === "") { | ||
| return ""; | ||
| } | ||
|
|
||
| return title | ||
| .trim() | ||
| .split(/\s+/) | ||
| .slice(0, numWords) // Only first `numWords` words | ||
| .join("-") | ||
| .toLowerCase() | ||
| .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 { | ||
| prefix: string; | ||
| entityType: string; | ||
| entityNumber: number; | ||
| timestamp: string; | ||
| sha?: string; | ||
| label?: string; | ||
| description?: string; | ||
| } | ||
|
|
||
| /** | ||
| * Replaces template variables in a branch name template | ||
| * Template format: {{variableName}} | ||
| */ | ||
| export function applyBranchTemplate( | ||
| template: string, | ||
| variables: BranchTemplateVariables, | ||
| ): string { | ||
| let result = template; | ||
|
|
||
| // Replace each variable | ||
| Object.entries(variables).forEach(([key, value]) => { | ||
| const placeholder = `{{${key}}}`; | ||
| const replacement = value ? String(value) : ""; | ||
| result = result.replaceAll(placeholder, replacement); | ||
| }); | ||
|
|
||
| return result; | ||
| } | ||
|
|
||
| /** | ||
| * Generates a branch name from the provided `template` and set of `variables`. Uses a default format if the template is empty or produces an empty result. | ||
| */ | ||
| export function generateBranchName( | ||
| template: string | undefined, | ||
| branchPrefix: string, | ||
| entityType: string, | ||
| entityNumber: number, | ||
| sha?: string, | ||
| label?: string, | ||
| title?: string, | ||
| ): string { | ||
| const now = new Date(); | ||
|
|
||
| const variables: BranchTemplateVariables = { | ||
| prefix: branchPrefix, | ||
| entityType, | ||
| entityNumber, | ||
| timestamp: `${now.getFullYear()}${String(now.getMonth() + 1).padStart(2, "0")}${String(now.getDate()).padStart(2, "0")}-${String(now.getHours()).padStart(2, "0")}${String(now.getMinutes()).padStart(2, "0")}`, | ||
| sha: sha?.substring(0, 8), // First 8 characters of SHA | ||
| label: label || entityType, // Fall back to entityType if no label | ||
| description: title ? extractDescription(title) : undefined, | ||
| }; | ||
|
|
||
| if (template?.trim()) { | ||
| const branchName = applyBranchTemplate(template, variables); | ||
|
|
||
| // Some templates could produce empty results- validate | ||
| if (branchName.trim().length > 0) return branchName; | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We don't enforce Kubernetes compatibility for the template case- I figured users that needed it could make their template compatible, and that this way we allow users to specify underscores or uppercase characters in their template if desired. |
||
|
|
||
| console.log( | ||
| `Branch template '${template}' generated empty result, falling back to default format`, | ||
| ); | ||
| } | ||
|
|
||
| const branchName = `${branchPrefix}${entityType}-${entityNumber}-${variables.timestamp}`; | ||
| // Kubernetes compatible: lowercase, max 50 chars, alphanumeric and hyphens only | ||
| return branchName.toLowerCase().substring(0, 50); | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would appreciate some feedback on this- a bare catch block feels like the wrong way to do this.