Case study
Modernizing a 96-activity Dynamics 365 workflow assembly without breaking existing workflows
The challenge
Workflow Tools for Dynamics 365 is a widely used open-source assembly of custom workflow activities (Clone Record, Query Values, Set Process, Share Record, JSON Parser and many more). It started in 2015 and has grown through many contributors to 96 activities that organizations depend on inside their classic workflows.
Years of accumulated change left the usual problems: duplicated helper code, inconsistent error handling, a bundled third-party library, and no systematic way to prove that an upgrade wouldn't break the workflows already built on top of it.
What we did
Refactored the code
- Merged duplicate helper projects into a single shared library.
- Added a common activity base class and standardized tracing and exception handling.
- Moved activities to thin entry points that read inputs, call one shared method and set outputs.
- Replaced internal FetchXML with QueryExpression, removed dead code, and fixed blocking HTTP calls.
- Replaced a bundled library copy with the Newtonsoft.Json package, merged into the single deployable assembly with ILRepack, because Dataverse loads only the registered assembly.
Built an upgrade test, not just unit tests
- Wrote a test plan of 16 on-demand classic workflows that together exercise all 79 activities in the previously published version.
- Scripted the test data, the workflow creation, and a runner that executes every workflow, collects each one's results, and cleans up.
- Ran them on the old version for a baseline, upgraded in place, ran them again, and diffed the two runs automatically.
- Added 354 automated unit and integration tests alongside.
Fixed what the comparison found
The before-and-after diff exposed real differences that unit tests would not have caught. For example, six workflow argument names that existing workflows relied on had to be restored.
Made the build repeatable
- A Power Platform build that leaves out activities whose tables don't exist there, built from the same source and keeping the original assembly name so existing installs upgrade in place.
- Continuous integration that builds and tests every push, and a release workflow that builds the solution packages from a version tag.
The result
Every difference between the old and new version was found, listed in one report, and checked against a documented list of expected changes before release. Future changes can be verified by re-running the same automated test instead of clicking through workflows by hand.
Why it matters for you
This is the approach behind every Plugin Rescue engagement: inventory each component, record what it does today, upgrade it, and prove that nothing your business depends on has changed.