Flowline 0.5.0

There is a newer version of this package available.
See the version list below for details.
dotnet tool install --global Flowline --version 0.5.0
                    
This package contains a .NET tool you can call from the shell/command line.
dotnet new tool-manifest
                    
if you are setting up this repo
dotnet tool install --local Flowline --version 0.5.0
                    
This package contains a .NET tool you can call from the shell/command line.
#tool dotnet:?package=Flowline&version=0.5.0
                    
nuke :add-package Flowline --version 0.5.0
                    

Flowline

CI NuGet NuGet

Flowline is a CLI tool for delivering Dataverse solutions with unmanaged packages, Git as the source of truth, and a straightforward DEV to TEST to PROD workflow.


Why Flowline?

PAC CLI gives you the primitives — Flowline gives you the workflow. Export, unpack, pack, and import are building blocks; Flowline turns them into a defined project structure with a clone → push → sync → deploy loop, plus attribute-driven plugin registration and a direct push that skips the pack/import cycle.

Sync-first, not pack-first. Flowline is for teams that own their Dataverse environments. DEV is the working canvas — makers and developers contribute directly there, sync captures its state into source control, and deploy ships exactly what was confirmed in DEV. For ISV-style packaging (reproducible builds, no shared DEV env, AppSource distribution), reach for ALM Accelerator or Power Platform Build Tools instead. And unlike Power Platform Pipelines — which require Managed Environments and managed solutions — Flowline requires neither.

Flowline brings a few things the other tools don't:

  • Source-controlled solution XML. sync unpacks the solution per component, so git diff shows real changes — not a binary blob. clone bootstraps an existing solution into the repo; deploy packages from the repo and imports into the target.
  • Fast push for code assets. push syncs plugin assemblies and web resources directly to DEV without a full solution import. Use it from a Flowline project, or point it at a standalone DLL and web resource folder.
  • Attribute-driven plugin registration. Decorate IPlugin classes with [Step], [Filter], [PreImage], and [PostImage]; Flowline reads the compiled assembly and handles the Dataverse registrations.
  • Plugins, workflow activities, and Custom APIs in one assembly. Flowline reads all supported types from a single assembly in one pass.
  • Modern auth. Flowline reuses the PAC CLI token cache. No passwords, no client secrets in scripts, no Windows Credential Manager.

Install

dotnet tool install --global Flowline

Prerequisites (PAC CLI and Git):

winget install Microsoft.PowerAppsCLI
winget install Git.Git

Authenticate with PAC CLI before using Flowline:

pac auth create --environment https://your-org.crm4.dynamics.com

Authenticating in CI/CD pipelines:

- run: pac auth create --kind ServicePrincipal --applicationId $CLIENT_ID --clientSecret $CLIENT_SECRET --tenant $TENANT_ID
- run: flowline deploy prod

Usage Modes

Flowline can be used in two ways.

Full Project Workflow

Use this when Flowline owns the local solution structure. clone creates .flowline, the unpacked solution, an Plugins project, and a WebResources project.

# Create a Git repo for the Flowline project
mkdir contoso-flowline
cd contoso-flowline
git init

# One-time: bring an existing solution into the repo
flowline clone ContosoCustomizations --prod https://contoso.crm4.dynamics.com

# Generate early-bound C# types (first run derives and saves the namespace)
flowline generate

# Daily dev loop
flowline push
flowline sync
git commit -m "feat: add validation"

# Promote
flowline deploy test
flowline deploy prod

For fresh environments:

flowline provision dev --prod https://contoso.crm4.dynamics.com
flowline provision test --prod https://contoso.crm4.dynamics.com

Project mode expects this structure:

solutions/
  ContosoCustomizations/
    ContosoCustomizations.cdsproj  # cdsproj + unpacked solution XML in src/
    src/
    Plugins/                  # plugin assembly project
      Plugins.csproj
      Models/                 # early-bound C# types — generated by flowline generate
    WebResources/             # web resource files
      dist/                   # files here are synced to Dataverse by push
    ContosoCustomizations.sln
.flowline                     # environment URLs and solution config

Files under WebResources/dist/ are synced to Dataverse by flowline push. Files named *_nosync.* are excluded.

Standalone Push

