Giter Site home page Giter Site logo

delegateas / daxif Goto Github PK

View Code? Open in Web Editor NEW
40.0 40.0 15.0 15.77 MB

A framework for automating a lot of xRM development processses. By using simple F# script commands/files one can save a lot of time and effort during this process by using Delegates DAXIF# library.

License: Other

C# 14.49% F# 85.24% Batchfile 0.09% PowerShell 0.19%
automation developer-tools dynamics-365 dynamics-crm tooling

daxif's People

Contributors

bo-stig-christensen avatar danaakesen avatar emilielildholdt avatar fdominguezcen avatar henrikhannemose avatar magesoe avatar misoeli avatar mkholt avatar mktange avatar mlr-dg avatar sigurdthorlund avatar skovlund avatar tommalow avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

daxif's Issues

Add handling of Entity/Attribute Mappings

Deletion of Attribute Mapping is not currently part of the solution and needs to be update for each environment. Additionally, it is know that upgrading an environment can result in deleted mappings being reintroduced.

So two new things needs to be added to Daxif.

  1. Add methods for deleting and adding attribute mappings for a given environment (should always be dev) given a list of mappings.
  2. Add Attribute Mappings to Extended Solution so that it becomes part of the deploy process and synced across environments

Question regarding F# and Plugins

I've been watching your awesome projects (especially XrmDefinitelyTyped and this one) for a while, and I'm finally giving in and trying to deep dive into F#. Is it possible to write plugins entirely in F#? If so, is it also possible to use/modify the extended version of the plugin base that DAXIF requires?

Problems running Daxif script in Visual studio 2017 v15.3 and up

Some Daxif f# scripts fails when running in F# interactive in Visual Studio 2017 v15.3 and newer. The scripts fails due to Visual Studio trying to access two dll assemblies, Microsoft.VisualStudio.Shell.15.0.dll and Microsoft.VisualStudio.Shell.Framework.dll, which it cannot find. This is most likely an issue in the F# interactive in visual studio in cooperation with the CRM sdk assemblies.

The current solutions is to copy these two dll's into the same folder as the f# scripts.

The dll's can be found in the folder: C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\PublicAssemblies

Upgrade to latest DataVerse Client SDK

Currently Daxif uses the now outdated Microsoft.CrmSdk.XrmTooling.CoreAssembly package, which in turn makes use of ADAL for auth (through Microsoft.IdentityModel.Clients.ActiveDirectory).
This is inconvinient as ADAL support has stopped as of December 31st 2022.

In order to make use of latest (and supported) MSAL-based implementation it is necessary to port the code to use the latest Microsoft.PowerPlatform.DataVerse.Client package.

Flag for specifying which web resources to synchronize

Is your feature request related to a problem? Please describe.
We have non-coders deploying via DAXIF. They would like to easily be able to add web resources (e.g. images) to a solution, without having to understand DAXIF, Visual Studio, Git etc.
Today they can add web resources directly to a solution, but DAXIF will then try to delete those web resources (and fail if they are in use).

Describe the solution you'd like
I suggest changing DAXIF such that it only tries to delete web resources if their type/name is in a whitelist. E.g. .js and .html files could by default be the only files that DAXIF tries to delete if they are not in version control.

Automatically update nuget packages to latest version on each release

Is your feature request related to a problem? Please describe.
We do not remember to update the CrmSdk assemblies when releasing DAXIF (as of this writing the DLLs are approximately 1 year old).

Describe the solution you'd like
I propose automatically updating the nuget packages to the newest version on each release.
As far as I can see, we are currently using the old packages.config, which does not support automatically downloading the highest available version. This would thus be a good time to migrate to PackageReference which does support floating versions.

It should be easy to migrate to PackageReference, but I get an message that "Project is not eligible for migration" when trying to do so. Since I do not have time to fix this now, I am creating this issue to remember to do this at some point in the future :)

System.MissingMethodException

Hi,

I keep getting this error when I try to run the scripts.
depending on which script, it's a different method being referenced.

I think it has something to do with my F# tools, but seeing as this is my first experience using F#, I have no clue how to resolve this.

Below 2 of the exceptions I'm getting

SolutionExportDev.fsx / CountEntities.fsx

