Skip to content

feat: add custom commit and PR templates in server config#5091

Merged
markphelps merged 6 commits into
v2from
markphelps/custom-commit-templates
Nov 26, 2025
Merged

feat: add custom commit and PR templates in server config#5091
markphelps merged 6 commits into
v2from
markphelps/custom-commit-templates

Conversation

@markphelps

Copy link
Copy Markdown
Collaborator

Summary

Add support for configuring custom commit message and pull request templates at the server configuration level (per storage backend). This allows operators to define server-wide default templates that can be used when creating commits and pull requests through the Flipt UI.

Changes

  • Added TemplatesConfig struct to internal/config/storage.go with fields for commit messages, PR titles, and PR bodies
  • Extended StorageConfig to include a Templates field allowing per-storage backend configuration
  • Updated fs.GetConfig() to accept and apply server-level templates as defaults
  • Added serverTemplates parameter to NewEnvironmentFromRepo and passed through the call chain
  • Added comprehensive tests for server-level template functionality
  • Updated config/local.yml with example template configuration

Backward Compatibility

This change is fully backward compatible. All parameters are optional and the feature gracefully falls back to defaults.

Related

Fixes #5087

Add support for configuring commit message and pull request templates
at the server configuration level. This allows operators to define
server-wide default templates that can be used when creating commits
and pull requests through the Flipt UI.

Templates are configured per storage backend and support:
- commit_message: Template for commit messages
- proposal_title: Template for pull request titles
- proposal_body: Template for pull request body content

Template priority (highest to lowest):
1. Repository-level templates (in flipt.yaml)
2. Server-level templates (in config.yml storage section)
3. Built-in defaults

This is useful for CI/CD integration, such as adding [skip ci]
to commit messages to prevent unnecessary pipeline triggers.

Example configuration:
  storage:
    default:
      templates:
        commit_message: "{{ (index .Changes 0) }} [skip ci]"

Fixes #5087

Signed-off-by: Mark Phelps <[email protected]>
@markphelps markphelps added the v2 Flipt v2 label Nov 25, 2025
Add TemplatesConfig.Validate() method to check that all configured
templates are valid Go text/templates at config load time. This
provides clear error messages at startup rather than silently
falling back to defaults when a template has a syntax error.

- Added Validate() method to TemplatesConfig in internal/config/storage.go
- Call validation from StorageConfig.validate() during config load
- Added comprehensive tests for template validation
- Updated documentation in DefaultFliptConfig to clarify graceful degradation

Signed-off-by: Mark Phelps <[email protected]>
@codecov

codecov Bot commented Nov 25, 2025

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 84.31373% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 60.37%. Comparing base (06bce4b) to head (0c97fe8).
⚠️ Report is 1 commits behind head on v2.

Files with missing lines Patch % Lines
internal/config/config.go 0.00% 1 Missing and 1 partial ⚠️
internal/storage/environments/git/store.go 88.23% 2 Missing ⚠️
internal/storage/fs/config.go 88.88% 2 Missing ⚠️
cmd/flipt/validate.go 0.00% 1 Missing ⚠️
internal/coss/storage/environments/git/store.go 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##               v2    #5091      +/-   ##
==========================================
+ Coverage   60.31%   60.37%   +0.05%     
==========================================
  Files         136      137       +1     
  Lines       13394    13423      +29     