Use this when you only want Flowline's direct Dataverse push. You do not need a Flowline project, .flowline, Git repo, solutions/ folder, Plugins project, or WebResources project.

Run it from a normal folder that is not a Flowline project folder:

flowline push ContosoCustomizations --dll ./bin/Release/MyPlugins.dll --dev https://contoso-dev.crm4.dynamics.com
flowline push ContosoCustomizations --webresources ./dist --dev https://contoso-dev.crm4.dynamics.com
flowline push ContosoCustomizations --dll ./bin/Release/MyPlugins.dll --webresources ./dist --dev https://contoso-dev.crm4.dynamics.com

If --dev is omitted, Flowline uses the current resource-specific PAC auth profile.

Standalone rules:

  • --dll must point to an already-built plugin assembly.
  • --webresources points directly at the folder whose files should be synced.
  • --scope is not allowed with --dll or --webresources.
  • .flowline is not read in standalone mode.
  • If .flowline exists in the current folder, standalone mode stops because that usually means project mode and standalone mode were mixed.
  • The target solution must be unmanaged.

Plugin And Custom API Registration

Add the Flowline.Attributes NuGet package to your Plugins project:

<PackageReference Include="Flowline.Attributes" Version="1.0.0" PrivateAssets="all" />

Decorate your plugin classes. No base class is needed:

[Step("account")]
[Filter("name", "creditlimit")]
[PreImage("name", "creditlimit")]
public class AccountPreUpdatePlugin : IPlugin
{
    public void Execute(IServiceProvider sp) { ... }
}

flowline push reads the compiled assembly and creates or updates plugin types, steps, images, and Custom API registrations in Dataverse.

Full attribute reference: Flowline.Attributes README


Commands

Command What it does
clone <solution> Bootstrap an existing solution from production into the repo. Sets up the full project structure.
push [solution] Build and sync project assets to DEV, or push standalone artifacts with --dll / --webresources.
sync [solution] Pull the current solution state from DEV and unpack it into the repo.
deploy <target> Pack the solution from the repo and import it into TEST, PROD, or an explicit URL.
provision [dev\|test] Provision a DEV or TEST environment by copying from production.
generate [solution] Generate early-bound C# types for the solution's entities and custom APIs into Plugins/Models/.
status Show environment info, Flowline version, and PAC CLI status.

Early-Bound Type Generation

flowline generate wraps pac modelbuilder build with opinionated defaults. It auto-discovers the solution's entities and custom APIs from DEV, generates early-bound C# types into Plugins/Models/, and saves the namespace to .flowline.

# First run — namespace derived from Plugins.csproj and saved to .flowline
flowline generate

# Subsequent runs pick up namespace and extra tables from .flowline automatically
flowline generate

# Override or set namespace permanently
flowline generate --namespace Contoso.Plugins.Models

# Include extra tables not in the solution
flowline generate --extra-tables account,contact

Generated types land in Plugins/Models/ alongside your plugin code — no separate assembly, no ILMerge. Running generate again fully replaces the folder, so stale files from removed entities are cleaned up automatically.

Requires an active pac auth create session against the DEV environment. The namespace is derived in order from <RootNamespace>, then <PackageId> (set by pac plugin init --name), then the csproj filename, then <SolutionName>.Models. Once derived, it is saved to .flowline and reused on every subsequent run.

CI pipelines and offline use are not supported — generate always queries live DEV. Teams that need generated types in CI should commit Plugins/Models/ to source control and re-run flowline generate locally when solution entities change.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

Version Downloads Last Updated
0.18.0 101 8/26/2026
0.17.0 192 8/16/2026
0.16.0 104 8/7/2026
0.15.0 115 8/3/2026
0.14.0 115 7/31/2026
0.13.0 108 7/24/2026
0.12.0 116 7/17/2026
0.11.0 122 7/15/2026
0.10.0 129 7/12/2026
0.9.0 129 7/5/2026
0.8.0 129 6/29/2026
0.7.0 136 6/21/2026
0.6.0 143 6/5/2026
0.5.0 134 5/29/2026
0.4.0 147 5/7/2026
0.3.0 119 5/5/2026
0.2.0 146 4/19/2026
0.1.0 216 6/28/2025