System.MissingMethodException: Method not found: 'Microsoft.FSharp.Core.FSharpOption`1<!!0> Microsoft.FSharp.Collections.SeqModule.TryHead(System.Collections.Generic.IEnumerable`1<!!0>)'.
   at DG.Daxif.Common.CrmDataHelper.retrieveFirstMatch(OrganizationServiceProxy proxy, QueryExpression query)
   at DG.Daxif.Modules.Solution.Versioning.getSolutionVersionNumber(OrganizationServiceProxy proxy, String solutionName)
   at DG.Daxif.Solution.UpdateVersionNumber(Environment env, String solutionName, FSharpOption`1 increment)
   at <StartupCode$FSI_0002>.$FSI_0002.main@() in C:\Users\JST\Documents\Visual Studio 2017\Projects\TcMeetingDemo\TcMeetingDemo\Daxif\SolutionExportDev.fsx:line 16
Stopped due to error

PluginSyncDev.fsx

System.Exception: Failed to fetch plugin configuration from plugin assembly. This error can be caused if an old version of Plugin.cs is used.\nFull Exception: Method not found: '!!0 Microsoft.FSharp.Collections.ArrayModule.Head(!!0[])'.
   at Microsoft.FSharp.Core.PrintfModule.PrintFormatToStringThenFail@1356.Invoke(String message)
   at DG.Daxif.Modules.Plugin.PluginDetection.getPluginsFromAssembly(Assembly asm)
   at DG.Daxif.Modules.Plugin.PluginDetection.getAssemblyContextFromDll(String projectPath, String dllPath, PluginIsolationMode isolationMode, Boolean ignoreOutdatedAssembly)
   at DG.Daxif.Modules.Plugin.MainHelper.loadAndValidateAssembly[a](FSharpFunc`2 proxyGen, String projectPath, String dllPath, PluginIsolationMode isolationMode, Boolean ignoreOutdatedAssembly)
   at DG.Daxif.Modules.Plugin.MainHelper.analyze[a](FSharpFunc`2 proxyGen, String projectPath, String dllPath, String solutionName, PluginIsolationMode isolationMode, Boolean ignoreOutdatedAssembly)
   at DG.Daxif.Modules.Plugin.Main.syncSolution[a](FSharpFunc`2 proxyGen, String projectPath, String dllPath, String solutionName, PluginIsolationMode isolationMode, Boolean ignoreOutdatedAssembly, Boolean dryRun)
   at DG.Daxif.Plugin.Sync(Environment env, String assemblyPath, String projectPath, String solutionName, FSharpOption`1 dryRun, FSharpOption`1 isolationMode, FSharpOption`1 ignoreOutdatedAssembly, FSharpOption`1 logLevel)
   at <StartupCode$FSI_0002>.$FSI_0002.main@() in C:\Users\JST\Documents\Visual Studio 2017\Projects\TcMeetingDemo\TcMeetingDemo\Daxif\PluginSyncDev.fsx:line 11
Stopped due to error

Enable native support for running XrmMockup

Today we have built in support for running XrmContext (Solution.GenerateCSharpContext) and XrmDefinitelyTyped (Solution.GenerateTypeScriptContext) from DAXIF.

I propose that we add support to DAXIF for generating metadata for XrmMockup, e.g. by adding Solution.GenerateXrmMockupMetadata.

Today I manually start XrmMockup's metadata generation as part of my GenerateCSharpContext.fsx-script with code similar to the following. This is the code I would like to replace:

let usr, pwd, dom = Env.dev.getCreds()
let metadataDir = Path.solutionRoot + "\UnitTest\Metadata"
let startInfo = ProcessStartInfo()
startInfo.WorkingDirectory <- metadataDir
startInfo.FileName <- Path.Combine(metadataDir, "MetadataGenerator365.exe")
startInfo.Arguments <- sprintf "url=%s username=%s password=%s domain=%s ap=%s solutions=%s" 
  (Env.dev.url.ToString())
  usr
  pwd
  dom
  (Env.dev.ap.Value.ToString())
  SolutionInfo.name
Process.Start(startInfo)

Unable to generate context files: Invalid type for alternate key: OptionSet "Team_MembershipType"

Describe the bug
I have solution in Dynamics, where I used for generating the C Sharp Context, and executing the script for that, I have just added entity Team to the solution because I want to create plugin on Teams, and while generating the CSharp Context, i got an error "Unable to generate context files: Invalid type for alternate key: OptionSet "Team_MembershipType"

When I look at Dynamics the solution, fair enough, there are a manged solution from Microsoft, where there is an alternativ-key, that I cannot do much about it. I see this error as a bug, is it somthing you guys can confirm?

To Reproduce
Steps to reproduce the behavior:

  1. Go to Dynamics, and make a solution include Entity Team in it.
  2. Click on Visual Studio, and modify Script in Daxif folder GenerateCSharpContext.fsx and provide solution name created at point 1.
  3. Run the modified script GenerateCSharpContext.fsx
  4. See error at F# Interactive

Expected behavior
Here you will se an error simlar to the following:

(2020-10-13 09:22:54Z) [Error]: Unable to generate context files: Invalid type for alternate key: OptionSet "Team_MembershipType"

