daryllabar / DLaB.Xrm.XrmToolBoxTools

Plugins for the XrmToolBox
MIT License
78 stars 70 forks source link

Error while installing DLaB.Xrm.EarlyBoundGeneratorV2 through nuget #503

Closed otishone closed 5 months ago

otishone commented 5 months ago

Hi, I am trying to use the DLaB.Xrm.EarlyBoundGeneratorV2 via the pac and command line like described here:

https://github.com/daryllabar/DLaB.Xrm.XrmToolBoxTools/wiki/EBG-%E2%80%90-Integrating-The-Early-Bound-Generator-Into-Your-Build-Pipeline#running-via-the-command-line-pac

Currently we have a script that works correctly on version 2.2023.5.13 and Microsoft.PowerApps.CLI version 1.23.4. The script downloads a given version using nuget command line create the structure as described in the above article and runs the generator.

We tried to update script to use the latest version of the libraries but it fails with an error while installing the nuget with an error:

Attempting to resolve dependencies for package 'DLaB.Xrm.EarlyBoundGeneratorV2.2.2024.5.16' with DependencyBehavior 'Lowest'
Unable to resolve dependency 'XrmToolBox'. Source(s) used: 'nuget.org', 'AL.D365CRM', 'Microsoft Visual Studio Offline Packages', 'Local'.

I know that in the article it says to copy the tool from the XrmToolbox plugins folder, but is there any other way to automize it as we had?

The part of the script looks like this:

# download nuget
$sourceNugetExe = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe"
$targetNugetExe = "$scriptPath\tmp\nuget.exe"
$tmp = md $scriptPath\tmp
Invoke-WebRequest $sourceNugetExe -OutFile $targetNugetExe

# download PAC package
# At the moment there is problem with newer version of the CLI, until then we must wait for any update and use previous one
& $tmp\nuget install Microsoft.PowerApps.CLI -Version 1.23.4 -O $tmp
$pacFolder = Get-ChildItem $tmp | Where-Object { $_.Name -match 'Microsoft.PowerApps.CLI' }
Write-Verbose $pacFolder
move $tmp\$pacFolder\tools $toolPath

# download Early Bound Generator package
& $tmp\nuget install DLaB.Xrm.EarlyBoundGeneratorV2 -Version 2.2023.5.13 -O $tmp
$ebgFolder = Get-ChildItem $tmp | Where-Object { $_.Name -match 'DLaB.Xrm.EarlyBoundGeneratorV2' }
move $tmp\$ebgFolder\lib\net462\plugins\DLaB.EarlyBoundGeneratorV2 $toolPath\DLaB.EarlyBoundGeneratorV2

#Move extension DLL file
move $toolPath\DLaB.EarlyBoundGeneratorV2\DLaB.ModelBuilderExtensions.dll $toolPath\

# remove temp files
Remove-Item $tmp -Force -Recurse -ErrorAction Ignore
daryllabar commented 5 months ago

If you're running this as a part of a build pipeline, then you don't need the XTB dependences. In this case, try the API nuget file: https://www.nuget.org/packages/DLaB.Xrm.EarlyBoundGeneratorV2.Api

And if you have a script that works that you are willing to share, I'd love to post it in the docs.

otishone commented 5 months ago

Thanks for response, that worked for us.

We are using it for now not in the pipeline but as part of a command line that can be easily and quickly invoked. Second phase would be to add this to the pipeline, and rebuild context for all the projects.

It's a ps script that downloads everything get's the settings file and generates the model for a given project. We are using hardcoded versions in the script since there might be a situation that something in Microsoft comes up quicker that it is handled in the libraries, this way it is safer. The main script is as follows:

Param(
[Parameter(Mandatory)][string] $settingsFile,
[Parameter()][string] $appId,
[Parameter()][string] $secret,
[Parameter()][string] $outDirectory
)

$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
Write-Verbose "Script Path: $scriptPath"
$toolPath = $scriptPath + "\tool"

if (!$outDirectory) { $outDirectory = $scriptPath }

if (!$appId -Or !$secret) {
    Write-Host "Credentials not provided inline, reading from file."
    if ((Test-Path "$scriptPath\credentials.config") -eq $false){
        throw "Credentials config file missing. Create file based on the sample file and run the tool again."
    }

    $configJson = Get-Content ($scriptPath + "\credentials.config") -Raw | ConvertFrom-Json
    $appId = $configJson.appId
    $secret = $configJson.clientSecret

    Write-Host "Creadentials readed succesfully. Connecting as " + $appId
}

Write-Host "Configuration Applied from " + $settingsFile
Write-Host "Out Directory: " + $outDirectory

if ((Test-Path $settingsFile) -eq $false){
    throw "Settings file missing, default settings file missing as well."
}

if ((Test-Path "$toolPath\pac.exe") -eq $false) {
    # remove tool directory
    Remove-Item $toolPath -Force -Recurse -ErrorAction Ignore

    # download nuget
    $sourceNugetExe = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe"
    $targetNugetExe = "$scriptPath\tmp\nuget.exe"
    $tmp = md $scriptPath\tmp
    Invoke-WebRequest $sourceNugetExe -OutFile $targetNugetExe

    # download PAC package
    & $tmp\nuget install Microsoft.PowerApps.CLI -Version 1.32.8 -O $tmp
    $pacFolder = Get-ChildItem $tmp | Where-Object { $_.Name -match 'Microsoft.PowerApps.CLI' }
    Write-Verbose $pacFolder
    move $tmp\$pacFolder\tools $toolPath

    # download Early Bound Generator package
    & $tmp\nuget install DLaB.Xrm.EarlyBoundGeneratorV2.Api -Version 2.2024.5.16 -O $tmp
    $ebgFolder = Get-ChildItem $tmp | Where-Object { $_.Name -match 'DLaB.Xrm.EarlyBoundGeneratorV2' }
    move $tmp\$ebgFolder\lib\net48 $toolPath\DLaB.EarlyBoundGeneratorV2.API

    #Move extension DLL file
    move $toolPath\DLaB.EarlyBoundGeneratorV2.API\DLaB.ModelBuilderExtensions.dll $toolPath\

    # remove temp files
    Remove-Item $tmp -Force -Recurse -ErrorAction Ignore
}

$environmentId = 'ENVIRONMENT_URL'
$tenant = 'TENANT_ID'

& $toolPath\pac auth create --name EBGConnection --environment $environmentId --applicationId $appId --clientSecret $secret --tenant $tenant
& $toolPath\pac modelbuilder build --outdirectory $outdirectory --settingsTemplateFile $settingsFile

And then we are invoking it using a cmd command:

@echo off
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "./update-model.ps1 -outDirectory \"PROJECT_CONTEXT_FOLDER"" -settingsFile \"settings\SETTINGS_FILE.builderSettings.json\""