Repository navigation
Add support for protectedSettings to override lower priority settings - #2293
Chris Blank (ChrisBlankDe) wants to merge 28 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This pull request adds an importantSettings mechanism to AL-Go’s settings merge logic so selected settings can be “protected” during multi-source settings resolution, and documents the new behavior across schema + docs + release notes with accompanying Pester tests.
Changes:
- Extend settings merge logic to recognize an
importantSettingslist and prevent overriding of protected (non-array) settings. - Add Pester tests covering important setting protection, interaction with arrays/
overwriteSettings, and conditional settings. - Update schema and documentation (
settings.md,RELEASENOTES.md) to describe the new setting and expected behavior.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| Actions/.Modules/ReadSettings.psm1 | Implements important-setting tracking in the merge pipeline. |
| Actions/.Modules/settings.schema.json | Adds importantSettings to the settings schema with defaults/description. |
| Tests/ReadSettings.Test.ps1 | Adds test coverage for the important-setting merge semantics. |
| Scenarios/settings.md | Documents importantSettings behavior and examples. |
| RELEASENOTES.md | Adds release note entry describing the new capability. |
|
Interesting concept. We'd have to give it a bit of a thought, as it goes a bit against the way "important" settings are defined. For now, I can't tell I like |
|
I missed to add the use-case to description. added now. I think this will help understand what we're trying to achieve with this feature. When naming it, we got inspired by the !important rule in CSS, since we want to implement a similar concept. i wouldnt name it Think about what you'd like to call it, and I'll be happy to change it. |
Maria Zhelezova (mazhelez)
left a comment
There was a problem hiding this comment.
Left some comments for you to look at.
Also, let's also address the name of the new setting. I understand the CSS origin, but the syntax is quite different.
Here are my suggestions:
protectedSettingsenforcedSettings
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (5)
Scenarios/settings.md:324
- This explanation reverses the merge order described above: line 13 says later-applied sources win, while this paragraph calls the organization source “higher priority” and the later project source “lower priority.” In that terminology, a lower-priority source would not override the value in the first place. Describe the feature in terms of earlier/later application order so users can tell which values are protected.
By default, AL-Go follows a standard settings hierarchy where settings from higher priority levels (closer to deployment) override settings from lower priority levels. However, you can mark specific settings as **important** to protect them from being overridden by lower priority settings using the `importantSettings` array.
When a setting is marked as important at a higher level in the hierarchy, it cannot be overridden by non-important values from lower priority levels. If a lower-priority source also marks the same setting as important, then the lower-priority value is allowed to override.
Actions/.Modules/settings.schema.json:402
- This wording implies that nested
deliverToAppSourcemembers can individually be marked important, but importance is tracked only for top-level names and the recursive merge receives no importance lists (ReadSettings.psm1:89). If this describes the parent-level gate, namedeliverToAppSourceexplicitly so users do not try to addincludeDependenciestoimportantSettings.
"description": "An array of settings to be overwritten by the current deliverToAppSource setting. If a setting is marked as important in higher-priority settings, overwrite is ignored unless the current source also marks that same setting as important. See https://aka.ms/ALGoSettings#overwriteSettings"
Actions/.Modules/settings.schema.json:657
- This wording implies that nested
alDocmembers can individually be marked important, but importance is tracked only for top-level names and the recursive merge receives no importance lists (ReadSettings.psm1:89). Clarify that the gate applies to the top-levelalDocsetting rather than names such asincludeProjects.
"description": "An array of settings to be overwritten by the current alDoc setting. If a setting is marked as important in higher-priority settings, overwrite is ignored unless the current source also marks that same setting as important. See https://aka.ms/ALGoSettings#overwriteSettings"
Actions/.Modules/settings.schema.json:687
- This wording implies that nested
commitOptionsmembers can individually be marked important, but importance is tracked only for top-level names and the recursive merge receives no importance lists (ReadSettings.psm1:89). Clarify that the gate applies to the top-levelcommitOptionssetting rather thanpullRequestLabels.
"description": "An array of settings to be overwritten by the current commitOptions setting. If a setting is marked as important in higher-priority settings, overwrite is ignored unless the current source also marks that same setting as important. See https://aka.ms/ALGoSettings#overwriteSettings"
Actions/.Modules/ReadSettings.psm1:86
- This guard also changes merging for complex object settings such as
deliverToAppSource,alDoc, andcommitOptions, but the added tests cover only scalar and array values. Add Pester cases showing that a non-important source cannot modify an important object and that a source marking the parent object important can merge or overwrite it; otherwise regressions in the recursive path are untested.
# For non-array properties: skip if this setting is marked as important from higher priority source,
# unless the lower-priority source also marks this property as important.
if ($dstImportantSettings -contains $prop -and $srcPropType -ne "Object[]" -and $srcImportantSettings -notcontains $prop) {
OutputDebug "Skipping important setting '$prop' marked from higher priority source (non-array type)"
return
There was a problem hiding this comment.
🟡 Changes recommended
Source attribution can include rejected object merges, and derived settings can lose their protection metadata.
2 open findings
6 resolved since last review
This applies accumulated protection toCustomSettingsas well, so a custom setting no longer… This final test leaves both process-level settings variables populated. Because Pester files can… Use “a protected setting” rather than “an protected setting.” The new setting's documentation does not state its default. Add that it defaults to an empty array… The priority terminology contradicts the established merge order above: line 13 says the… This added caveat is inaccurate for this nestedoverwriteSettings:protectedSettingssupports…
🧠 Review effort: Balanced
Give feedback about Copilot approvals in this survey to enter a drawing for a $150 gift card.
|
Maria Zhelezova (@mazhelez) I addressed the new Copilot and script analyzer comments. I also made further changes in response to your review comment and its replies. |
|
Copilot resolve the merge conflicts in this pull request. Move the release notes above the v10.0 section. |
|
Maria Zhelezova (@mazhelez) I've resolved the merge conflicts |



❔What, Why & How
This pull request introduces a new
protectedSettingsmechanism that allows you to protect specific settings from being overridden by lower-priority sources in the AL-Go settings hierarchy. The implementation ensures that settings marked as protected can only be overridden by lower-priority sources if those sources also explicitly mark the same setting as protected. This applies to both standard and conditional settings, and integrates with the existingoverwriteSettingsmechanism. Documentation and schema files are updated to reflect this new feature.Protected settings
protectedSettingsarray in settings files, enabling top-level settings to be protected from non-protected overrides by lower-priority sources. The merging logic inMergeCustomObjectIntoOrderedDictionarywas updated to enforce this rule for both direct and conditional settings, and to ensure that array settings are always merged. [1] [2] [3] [4]Schema and documentation updates:
settings.schema.jsonto add theprotectedSettingsproperty and clarified the behavior ofoverwriteSettingswhen protected settings are involved. [1] [2] [3] [4]protectedSettingsinRELEASENOTES.mdandScenarios/settings.md. [1] [2]Other improvements:
protectedSettingsto the default settings returned byGetDefaultSettings.These changes make it easier to enforce organization- or repository-level settings and prevent accidental overrides from lower-priority sources, while maintaining flexibility for advanced scenarios.
Use Case 1
We want to define conditionalSetting for different buildModes as ALGoOrgSettings as we need them in many Repos.
For example we have one BuildMode for MinVersion Validation:
{ "ConditionalSettings": [ { "buildModes": [ "minversion" ], "settings": { "artifact": "/sandbox/*//first", "nuGetFeedSelectMode": "EarliestMatching" } } ] }in the target repo its then enough to define the buildModes:
{ "buildModes": [ "default", "minversion" ] }if we add the buildMode to any workflow in the repo/project the artifact get overwritten by the repo/project setting.
If we define the artifact setting in conditional setting as protected, this overwrite wouldnt happen.
Use Case 2
Went to define a buildmode for testing isv solution against different localizations
{ "ConditionalSettings": [ { "buildModes": [ "at" ], "settings": { "country": "at" } } ] }in the target repo its then enough to define the buildModes:
{ "country": "de", "buildModes": [ "default", "at" ] }the country of this build mode is overwritten by the country defined in the repo.
However, we can't omit the “country” definition from the repo settings because there are solutions that need to be built against ‘w1’ and others that need to be built against ‘de’.
Related to issue: #
✅ Checklist