Skip to content

Commit 0513597

Browse files
authored
Improve config validation in changelog command (#2319)
1 parent 4301061 commit 0513597

File tree

1 file changed

+49
-5
lines changed

1 file changed

+49
-5
lines changed

src/services/Elastic.Documentation.Services/ChangelogService.cs

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,16 @@ Cancel ctx
8181
}
8282
}
8383

84-
// Validate products if configuration provides available products
85-
if (config.AvailableProducts != null && config.AvailableProducts.Count > 0)
84+
// Always validate products against products.yml
85+
var validProductIds = configurationContext.ProductsConfiguration.Products.Keys.ToHashSet(StringComparer.OrdinalIgnoreCase);
86+
foreach (var product in input.Products)
8687
{
87-
foreach (var product in input.Products.Where(p => !config.AvailableProducts.Contains(p.Product)))
88+
// Normalize product ID (replace underscores with hyphens for comparison)
89+
var normalizedProductId = product.Product.Replace('_', '-');
90+
if (!validProductIds.Contains(normalizedProductId))
8891
{
89-
collector.EmitError(string.Empty, $"Product '{product.Product}' is not in the list of available products. Available products: {string.Join(", ", config.AvailableProducts)}");
92+
var availableProducts = string.Join(", ", validProductIds.OrderBy(p => p));
93+
collector.EmitError(string.Empty, $"Product '{product.Product}' is not in the list of available products from config/products.yml. Available products: {availableProducts}");
9094
return false;
9195
}
9296
}
@@ -147,7 +151,6 @@ Cancel ctx
147151
)
148152
{
149153
// Determine config file path
150-
_ = configurationContext; // Suppress unused warning - kept for future extensibility
151154
var finalConfigPath = configPath ?? _fileSystem.Path.Combine(Directory.GetCurrentDirectory(), "docs", "changelog.yml");
152155

153156
if (!_fileSystem.File.Exists(finalConfigPath))
@@ -165,6 +168,47 @@ Cancel ctx
165168
.Build();
166169

167170
var config = deserializer.Deserialize<ChangelogConfiguration>(yamlContent);
171+
172+
// Validate that changelog.yml values conform to ChangelogConfiguration defaults
173+
var defaultConfig = ChangelogConfiguration.Default;
174+
var validProductIds = configurationContext.ProductsConfiguration.Products.Keys.ToHashSet(StringComparer.OrdinalIgnoreCase);
175+
176+
// Validate available_types
177+
foreach (var type in config.AvailableTypes.Where(t => !defaultConfig.AvailableTypes.Contains(t)))
178+
{
179+
collector.EmitError(finalConfigPath, $"Type '{type}' in changelog.yml is not in the list of available types. Available types: {string.Join(", ", defaultConfig.AvailableTypes)}");
180+
return null;
181+
}
182+
183+
// Validate available_subtypes
184+
foreach (var subtype in config.AvailableSubtypes.Where(s => !defaultConfig.AvailableSubtypes.Contains(s)))
185+
{
186+
collector.EmitError(finalConfigPath, $"Subtype '{subtype}' in changelog.yml is not in the list of available subtypes. Available subtypes: {string.Join(", ", defaultConfig.AvailableSubtypes)}");
187+
return null;
188+
}
189+
190+
// Validate available_lifecycles
191+
foreach (var lifecycle in config.AvailableLifecycles.Where(l => !defaultConfig.AvailableLifecycles.Contains(l)))
192+
{
193+
collector.EmitError(finalConfigPath, $"Lifecycle '{lifecycle}' in changelog.yml is not in the list of available lifecycles. Available lifecycles: {string.Join(", ", defaultConfig.AvailableLifecycles)}");
194+
return null;
195+
}
196+
197+
// Validate available_products (if specified) - must be from products.yml
198+
if (config.AvailableProducts != null && config.AvailableProducts.Count > 0)
199+
{
200+
foreach (var product in config.AvailableProducts)
201+
{
202+
var normalizedProductId = product.Replace('_', '-');
203+
if (!validProductIds.Contains(normalizedProductId))
204+
{
205+
var availableProducts = string.Join(", ", validProductIds.OrderBy(p => p));
206+
collector.EmitError(finalConfigPath, $"Product '{product}' in changelog.yml is not in the list of available products from config/products.yml. Available products: {availableProducts}");
207+
return null;
208+
}
209+
}
210+
}
211+
168212
return config;
169213
}
170214
catch (IOException ex)

0 commit comments

Comments
 (0)