System.Exception: DG XrmContext failed
at DG.Daxif.Common.Utility.postProcess(Int32 code, String es, String os, ConsoleLogger log, String proc) in ..\Daxif\src\Delegate.Daxif\Common\Utility.fs:line 173
at DG.Daxif.Modules.Solution.Main.updateCustomServiceContext(Environment env, String outputDirectory, String pathToExe, LogLevel log, FSharpList1 solutions, FSharpList1 entities, FSharpList`1 extraArgs) in ..\Daxif\src\Delegate.Daxif\Modules\Solution\Main.fs:line 312
at <StartupCode$FSI_0004>.$FSI_0004.main@() in ..\Scripts\Daxif\GenerateCSharpContext.fsx:line 11
Stopped due to error

Screenshots
No need

Environment

  • CRM/D365/CDS version: Crm Online v.(9.1.0.23470) (.crm4.dynamics.com)
  • Tool version: DAXIF# v.4.8.1.0
  • Other applicable environments (Visual Studio Community 2019)

Additional context
No need

Not being asked to re-enter creds when using MFA/OAuth method and GetCrmServiceClient

Describe the bug
If user/pass creds are saved and getting a new password, running the following will fail:

let env = DG.Daxif.Environment.Get "MFADevelopment"
let proxy = env.connect().GetCrmServiceClient();

The issue that the above doesn't ask to re-enter creds. I know this, since using the old way it will asked to overwrite and re-enter my username and password, and after this the above two lines will work.

So there is missing a prompt asking to re-enter the user's creds when using the above code.

To Reproduce
Steps to reproduce the behavior:

  1. Hopefully, the above description will be enough to reproduce.

Expected behavior
A prompt should appear when using the code in the description and the user's have got a new password.

Environment

  • CRM/D365/CDS version: 9.1.x
  • Tool version: 5.2.0

CrmServiceClient - Use 'useUniqueInstance' parameter to enable a script to connect to multiple environments

CrmServiceClient has a constructor parameter 'useUniqueInstance' that enables the use of multiple environments for each CrmServiceClient instance.

The con is additional initialization time in constructor, even towards same environment multiple times.
The pro is the possibility to connect to multiple environments within one script.

The feature will be parameterized and default to 'false' to keep existing scripts running as previously. - Also most scripts will be using connections to a single environment only.

[Feature Request] Support for NuGet package plug-ins

Is your feature request related to a problem? Please describe.
Currently many projects use ILMerge for deploying plug-in solutions with external dependencies. Microsoft recently released the preview for deploying NuGet packages instead of DLLs to Dynamics. This should be supported by Daxif, so we can deploy nuget packages.

Describe the solution you'd like
I want the same user experience when deploying DLLs. Maybe in the config stating if it's a DLL or NuGet package and deploy the package with all steps etc. like how it currently works.

Describe alternatives you've considered
Alternative is to deploy using the plug-in registration tool and cry.

Create Action processes like plugin registrations

Is your feature request related to a problem? Please describe.
We currently support automatic registration of plugins and plugin steps.
However, creating an action / workflow codeactivity required manual work.

Describe the solution you'd like
Two features would greatly improve the functionality:

  1. Register CodeActivities as Actions, handling input and output parameters
  2. Support custom messages when registering plugins, which can be used to call directly without setting up an Action.

Null reference on plugin sync updating post image

I ran into a problem when running plugin sync and syncronization attempts to update a post image.
The image was updated to have fewer attributes.
I got the following trace log:

(2018-05-02 10:41:34Z) [Info]: Updating sdkmessageprocessingstepimage: {Plugin Class}: Synchronous Post Create of {Entity}, PostImage
System.Exception: 02/05/2018 08.41.35: An unexpected error occurred.
Errorcode: -2147220970
Trace:


	[======INNER FAULT======]
02/05/2018 08.41.35: System.NullReferenceException: Object reference not set to an instance of an object.
   at Microsoft.Crm.ObjectModel.SdkMessageProcessingStepImageServiceInternal`1.Update(IBusinessEntity entity, ExecutionContext context): Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #A4494E00
Errorcode: -2147220970
Trace:

   at DG.Daxif.Common.CrmUtility.raiseExceptionIfFault(OrganizationServiceFault fault)
   at [email protected](OrganizationServiceFault fault)
   at DG.Daxif.Common.CrmDataHelper.func2@1[a](FSharpFunc`2 faultHandler, FSharpFunc`2 resultTransform, ExecuteMultipleResponseItem[] array)
   at DG.Daxif.Common.CrmDataHelper.performAsBulkResultHandling@96.Invoke(OrganizationRequest[] x)
   at DG.Daxif.Modules.Plugin.MainHelper.update(OrganizationServiceProxy proxy, MapDiff`3 imgDiff, MapDiff`3 stepDiff)
   at DG.Daxif.Modules.Plugin.MainHelper.performSync[a](OrganizationServiceProxy proxy, a solutionName, AssemlyLocal asmCtx, FSharpOption`1 asmReg, FSharpMap`2 sourceTypes, FSharpMap`2 sourceSteps, FSharpMap`2 sourceImgs, FSharpMap`2 targetTypes, FSharpMap`2 targetSteps, FSharpMap`2 targetImgs)
   at DG.Daxif.Modules.Plugin.Main.syncSolution[a](FSharpFunc`2 proxyGen, String projectPath, String dllPath, String solutionName, PluginIsolationMode isolationMode, Boolean ignoreOutdatedAssembly, Boolean dryRun)
   at DG.Daxif.Plugin.Sync(Environment env, String assemblyPath, String projectPath, String solutionName, FSharpOption`1 dryRun, FSharpOption`1 isolationMode, FSharpOption`1 ignoreOutdatedAssembly, FSharpOption`1 logLevel)
   at <StartupCode$FSI_0003>.$FSI_0003.main@() in C:\Users\tkm\Documents\Repos\...\PluginSyncDev.fsx:line 11
Stopped due to error

Environments with double authentication is impossible to connect

Hi all,

I worked with Daxif before and normally everything works smooth.
But on our own development environment we use double authentication in Office 365.
Is there a way I can make this work?

The error I get is the following.


(2018-10-18 14:26:35Z) [Error]: Unable to generate TypeScript files: An unsecured or incorrectly secured fault was received from the other party. See the inner FaultException for the fault code and detail.

System.Exception: Delegate XrmDefinitelyTyped failed
   at DG.Daxif.Common.Utility.postProcess(Int32 code, String es, String os, ConsoleLogger log, String proc)
   at DG.Daxif.Modules.Solution.SolutionHelper.updateTypeScriptContext'[a,b](a org, String location, b ap, String usr, String pwd, String domain, String exe, ConsoleLogger log, FSharpList`1 solutions, FSharpList`1 entities, FSharpList`1 extraArgs)
   at DG.Daxif.Modules.Solution.Main.updateTypeScriptContext[a](Uri org, String outputDirectory, a ap, String usr, String pwd, String domain, String pathToExe, LogLevel log, FSharpList`1 solutions, FSharpList`1 entities, FSharpList`1 extraArgs)
   at <StartupCode$FSI_0058>.$FSI_0058.main@() in C:\Repos\Syntra\Crm.Extensions\Esc.Syntra.Crm.Extension\Scripts\Daxif\GenerateTypeScriptContext.fsx:line 10
Stopped due to error

Thanks in advance!

Custom API support (execution stage = internal/30)

Plugins configured to be executed from/in a Custom API are registered in the 'internal' execution stage by selecting the Plugin Type in Power Platform.

image

image

Solution/request:
Add 'Internal' to ExecutionStage, so plugins can be specified to run in the Internal execution stage.
Plugins specified to run in the Internal execution stage do not need to be registered (I don't think this is even possible), but they are executed when the corresponding Custom API triggered.

image

Things I've done:
I already added Internal to the ExecutionStage enum, but then registration fails.
When registered manually using the Plugin Registration tool, the plugin gets triggered when calling the Custom API.

image

Trying to set-up plugin deployment with Daxif

Hi there,

I've seen your presentation at eXtreme and was trying to remove some of the deadly sins of CRM development. I've removed one already using the early bound and was trying to set-up automated deployment for a new plugin project. But I'm encountering some issue and can't figure out what is wrong with my set-up.

I will try to explain the set-up without giving to much customer details.

  • Simple plugin solution, with 3 plugins on a Dynamics 365 V9.0 environment using the Dynamics 365 9.0.0.7 Microsoft.Xrm.Sdk (nuget).
  • Running the tool from Visual Studio 2017 via F# Interactive.
  • The plugins aren't registered in Dynamics yet.

Error message
(2018-04-10 15:25:20Z) [Info]: Environment: "XXXX DEV" (https://xxx.crm4.dynamics.com/XRMServices/2011/Organization.svc)
(2018-04-10 15:25:20Z) [Info]: User: [email protected]
(2018-04-10 15:25:21Z) [Info]: DAXIF# v.4.1.1.0
(2018-04-10 15:25:21Z) [Info]: Action: Plugin synchronization
(2018-04-10 15:25:21Z) [Info]: Comparing plugins registered in CRM versus those found in your local code
(2018-04-10 15:25:21Z) [Verbose]: Loading local assembly and it's plugins
Binding session to 'D:\Projects\xxx\xxxx\xxxx.Plugins\xxx.Plugins.Tools\Daxif\bin\Microsoft.Xrm.Sdk.dll'...
System.Exception: Failed to fetch plugin configuration from plugin assembly. This error can be caused if an old version of Plugin.cs is used.\nFull Exception: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
at Microsoft.FSharp.Core.PrintfModule.PrintFormatToStringThenFail@1645.Invoke(String message)
at DG.Daxif.Modules.Plugin.PluginDetection.getPluginsFromAssembly(Assembly asm)
at DG.Daxif.Modules.Plugin.PluginDetection.getAssemblyContextFromDll(String projectPath, String dllPath, PluginIsolationMode isolationMode, Boolean ignoreOutdatedAssembly)
at DG.Daxif.Modules.Plugin.MainHelper.loadAndValidateAssembly[a](FSharpFunc2 proxyGen, String projectPath, String dllPath, PluginIsolationMode isolationMode, Boolean ignoreOutdatedAssembly) at DG.Daxif.Modules.Plugin.MainHelper.analyze[a](FSharpFunc2 proxyGen, String projectPath, String dllPath, String solutionName, PluginIsolationMode isolationMode, Boolean ignoreOutdatedAssembly)
at DG.Daxif.Modules.Plugin.Main.syncSolution[a](FSharpFunc2 proxyGen, String projectPath, String dllPath, String solutionName, PluginIsolationMode isolationMode, Boolean ignoreOutdatedAssembly, Boolean dryRun) at DG.Daxif.Plugin.Sync(Environment env, String assemblyPath, String projectPath, String solutionName, FSharpOption1 dryRun, FSharpOption1 isolationMode, FSharpOption1 ignoreOutdatedAssembly, FSharpOption`1 logLevel)
at <StartupCode$FSI_0074>.$FSI_0074.main@() in D:\Projects\xxx\xxx\xxx.Dynamics365.Plugins\xxx.Dynamics365.Plugins.Tools\Daxif\PluginSyncDev.fsx:line 12
Stopped due to error

Plugin Definition

public class AddAccountToAccessTeam : Plugin
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="AddAccountToAccessTeam"/> class.
        /// And registers the plugin on the correct plugin events.
        /// </summary>
        public AddAccountToAccessTeam()
            : base(typeof(AddAccountToAccessTeam))
        {
            RegisterPluginStep<account>(EventOperation.Update, ExecutionStage.PostOperation, ExecuteAddAccountToAccessTeam)
                .SetExecutionMode(ExecutionMode.Synchronous);
        }

private void ExecuteAddAccountToAccessTeam(LocalPluginContext localContext)
        {
        }
}

