All articles
DevOps
NaN undefined NaN·9 min read

Merging multiple solutions into one release

When a change spans several solutions, a custom task and a PowerShell step in Azure DevOps can combine them into a single, easy-to-deploy artifact.

As a Power Platform estate grows, work naturally spreads across several solutions. Deploying them one by one is fiddly and error-prone — get the order wrong and an import fails, forget one and production is left in a half-updated state. A cleaner approach is to merge the relevant solutions into a single release artifact as part of the pipeline, so a deployment becomes one predictable step instead of several fragile ones.

This article walks through the approach: a custom task that does the merging, and a pipeline step that calls it.

Why merge at all

There are good reasons to keep solutions separate during development — clear ownership, independent components, sensible boundaries. But at release time, a feature that spans several of them needs to land together and in the right order. Coordinating that by hand across environments is exactly the kind of repetitive, error-prone task automation exists to remove.

Merging keeps the development-time structure intact while giving you a single, clean thing to deploy. It’s not a substitute for good solution design — it’s what makes a good design easy to ship.

A custom task

The mechanism is a custom task built as a .NET class library that exposes a PowerShell cmdlet. Building it as a cmdlet means the pipeline can call it like any other PowerShell command, passing the parameters it needs:

  • the environment URL to connect to,
  • the credentials (a client ID and secret for a service principal),
  • and the list of solutions to combine.

A shared base class handles the common parameters so each command stays focused:

public abstract class CommandBase : Cmdlet
{
    [Parameter(Mandatory = true)]
    public string EnvironmentUrl { get; set; } = "";

    [Parameter(Mandatory = true)]
    public string ClientId { get; set; } = "";

    [Parameter(Mandatory = true)]
    public string ClientSecret { get; set; } = "";
}

You build the project once, and commit the compiled binaries to the Azure DevOps repository so the pipeline can load them without any external dependency or package feed.

Calling it from the pipeline

In the pipeline, a PowerShell task loads the compiled module and invokes the merge command, passing the connection parameters and the list of solutions to combine:

Import-Module "$(Build.SourcesDirectory)/tasks/MergeSolutions.dll"
Merge-Solutions -EnvironmentUrl $(EnvUrl) `
                -ClientId $(ClientId) `
                -ClientSecret $(ClientSecret) `
                -Solutions "SolutionA","SolutionB","SolutionC"

The output is a single merged solution — the release artifact that the rest of the pipeline deploys. Because it runs as an ordinary pipeline step, it slots neatly into the existing build and release flow, right before the import stage.

Keeping it robust

A few things make this dependable in practice:

  • Fail loudly. If a solution can’t be found or the merge fails, the task should stop the pipeline with a clear message rather than producing a broken artifact.
  • Pin your inputs. Be explicit about which solutions and versions are being merged, so a release is reproducible.
  • Secure the credentials. The client secret comes from a variable group or Key Vault, never hard-coded, and the service principal has only the access it needs.

When to use it

Merging is most useful when a feature genuinely spans multiple solutions that always ship together. If your solutions are truly independent and deploy on their own schedules, you don’t need it — keep them separate. But for coordinated releases, this pattern removes a whole class of ordering mistakes and makes deployments simpler to run and easier to reason about.

Like most good automation, it’s a modest amount of upfront work that quietly saves you from a recurring, avoidable source of release-day stress.

Want to talk through something like this for your own environment? Get in touch.

Have a Power Platform or Azure problem worth solving?

Tell us what you're building. We'll bring the architecture, the delivery and the follow-through.