PAC CLI provides a rich namespace dedicated to working with Dataverse solutions.
The commands provided there are really powerful, and designed to drive a code-first approach to solution management, that personally I ❤️ a lot.
Before PACX, my usual Dataverse development cycle was:
- use
pac solution init
to initialize locally my dataverse solution project (*.cdsproj) - manually update the generated
Solution.xml
file to add details about my company's publisher - build the solution via
dotnet build
- if not previously done, connect to my Dataverse environment via
pac auth
- publish the solution to dataverse via
pac solution import
- start manually create/update solution components via make.powerapps.com
- sync the changes locally via
pac solution sync
- when ready, commit everything on my Azure DevOps repo
When I started scripting data model manipulations with PACX, I felt the urge of a couple more commands to streamline my development activities.
pacx solution setDefault
At first it was pacx solution setDefault
. This came before Dataverse preferred solution feature came out, and it's pretty much a "local" version of it.
When I created tables or columns via PACX (we'll see how to in the upcoming articles) I wanted them to be placed automatically in the context of a given solution. pacx solution setDefault
allows user to define which solution should be considered "default" from now on, on the currently selected environment.
PACX saves in it's local settings storage the default solution specified for each environment. Then, when I ran any command such as pacx table create
, I no longer needed to pass the --solution argument. Time saved 😎
pacx solution getDefault
In complex scenarios, when I have multiple solutions in place, it happens to forget which solution is set as default for the current environment. That's why I created the second command, pacx solution getDefault
. It simply returns the default solution set for the current environment, if any.
pacx solution create
The code-first approach to solution management is great but... what if you just need to create a temporary solution (e.g. to work with Ribbon Workbench) that you don't want to save locally or on the repo?
I often found myself in the situation where the solution where already there, and I needed to segregate specific components in a separate one. pacx solution create
creates a new solution directly on the current environment, without saving anything locally.
If you want, you can later clone that solution using
pac solution clone
and keep it updated viapac solution sync
.
pacx solution create
has the same behavior of pac solution init
: creates the solution and also the publisher if needed.
The minimum required info for the command is the (display) name
of the solution to create, and one of publisherUniqueName
or publisherPrefix
(you can specify both, at least 1 is required).
pacx solution create --name master --publisherUniqueName greg
pacx solution create -n master -pun greg
pacx solution create --name master --publisherPrefix greg
pacx solution create -n master -pp greg
The following conventions apply:
- if the
uniqueName
argument is not specified, it's reduced from thename
argument considering only letters, numbers or underscores, all in lowercase. - solution version is set to 1.0.0.0 by default
- solution is (of course) unmanaged
- about the publisher
- if
publisherUniqueName
is specified, the tool tries to find a publisher with that unique name in the environment. If found, it is used as publisher for the solution. - if
publisherUniqueName
is not specified, butpublisherPrefix
is provided, the tool tries to find a publisher with that prefix in the environment. If found, it is used as publisher for the solution.
- if
If no publisher has been found, a new publisher is created, with the following defaults:
-
uniquename:
- uses
publisherUniqueName
if provided, otherwise - uses
publisherFriendlyName
if provided (considering only letters, numbers and underscores), otherwise - uses
publisherPrefix
- uses
-
friendlyname:
- uses
publisherFriendlyName
if provided, otherwise - uses
publisherUniqueName
if provided, otherwise - uses
publisherPrefix
- uses
-
customizationprefix:
- uses
publisherPrefix
if provided, otherwise - uses
publisherUniqueName
if provided, considering only letters or numbers. If the length of the generated string is <= 5 chars, takes the whole string, otherwise extracts the first 3 chars. Otherwise... - uses
publisherFriendlyName
, considering only letters or numbers. If the length of the generated string is <= 5 chars, takes the whole string, otherwise extracts the first 3 chars.
- uses
-
customizationoptionvalueprefix:
- uses
publisherOptionSetPrefix
argument if provided, otherwise sets it to 10000
- uses
Personally, now I use it a lot. I changed the approach described in the beginning of the current article this way:
- use
pacx solution create
to create my solution on the dataverse environment, also creating the publisher if needed - set that solution to default via
pacx solution setDefault
- start the data model manipulations via
pacx table
,pacx column
andpacx rel
commands - when ready, clone the solution locally via
pac solution clone
- do all the other stuff via pacx or make.powerapps.com
- sync the changes locally via
pac solution sync
- when ready, commit everything on my Azure DevOps repo
I find this approach more lean and direct, and allows me to focus on content right at step #2 instead of step #6 as before.
pacx solution delete
I added this command because I'm lazy. PAC CLI already contains a command to delete a solution from a given environment, but I kept forgetting it and writing
pacx solution delete ...
instead of
pac solution delete ...
Thus... I created an alias command, that does basically the same thing.
pacx solution getPublisherList
This is quite easy, it just prints the list of publishers already available in the current environment
In the next articles we'll deep dive on table management commands.