Plugin Class used
I've tried to use the following two classes

Dynamcs DLL
I've also tried to replace the \Daxif\bin\Microsoft.Xrm.Sdk.dll to use the latest Xrm.Sdk (v 9.0.0.7). But that gives me the same error.

I'm a bit lost. Is there a sample somewhere with a very basic set-up that works?

Thanks!

Cannot publish Custom API - Not recognized in sync

Describe the bug
We have created a Custom API and defined in code according to the Custom API Setup. When trying to deploy it with the 5.4.0 version it syncs my plugins, but it doesn't sync the Custom API. Somehow I think it ignores / cannot find the class and then doesn't register it.

I can't find out why it wouldn't recognize the class / doesn't register. I tried to look into to the sync source code, but couldn't find any clue on why it wouldn't register. Maybe some of you know how it internally works and what I might have forgotten. Or is this function disabled at all in the new 3.4.0 version?

Maybe the most important part is that when I register through the plugin registration tool of Microsoft, I do find my custom API, I can register it there, and then (when linking to custom API configuration records) it also executes just fine...

To Reproduce
Steps to reproduce the behavior:

  1. Add a custom API to your source code
  2. Try to run the daxif sync script
  3. Sync script doesn't recognize the Custom API and (when registered through the Plugin Registration tool) it deletes the custom API from the system and when not yet available in the system it doesn't try to register it.

