Skip to content

Preserve overwriteSettings when template project settings are merged after user repo settings#2233

Open
jeffreybulanadi wants to merge 1 commit intomicrosoft:mainfrom
jeffreybulanadi:fix/2228-overwrite-settings-custom-template
Open

Preserve overwriteSettings when template project settings are merged after user repo settings#2233
jeffreybulanadi wants to merge 1 commit intomicrosoft:mainfrom
jeffreybulanadi:fix/2228-overwrite-settings-custom-template

Conversation

@jeffreybulanadi
Copy link
Copy Markdown

Problem

When a repository uses overwriteSettings in .github/AL-Go-Settings.json to clear or replace an array property (such as appDependencyProbingPaths), a subsequent template-managed settings source (AL-Go-TemplateProjectSettings.doNotEdit.json) re-merges its own values for that property. This causes the user intent to be silently ignored.

The root cause is in MergeCustomObjectIntoOrderedDictionary: the function is called independently for each source. The overwriteSettings mechanism removes a property from the destination only at the moment of the user source merge. Any template source that appears later in the ordered list has no knowledge that the property was already overwritten, so it re-applies its values unconditionally.

Closes: #2228

Solution

Track which settings names have been explicitly overwritten by any user-controlled source as ReadSettings iterates the ordered sources list. Pass that accumulated list into MergeCustomObjectIntoOrderedDictionary alongside a flag that identifies whether the current source is a template-managed file. When both conditions are true, skip the merge for that property.

Changes to Actions/.Modules/ReadSettings.psm1

MergeCustomObjectIntoOrderedDictionary receives two new optional parameters:

  • [string[]] overwrittenSettings: names of settings already declared as overwritten by a prior user-controlled source.
  • [bool] isTemplateSource: true when the source file is a template-managed *.doNotEdit.json file.

When isTemplateSource is true and the property name appears in overwrittenSettings, the merge for that property is skipped in both the "add new properties" loop and the "update existing properties" loop.

The ReadSettings foreach loop now:

  1. Determines isTemplateSource from the source file name.
  2. Passes -overwrittenSettings and -isTemplateSource to both MergeCustomObjectIntoOrderedDictionary calls (main merge and conditional settings merge).
  3. After each non-template source is merged, accumulates property names declared in its overwriteSettings list so subsequent template sources cannot re-introduce those values.

Changes to Tests/ReadSettings.Test.ps1

Two integration tests added:

  1. Verifies that appDependencyProbingPaths remains empty after a user overwrite even when the template project settings file contains values for that property.
  2. Verifies that a user project settings file can still add values to a property after it was overwritten at the repo level, and that template values remain excluded.

Testing

  1. Create a repository that uses an AL-Go template.
  2. In .github/AL-Go-TemplateProjectSettings.doNotEdit.json, add an entry to appDependencyProbingPaths.
  3. In .github/AL-Go-Settings.json, set overwriteSettings: ["appDependencyProbingPaths"] and appDependencyProbingPaths: [].
  4. Run any AL-Go workflow that reads settings.
  5. Before this change, appDependencyProbingPaths in the resolved settings contains the template entry. After this change, it is empty as the user specified.

Unit tests can be run locally with Pester v5:

Invoke-Pester -Path Tests/ReadSettings.Test.ps1

When a user repo settings file (AL-Go-Settings.json) uses overwriteSettings
to clear or replace an array property such as appDependencyProbingPaths, a
subsequent template-managed source file (AL-Go-TemplateProjectSettings.doNotEdit.json)
was able to re-merge its own values into that property because the
MergeCustomObjectIntoOrderedDictionary function had no awareness of
which settings had already been explicitly overwritten by a user source.

Changes:
- MergeCustomObjectIntoOrderedDictionary gains two optional parameters:
  overwrittenSettings ([string[]]) - names of settings already overwritten
  by a user-controlled source, and isTemplateSource ([bool]) - true when
  the source file is a template-managed *.doNotEdit.json file.
  When isTemplateSource is true and a property name appears in
  overwrittenSettings, the merge of that property is skipped entirely.

- ReadSettings now tracks overwrittenSettings as it iterates the ordered
  settings sources. After each non-template source is merged, any property
  names declared in its overwriteSettings list are accumulated. Template
  sources that follow receive the accumulated list so they cannot
  re-introduce overwritten values.

- Two Pester tests added to ReadSettings.Test.ps1 covering:
  1. overwriteSettings in a user source prevents template project settings
     from re-merging that property.
  2. overwriteSettings in a user source still allows later user project
     settings to contribute additional values to that property.
Copilot AI review requested due to automatic review settings May 1, 2026 22:45
@jeffreybulanadi jeffreybulanadi requested a review from a team as a code owner May 1, 2026 22:45
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 updates the AL-Go settings merge logic so that overwriteSettings declared in user-controlled sources continues to take effect even when template-managed *.doNotEdit.json sources are merged later, preventing templates from re-introducing values that a user explicitly cleared/replaced.

Changes:

  • Extend MergeCustomObjectIntoOrderedDictionary and ReadSettings to track settings explicitly overwritten by user sources and skip merging those settings from template sources.
  • Add Pester integration tests covering the overwrite-vs-template merge behavior for appDependencyProbingPaths.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
Actions/.Modules/ReadSettings.psm1 Tracks overwritten setting names across sources and prevents later template sources from re-merging them.
Tests/ReadSettings.Test.ps1 Adds integration tests ensuring user overwrites win over template settings while still allowing later user sources to merge.

Comment on lines +509 to +511
if (-not $isTemplateSource -and $settingsJson.PSObject.Properties.Name -contains "overwriteSettings") {
$settingsJson.overwriteSettings | ForEach-Object {
if ($_ -notin $overwrittenSettings) {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Orverwritesettings fail with custom Al-Go Template

2 participants