You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Follow-ups to #19 (project files), plus tests, docs and release notes for the next release.
Fixes and changes
Opening a project and choosing "No" (remove existing) now disposes all watchers and forgets the persisted assembly, package and web resource watches. Before, the removed watchers kept deploying in the background.
Web resources are stored in the project file with their root folder and mappings, and restored on open: merged when the root folder matches, asked when it differs. Project files from the first version get a message instead.
Plugin assemblies are remembered per connection and reload on reconnect, like packages and web resources.
Plugin packages: if the saved id doesn't exist in the connected environment, the upload looks the package up by name and retries.
Packages in a project are skipped on environments without plugin package support, and wait for that check when a project is opened right after connecting.
Open... and Add > Plugin assembly need a connection.
WatchPluginFile.Dispose no longer throws when nothing was watched, and disposes its FileSystemWatcher.
New XrmToolBox.AutoDeployer.Tests (NUnit, like PluginRegistration): 46 unit tests for project files and the sample templates, web resource settings merge, package lookup and web resource naming. CI runs them and uploads the results.
3 integration tests (category Integration, local only) deploy through the plugin assembly and plugin package watchers, including the lookup by name. They're skipped without settings.
Tests/TestBench: test plugin assembly, plugin package, web resources, sample project templates, setup/cleanup scripts and a manual test plan. Connection string, publisher and prefix come from the gitignored Tests/testbench.local.json or environment variables; without a publisher the test bench creates its own.
To keep the helpers testable, project file reading, web resource merging and package lookup moved into small static classes (no behaviour change).
Docs and release
README: project files, per-connection settings, and a building and testing section linking to the test bench README.
- Dispose all watchers when replacing them on project open, and forget
persisted package/web resource watches so they don't come back
- Store web resource settings in the project file and restore them on open
- Skip plugin packages on environments that don't support them
- If a package upload fails because the package id doesn't exist in this
environment, look it up by name and retry
- Require a connection before opening a project
- AddPluginAssembly uses its path parameter; rename Type enum to WatchFileType
- WatchPluginFile.Dispose no longer throws when nothing was watched, and
disposes the FileSystemWatcher
- Fix Save button tooltip
- Watched plugin assembly paths are saved per connection and restored when
connecting, so all watch types behave the same
- Removing an assembly (or replacing watchers from a project) forgets it too
- Adding a plugin assembly requires a connection
- Packages in a project opened while the plugin package support check is
still running are added once the check completes, instead of being skipped
…or testing
No behaviour change: MainControl and WatchPluginPackageFile call the new static helpers, and the web resource naming helpers become internal so tests can reach them.
- XrmToolBox.AutoDeployer.Tests (NUnit, like PluginRegistration): project
files, web resource settings merge, plugin package lookup and web
resource naming
- Integration tests (category Integration, local only) deploy the test
bench through the plugin assembly and plugin package watchers. They're
skipped without a connection string (AUTODEPLOYER_TEST_CONNECTION or the
gitignored Tests/connection.local.txt)
- Tests/TestBench: test plugin assembly, plugin package, web resources,
sample .adproj files, Dataverse setup/cleanup scripts and a manual test plan
- Web resource roots written with forward slashes now count as the same folder
The test bench README now walks through the app registration, application user, publisher and connection string, how to run the tests in Visual Studio and from the command line, and common errors. The main README describes project files and links to it. Setup-Dataverse.ps1 says so when the publisher is missing.
- Connection string, publisher and prefix come from Tests/testbench.local.json
(gitignored, example in Tests/testbench.example.json), each overridable by
AUTODEPLOYER_TEST_CONNECTION / _PUBLISHER / _PREFIX. Replaces
Tests/connection.local.txt
- Setup-Dataverse.ps1 uses an existing publisher (checking its prefix) or
creates it; without settings it creates its own AutoDeployTest / adt.
Cleanup only removes a publisher the test bench created
- Sample projects are templates with placeholders for the test bench folder,
prefix and package id; Setup writes filled-in copies to Projects/Local
- Integration tests take the package name from the prefix setting
…eference
- .github/dependabot.yml: weekly, grouped updates for the plugin and test
projects' NuGet packages and for the workflow actions
- Remove the NuGet.Protocol reference: nothing uses it, and its HintPath
pointed at the packages folder that went away with packages.config (#14)
- Tests: pin MscrmTools.Xrm.Connection to the plugin's version, which
removes the MSB3277 version conflict warnings
The reason will be displayed to describe this comment to others. Learn more.
🟡 Changes recommended
Unresolved restoration and deferred-watch handling can interrupt connection switching or violate project choices, while merge and XML-escaping issues affect saved configurations.
Extends the project-file support introduced in #19 with web-resource settings, per-connection assembly restoration, and watcher lifecycle fixes. Adds automated tests and a Dataverse test bench for validating deployment behavior.
Changes:
Restores and persists watches, handles package lookup by name, and adds connection and package-support guards.
Adds unit tests, local integration tests, sample projects, and setup/cleanup scripts; runs unit tests in CI.
Updates usage documentation, testing instructions, and release notes.
…conflicts
- Sample projects: XML-escape the test bench folder and prefix when filling
in the templates (Setup-Dataverse.ps1 and the tests), so a folder like
C:\R&D still gives valid files
- Packages from projects opened while the support check runs are appended
instead of replaced, and cleared when the watchers are replaced
- A saved plugin assembly that can't be watched (deleted or moved DLL) is
skipped and reported, instead of aborting the connection switch; adding
one that fails shows the error and isn't saved
- Web resource settings with the same root folder but a different prefix are
treated as a conflict and ask before replacing, since the manager rebuilds
every CRM name from one prefix
The clone path is inserted directly into XML text. A valid Windows path such as C:\src\R&D\Tests\TestBench makes every generated project malformed because the ampersand is not escaped, so none of the ready-to-open samples can be loaded. XML-escape the replacement path before inserting it, or populate the XML elements through an XML API.
The sample-loading helper also substitutes an unescaped filesystem path into XML. When the repository is cloned beneath a directory containing &, such as C:\src\R&D, the sample-project unit tests fail during deserialization even though that clone path is valid. Escape Folder as XML text before replacement so it round-trips to the original path.
Preserve or clear queued packages when replacing watches
XrmToolBox.AutoDeployer/MainControl.cs:194
While the support check is pending, opening another project overwrites previously queued packages even when existing watches are kept. Replacing watches with a package-free project instead leaves the old queue intact, so those packages reappear when the check completes. Include queued packages in the keep/replace prompt, accumulate them when keeping, and clear them in RemoveAllWatchers when replacing.
Skip failed assembly watcher restores
XrmToolBox.AutoDeployer/MainControl.cs:684
Automatic reload now constructs every saved assembly watcher during UpdateConnection, but WatchPluginFile reads the DLL immediately and throws if it has been deleted, moved, or cleaned from the build output. One stale saved path therefore aborts connection initialization before package support and web-resource watches are restored. Handle reload failures per assembly, report the affected path, and continue restoring the other watches.
Prevent duplicate watches after package identity resolution
After this resolved ID is persisted, reopening the original cross-environment project with existing watches kept creates a duplicate: AddPluginPackage only matches the old ID saved in the project. Both watches then upload the same file to the same package. Reconcile resolved package identity during import, or retain a stable source identity so reopening the project does not create another watch.
Prevent duplicate resource names during project merging
Merging projects with the same root can add different local files that target the same CrmName, creating watchers that overwrite one Dataverse resource. This bypasses the duplicate-name validation in WebResourcesManagerDialog.cs:410–413. Preserve that constraint during merging by retaining the existing mapping or asking the user to resolve the conflict.
- Opening a project matches a package watch by name and file too, so a watch
whose id was resolved by name isn't added a second time
- Merging web resource settings skips a mapping whose CRM name another file
already deploys to, like the manager's own validation
The manager retains unchecked scan results in Mappings, so an existing entry with IsActive = false causes an incoming active mapping for the same file to be discarded here. Opening a project with “Keep existing” then silently omits that project's watch, since RefreshWebResourceWatchers skips inactive mappings. Preserve an active watch from either configuration when merging duplicate paths.
…pping
When the connection already maps the same file but doesn't watch it (the
manager keeps unchecked scan results), the merged mapping is watched if
either side watches it, instead of silently dropping the project's watch.
Prompt before replacing projects with pending package watches
XrmToolBox.AutoDeployer/MainControl.cs:196
When a project contains only packages and the support check is still pending, its watches exist only in _pendingProjectPackages, leaving the list empty. Opening another project then bypasses the keep/replace prompt entirely, so the first project's queued packages cannot be replaced and are eventually added alongside the second project. Include a nonempty pending queue in the prompt condition so RemoveAllWatchers can discard it.
Ignore support-check callbacks from earlier connections
XrmToolBox.AutoDeployer/MainControl.cs:963
A support check started for connection A can finish after switching to B. Its callback clears B's pending flag and consumes B's queued project packages using A's result; if A reports unsupported, those packages are discarded even when B's own check later succeeds. Capture the service and a connection-generation token when starting the check, and ignore callbacks from an earlier generation before changing state or draining the queue.
…ort checks
- WatchPluginPackageFile doesn't save its package list once disposed, also
when the save was already queued on the UI thread, so replaced watches
don't come back on reconnect
- WatchPluginFile stops waiting for the DLL when disposed and doesn't upload,
so a removed watch can't deploy to the connection it was created for
- Packages still waiting for the support check count for the keep/replace
question when opening another project
- A support check that finishes after switching connection is ignored
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-ups to #19 (project files), plus tests, docs and release notes for the next release.
Fixes and changes
WatchPluginFile.Disposeno longer throws when nothing was watched, and disposes itsFileSystemWatcher.AddPluginAssemblyuses its path parameter,Typeenum renamed toWatchFileType, tooltip wording.Tests
XrmToolBox.AutoDeployer.Tests(NUnit, like PluginRegistration): 46 unit tests for project files and the sample templates, web resource settings merge, package lookup and web resource naming. CI runs them and uploads the results.Integration, local only) deploy through the plugin assembly and plugin package watchers, including the lookup by name. They're skipped without settings.Tests/TestBench: test plugin assembly, plugin package, web resources, sample project templates, setup/cleanup scripts and a manual test plan. Connection string, publisher and prefix come from the gitignoredTests/testbench.local.jsonor environment variables; without a publisher the test bench creates its own.Docs and release
AutoDeployer.nuspecupdated.Housekeeping
.github/dependabot.yml: weekly, grouped updates for NuGet (plugin and tests) and GitHub Actions. Replaces the obsolete 2023 Dependabot PRs Bump NuGet.Common from 5.9.1 to 5.11.5 in /XrmToolBox.AutoDeployer #9, Bump NuGet.Protocol from 5.9.3 to 5.11.5 in /XrmToolBox.AutoDeployer #10 and Bump Microsoft.Rest.ClientRuntime from 2.3.22 to 2.3.24 in /XrmToolBox.AutoDeployer #11, which targeted the removedpackages.config.NuGet.Protocolreference, and pinnedMscrmTools.Xrm.Connectionin the tests to the plugin's version.How to test
Tests/TestBench/README.mdcovers the environment setup, running the integration tests, and the manual test plan in XrmToolBox.