Expected behavior
That the custom API would be registered in through the sync script.

Screenshots
image

Environment

  • D365 Online
  • Tool version: 5.4.0

Additional context

(2023-02-07 15:03:08Z) [Info]: DAXIF# v.5.4.0.0
(2023-02-07 15:03:08Z) [Info]: Action: Plugin synchronization
(2023-02-07 15:03:08Z) [Info]: Comparing plugins registered in CRM versus those found in your local code
(2023-02-07 15:03:08Z) [Verbose]: Connection timeout set to 0 hour, 59 minutes, 0 seconds
(2023-02-07 15:03:08Z) [Verbose]: Loading local assembly and it's plugins
(2023-02-07 15:03:08Z) [Verbose]: Local assembly loaded
(2023-02-07 15:03:08Z) [Verbose]: Validating plugins to be registered
(2023-02-07 15:03:08Z) [Verbose]: Validation completed
(2023-02-07 15:03:09Z) [Verbose]: Connection timeout set to 0 hour, 59 minutes, 0 seconds
(2023-02-07 15:03:09Z) [Info]: Starting plugin synchronization
(2023-02-07 15:03:09Z) [Info]: Deleting removed registrations
(2023-02-07 15:03:09Z) [Info]: Creating/updating assembly
(2023-02-07 15:03:10Z) [Info]: Updating pluginassembly: Xxx.Xxx.Dataverse.General.Plugins
(2023-02-07 15:03:10Z) [Info]: Updating existing registrations
(2023-02-07 15:03:10Z) [Info]: Creating new registrations
(2023-02-07 15:03:10Z) [Info]: Plugin synchronization was completed successfully

