From 7284047ae55cb4499556724671ed834fbc9c8222 Mon Sep 17 00:00:00 2001 From: Ariel Eli Date: Wed, 27 May 2026 19:03:28 +0300 Subject: [PATCH 1/6] feat(changelog): warn when template uses remote variables without matching feature When a user's template references variables like `github.contributors` or `commit.gitlab` but the binary was compiled without the corresponding feature flag (`github`, `gitlab`, etc.), the rendering silently produces empty output with no indication of why. Add a `warn_if_remote_template_variables_without_feature` check in `Changelog::build` that emits a `tracing::warn` for each remote whose template variables are present but whose Cargo feature is absent. Fixes #659 --- git-cliff-core/src/changelog.rs | 53 +++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/git-cliff-core/src/changelog.rs b/git-cliff-core/src/changelog.rs index 016243a23f..dca85a7f90 100644 --- a/git-cliff-core/src/changelog.rs +++ b/git-cliff-core/src/changelog.rs @@ -52,7 +52,7 @@ impl<'a> Changelog<'a> { /// Builds a changelog from releases and config. fn build(releases: Vec>, config: Config) -> Result { let trim = config.changelog.trim; - Ok(Self { + let changelog = Self { releases, header_template: match &config.changelog.header { Some(header) => Some(Template::new("header", header.clone(), trim)?), @@ -65,7 +65,9 @@ impl<'a> Changelog<'a> { }, config, additional_context: HashMap::new(), - }) + }; + warn_if_remote_template_variables_without_feature(&changelog); + Ok(changelog) } /// Constructs an instance from a serialized context object. @@ -658,6 +660,53 @@ impl<'a> Changelog<'a> { } } +/// Emits a warning when a template references remote-specific variables +/// (e.g. `github.contributors`) for a provider whose Cargo feature is not +/// compiled in. The render itself will fail later with a confusing +/// "variable not found in context" message; this warning gives users a +/// clear, actionable hint before that happens. +fn warn_if_remote_template_variables_without_feature(changelog: &Changelog<'_>) { + let templates: Vec<&Template> = [ + Some(&changelog.body_template), + changelog.header_template.as_ref(), + changelog.footer_template.as_ref(), + ] + .into_iter() + .flatten() + .collect(); + + macro_rules! warn_missing_feature { + ($feature:literal, $vars:expr, $example:literal) => { + #[cfg(not(feature = $feature))] + if templates.iter().any(|t| t.contains_variable($vars)) { + tracing::warn!( + "Template uses a `{}` variable (e.g. `{}`) but the `{}` feature is not \ + enabled. Rebuild git-cliff with `--features {}` or use a binary that \ + includes all remote features.", + $feature, + $example, + $feature, + $feature, + ); + } + }; + } + + warn_missing_feature!("github", &["github", "commit.github"], "github.contributors"); + warn_missing_feature!("gitlab", &["gitlab", "commit.gitlab"], "gitlab.contributors"); + warn_missing_feature!("gitea", &["gitea", "commit.gitea"], "gitea.contributors"); + warn_missing_feature!( + "bitbucket", + &["bitbucket", "commit.bitbucket"], + "bitbucket.contributors" + ); + warn_missing_feature!( + "azure_devops", + &["azure_devops", "commit.azure_devops"], + "azure_devops.contributors" + ); +} + fn get_body_template(config: &Config, trim: bool) -> Result