==========================================
+ Hits         8079     8104      +25     
- Misses       4631     4634       +3     
- Partials      684      685       +1     
Flag Coverage Δ
integrationtests 34.83% <41.17%> (-0.03%) ⬇️
unittests 51.41% <84.31%> (+0.06%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Add the templates property to the JSON schema for storage configuration.
This allows the schema validation test to pass when using the new
templates configuration option.

Signed-off-by: Mark Phelps <[email protected]>
Add the templates property to the Cue schema for storage configuration,
matching the JSON schema update.

Signed-off-by: Mark Phelps <[email protected]>
@markphelps
markphelps marked this pull request as ready for review November 25, 2025 15:39
@markphelps
markphelps requested a review from a team as a code owner November 25, 2025 15:39
@dosubot dosubot Bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Nov 25, 2025
@markphelps markphelps added needs docs Requires documentation updates and removed size:L This PR changes 100-499 lines, ignoring generated files. labels Nov 25, 2025
@dosubot

dosubot Bot commented Nov 25, 2025

Copy link
Copy Markdown

Documentation Updates

1 document(s) were updated by changes in this PR:

flipt

How did I do? Any feedback?  Join Discord

Comment thread internal/storage/fs/config.go Outdated
Address code review feedback:
1. Move TemplatesConfig from per-storage to root config level since
   templates are server-wide defaults (can still be overridden at
   repository level via flipt.yaml)
2. Change DefaultFliptConfig and related functions to accept value
   types instead of pointers, eliminating the nil parameter antipattern
3. Move TemplatesConfig to its own file (templates.go) since it's no
   longer related to storage configuration
4. Update JSON and Cue schemas to reflect templates at root level
5. Fix JSON tags to use camelCase convention

Signed-off-by: Mark Phelps <[email protected]>
@dosubot dosubot Bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Nov 26, 2025
@markphelps
markphelps requested review from Copilot and erka November 26, 2025 15:16

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds support for configuring custom commit message and pull request templates at the server configuration level. These templates can be used when creating commits and pull requests through the Flipt UI, providing a flexible way to customize the format of commit messages and PR content.

Key Changes:

  • Added TemplatesConfig struct with validation for commit messages, PR titles, and PR bodies
  • Extended Config struct to include global templates configuration
  • Updated DefaultFliptConfig and GetConfig to accept and apply server-level templates
  • Added comprehensive tests for template validation and server-level template functionality

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
internal/config/templates.go New file defining TemplatesConfig struct and validation method for server-level templates
internal/config/templates_test.go Comprehensive tests for template validation including valid and invalid template syntax
internal/config/config.go Added Templates field to root Config struct and integrated validation
internal/storage/fs/config.go Updated DefaultFliptConfig and GetConfig to accept server templates; repository templates override server templates
internal/storage/fs/config_test.go Added tests for server-level templates and partial template overrides
internal/storage/fs/snapshot_test.go Updated test calls to pass empty TemplatesConfig{}
internal/storage/fs/config_fuzz_test.go Updated fuzz test calls to pass empty TemplatesConfig{}
internal/storage/environments/git/store.go Added serverTemplates field to Environment struct and ServerTemplates() method; passed templates through GetConfig calls
internal/storage/environments/git/store_test.go Updated test calls to pass empty TemplatesConfig{} to NewEnvironmentFromRepo
internal/storage/environments/environments.go Passed f.cfg.Templates to NewEnvironmentFromRepo in factory
internal/coss/storage/environments/git/store.go Updated to call e.ServerTemplates() when getting config
cmd/flipt/validate.go Updated to pass empty TemplatesConfig{} for CLI validation without server config
config/local.yml Added example configuration showing template usage (contains documentation error)
config/flipt.schema.json Added JSON schema definition for root-level templates configuration
config/flipt.schema.cue Added CUE schema definition for root-level templates configuration
Comments suppressed due to low confidence (1)

internal/storage/fs/config.go:223

  • Inconsistent error handling for repository-level template parsing. The commit message template returns an error on parse failure (lines 198-205), while proposal title and body templates only log warnings (lines 210, 219). This inconsistency could lead to unexpected behavior where some invalid templates cause startup failures while others are silently ignored.

Consider either:

  1. Making all template parsing errors return errors (recommended for early failure detection), or
  2. Making all template parsing errors log warnings (if you want to be lenient)

The current behavior is confusing because it's not clear why commit message templates are treated differently.

	if conf.Templates.CommitMsg != "" {
		tmpl, err := template.New("commitMessage").Parse(conf.Templates.CommitMsg)
		if err != nil {
			return nil, err
		}

		c.Templates.CommitMessageTemplate = tmpl
	}

	if conf.Templates.ProposalTitle != "" {
		tmpl, err := template.New("proposalTitle").Parse(conf.Templates.ProposalTitle)
		if err != nil {
			logger.Warn("failed to parse template", zap.String("template", "proposalTitle"), zap.Error(err))
		} else {
			c.Templates.ProposalTitleTemplate = tmpl
		}
	}

	if conf.Templates.ProposalBody != "" {
		tmpl, err := template.New("proposalBody").Parse(conf.Templates.ProposalBody)
		if err != nil {
			logger.Warn("failed to parse template", zap.String("template", "proposalBody"), zap.Error(err))
		} else {
			c.Templates.ProposalBodyTemplate = tmpl
		}
	}

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.

Comment thread config/local.yml Outdated

@erka erka left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice

@markphelps
markphelps merged commit da0eb5c into v2 Nov 26, 2025
28 checks passed
@markphelps
markphelps deleted the markphelps/custom-commit-templates branch November 26, 2025 17:06
@github-project-automation github-project-automation Bot moved this to Done in Flipt V2 Nov 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs docs Requires documentation updates size:L This PR changes 100-499 lines, ignoring generated files. v2 Flipt v2

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

[Flipt v2] Allow users to customize templates for commits/PRs.

3 participants