ExtendedSolution sets state, regardless of whether it is needed.

When importing an extended solution, DAXIF will always call set state on processes, such that the state remains the same. However, this can produce unwanted side effects if the owner of those processes is suddenly disabled. This will also be true for similar situations.

I propose that such operations are only executed when needed, even though it would add additional overhead to the import.

Workflow upgrade

Upgrading a custom workflow activity is not supported, as Daxif does not support updating the Major and Minor version numbers of workflow assemblies.
An upgrade must be registered as a new assembly, but Daxif treats it as an update, resulting in the following Exception:
System.ServiceModel.FaultException`1[Microsoft.Xrm.Sdk.OrganizationServiceFault]: Plug-in assembly does not contain the required types or assembly content cannot be updated. (Fault Detail is equal to Microsoft.Xrm.Sdk.OrganizationServiceFault).
Stopped due to error

How does DataExport work?

I'm trying to use DG.Daxif.Data.Export() method but so far without any luck. I'm calling your lib from C# which I got working for the other methods (be looking at the errors and reading thru the F# code), but this method leaves me blank and wondering how it works.

I don't get any errors, no logging what it is doing or missing, even when LogLevel = Verbose. Is is very fast done, so it looks it is doing nothing. It's probably something simple I'm missing, but I can't figure it out.

Reproduce
I use the following C# code where SourceEnvironment is created somewhere else (no problem with the connection):

DG.Daxif.Data.Export(
    env: SourceEnvironment,
    entityNames: new string[] { "account" },
    pathToOutputFile: @"C:\Data.csv",
    deltaFromDate: null,
    logLevel: DG.Daxif.LogLevel.Verbose);

Expected behavior
I expect some data file to generated, like. csv or something else.

How to sync Workflows and Plugins that are in one project (dll)?

I'm using Daxif from C# in my build (NUKE https://nuke.build/) which works well. Now I'm trying to merge my custom Workflows and Plugins projects into one Extensions project (and therefore one dll).

My code executes the following steps, which work if the Workflows and Plugins are in separate dll's.

        DG.Daxif.Workflow.Sync(
            env: SourceEnvironment,
            assemblyPath: SourceDirectory / "Extensions" / "bin" / Configuration / "net462" / $"{SolutionInfo.baseNamespace}.dll",
            solutionName: SolutionInfo.name,
            isolationMode: null,
            logLevel: null
        );

        DG.Daxif.Plugin.Sync(
            env: SourceEnvironment,
            assemblyPath: SourceDirectory / "Extensions" / "bin" / Configuration / "net462" / $"{SolutionInfo.baseNamespace}.dll",
            projectPath: SourceDirectory / "Extensions" / "Extensions.csproj",
            solutionName: SolutionInfo.name,
            dryRun: false,
            isolationMode: null,
            ignoreOutdatedAssembly: null,
            logLevel: null
        );

I expected that the registration would of Workflows and Plugins in one dll would go well.

What happens is that the second step (DG.Daxif.Plugin.Sync) removes the custom workflow activities that are registrated in the step before.
image

Is there a way the prevent the removing of custom workflow activities when syncing plugins? First syncing the plugins and than the workflows doesn't work.

Special-character handling by the ViewExtender

The name of a view may include characters such as @, parenthesis, colons, and spaces.

Some of these (colons and spaces) are stripped away when generating F# parameters but others (@ and parenthesis) are not. This means that the code cannot be run as these characters are not allowed in F# parameter names.

Stripping the characters is not ideal either, as this may generate identical names for views with different names, e.g. 'My View 1' and 'My View 2' will both have the F# parameter name MyView. (Numeric characters are also stripped).

Generate TypeScript context Azure Pipelines

Describe the bug
I am using the YAML Pipelines to build my CRM system. I am using the nuget task to restore the packages. But that does not seem to update the dependencies or add the daxIf/bin folder needed or the other.fsx scripts. How are you guys generating the typescript context?
Are you checking in all the files on the DaxIf project?

Environment

  • D365/CDS version: 9.1.x
  • Tool version: Laters

Additional context
Add any other context about the problem here. Error messages og solution files.

Tls 1.2

When trying to deploy webresources to a 9.0 environment I kept getting an error "Unable to connect to CRM".
I managed to fix it by adding this to the script:

open System.Net

ServicePointManager.SecurityProtocol <- SecurityProtocolType.Tls12

Since 9.0 it's mandatory to use TLS 1.2 and its backward compatible. Hence why I added it.
I recon you guys have a better place to add this line.

Plugin Registration Setup

Hi,

I've been looking at your automatic plugin registrations and got a question.
According to MS best practices a plugin should be stateless. The only state a plugin can obtain is defined by the configuration parameters in the ctor. See quote.

For improved performance, Microsoft Dynamics 365 caches plug-in instances. The plug-in's Execute method should be written to be stateless because the constructor is not called for every invocation of the plug-in. Also, multiple system threads could execute the plug-in at the same time. All per invocation state information is stored in the context, so you should not use global variables or attempt to store any data in member variables for use during the next plug-in invocation unless that data was obtained from the configuration parameter provided to the constructor. Changes to a plug-ins registration will cause the plug-in to be re-initialized.

The plugin registrations are stored in a global collection on the ExtendedPlugin thus the use of state.
Is there any idea behind it why it was done this way? Wouldn't Attributes be a better use? Plugin registrations are basicly metadata and in a way 'static'. No need to rebuild the RegisteredEvents every time the plugin is instanced.

Change Extended Solution to delete plugin steps before the standard solution import

When renaming/deleting plugin steps in the source environment we are unable to import to the target environment. We get the error:

Plug-in assembly does not contain the required types or assembly content cannot be updated

This makes sense, since the renamed/deleted plugin steps still exist in the target environment, but not in the updated assembly.

To work around this, our current best practice for years has been to delete all plugin steps in the target environment before importing.

Extended Solution stores information about the plugin steps in the source environment, but currently is only run after the standard solution import. I suggest changing Extended Solution such that it deletes plugin steps (that have been renamed/removed) before the standard solution import. In this way it would no longer be necessary to blindly delete all plugin steps before an import.

Plugin.Sync - Few questions

Hello,

For the API Plugin.Sync(Env.dev, pluginDll, pluginProjFile, SolutionInfo.name)

  • What is the significance of the solution name parameter?
  • Can deployment only happen within the context of a solution? I want to deploy plugin assembly, steps, images, etc without making any solution changes or requiring a solution, just like the Plugin Registration tool.
  • Is there any support for a add/update only deployment mode or a deployment filter to specify specific plugin classes so that I could slowly add support to plugins over time rather than having to do an all or none approach to integration?
  • If I want to further customize the extended plugin base class, what is the specific criteria/interface that needs to be left unchanged to ensure Daxif can still extract the plugin configuration from the base class?
  • For async plugin steps, there is an option to delete the system job record if successful, is that part of the configuration that can be deployed? If not, what does Daxif set that too?

F# is not my first language and the documentation was very sparse so I was having some trouble obtaining the answer via code. I appreciate any help or direction you can provide.

Display dependencies

It would be nice to wrap the RetrieveDependenciesForDeleteRequest and retrieve names (and Entity names, where applicable) for all dependencies, so that I don't have to manually retrieve each of the dependencies from a Guid and a SolutionComponentType.

Automatically add javascript to form

I do not have a solution to this problem, but it would be nice to have it. The first time we add a new javascript file to a solution we also have to add it to the forms it's used on. It would be nice if it was automatically added.

It would also be nice if the method for registering code to a form was done in a strongly typed way.

[Plugin Sync] Failed to fetch custom api configuration from assembly since v5.3.*

Describe the bug
Sinc DAXIF v5.3.0 and up I can't synchronize my plugin(s), I'm now getting an exception about custom api. My C# project and the solution in Dynamics doesn't have any Customer API (but it has an endpoint to Azure ServiceBus), so I don't know where this error is suddenly coming from and/or how to solve this.

I went back to v.5.2.0 and with that version I can deploy!

If you need more info to help with this bug, please let me know.

To Reproduce
Steps to reproduce the behavior:

  1. Call DG.Daxif.Plugin.Sync from DAXIF 5.3.0 and up
  2. Fails with to error in the logging below.

I got the following logging/stacktrace:

(2022-05-22 10:17:19Z) [Info]: Environment: "Source" (Some https://XXX.crm4.dynamics.com/)
(2022-05-22 10:17:19Z) [Info]: DAXIF# v.1.0.0.0
(2022-05-22 10:17:19Z) [Info]: Action: Plugin synchronization
(2022-05-22 10:17:19Z) [Info]: Comparing plugins registered in CRM versus those found in your local code
(2022-05-22 10:17:19Z) [Verbose]: Connection timeout set to 0 hour, 59 minutes, 0 seconds
(2022-05-22 10:17:19Z) [Verbose]: Loading local assembly and it's plugins
10:17:19 [ERR] Target PushCustomizations has thrown an exception
System.Exception: Failed to fetch custom api configuration from assembly. This error can be caused if an old version of CustomAPI.cs is used.\nFull Exception: The input array was empty.
Parameter name: array
   at Microsoft.FSharp.Core.PrintfModule.PrintFormatToStringThenFail@1439.Invoke(String message)
   at DG.Daxif.Modules.Plugin.PluginDetection.getCustomAPIsFromAssembly(Assembly asm)
   at DG.Daxif.Modules.Plugin.PluginDetection.getAssemblyContextFromDll(String projectPath, String dllPath, AssemblyIsolationMode isolationMode, Boolean ignoreOutdatedAssembly)
   at DG.Daxif.Modules.Plugin.MainHelper.loadAndValidateAssembly(IOrganizationService proxy, String projectPath, String dllPath, AssemblyIsolationMode isolationMode, Boolean ignoreOutdatedAssembly)
   at DG.Daxif.Modules.Plugin.MainHelper.analyze[a](FSharpFunc`2 proxyGen, String projectPath, String dllPath, String solutionName, AssemblyIsolationMode isolationMode, Boolean ignoreOutdatedAssembly)
   at DG.Daxif.Modules.Plugin.Main.syncSolution[a](FSharpFunc`2 proxyGen, String projectPath, String dllPath, String solutionName, AssemblyIsolationMode isolationMode, Boolean ignoreOutdatedAssembly, Boolean dryRun)
   at DG.Daxif.Plugin.Sync(Environment env, String assemblyPath, String projectPath, String solutionName, FSharpOption`1 dryRun, FSharpOption`1 isolationMode, FSharpOption`1 ignoreOutdatedAssembly, FSharpOption`1 logLevel
)
   at Build.<get_PushCustomizations>b__40_3() in C:\Users\XXX\build\Build.cs:line 180
   at Nuke.Common.Utilities.Collections.EnumerableExtensions.ForEach[T](IEnumerable`1 enumerable, Action`1 action)
   at Nuke.Common.Execution.BuildExecutor.Execute(NukeBuild build, ExecutableTarget target, IReadOnlyCollection`1 previouslyExecutedTargets, Boolean failureMode)

Expected behavior
I expect plugin dll to be deployed and plugin steps to be registered.

Environment

  • CRM/D365/CDS version: Online 9.2.22044.142
  • Tool version: 5.3.0 and up
  • Other applicable environments

Additional context
To be clear call DAXIF from C# using NUKE BUILD, like this:

    Target PushCustomizations => _ => _
        .Requires(() => SourceUrl != null)
        .Requires(() => Authentication)
        .DependsOn(Compile)
        .Executes(() =>
        {
            Log.Information("Sync Plugins");
            DG.Daxif.Plugin.Sync(
                env: SourceEnvironment,
                assemblyPath: SourceDirectory / "Plugins" / "bin" / Configuration / "net462" / $"{SolutionInfo.baseNamespace}.Plugins.dll",
                projectPath: SourceDirectory / "Plugins" / "Plugins.csproj",
                solutionName: SolutionInfo.name,
                dryRun: false,
                isolationMode: null,
                ignoreOutdatedAssembly: null,
                logLevel: null);
        }

SolutionExtract

Hey guys
Awesome work! I just tried out the sample scripts, which worked perfectly fine. Although when I start the "SolutionExtract.fsx" from the console, it does nothing and the console stays empty.
Did I miss something?
Thanks

Daxif 5.5.0 - WebResourceSync failing if many updates

WebResourceSync uses multiple service clients to sync web resources asynchronously and simultaneously.
The new 'useUniqueInstance' feature for GetServiceClient() in some cases with many updates provokes an authentication error due to too many simultaneous connections.

'useUniqueInstance' feature should default to 'false' to continue working as before. - This means that if a developer wants to connect to multiple environments in one script he/she must use GetServiceClient() with parameter 'useUniqueInstance' set to 'true'.

Problem Deploying CodeActivity when using a BaseClass

Current Behaviour

When deploying a workflow using a CodeActivity base class you get the following error.
Plug-in assembly does not contain the required types or assembly content cannot be updated.
There are no issues when using XRMToolBox.

Expected Behaviour

If I uses a BaseClass I would like to be able to deploy using the provided WorkflowSyncDev.fsx script. Ideally without the baseclass showing up in CRM.

Possible Solution

Maybe an extra attribute on the baseclass that tells delegate this is a baseclass and should not be registered?

Reproduction Steps

  1. Create a class that extends from the WorkflowBase class added to this issue
  2. Run the WorkflowSyncDev.fsx

Environment

CRM 2011 on-premise latest rollup
.NET 4.5.2 for both the scripts + the code activities

Detailed Description

Can be found in the files attached.
This error also show up when there is no logic inside of the Workflow.

WorkflowBase.txt
ErrorMessage.txt

When adding multiple custom APIs with same request/response parameter names it only registers the request/response parameters for one custom API

Describe the bug
When you have multiple Custom APIs and use the same request & response parameter names. It will only register the request & response parameters of one Custom API instead of all.

To Reproduce
See screenshots :)

Expected behavior
That all custom APIs have request & response parameters.

Screenshots
image
image

Very simplified example of the situation. In this case, only on our first (Async) the request parameters are added. on the other one, no request parameters are added.

Environment

  • CRM/D365/CDS version: 9.x
  • Tool version: 5.5.1

Additional context
I think the error is in the compare:

/// Compares a custom API requestparameter from CRM with one in source code

There is also a "TODO" compare more :) I think the "More" should be that it also compares on the "Custom API" the request/response parameter is linked to.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.