enosix.SfdxUtil.psm1
#Region './Private/checkResponse.ps1' 0 function checkResponse { process { Write-Verbose ($_ | ConvertTo-Json -Depth 10) if (0 -eq $_.status) { # Workaround for oddity that result is that sometimes an array with a single element if ($_.result -is [array]) { $_.result = $_.result[0] } return $_ } throwResponse "Failure Response" $_ } } #EndRegion './Private/checkResponse.ps1' 13 #Region './Private/throwResponse.ps1' 0 function throwResponse ($message, $response) { throw "${message}: $(${response}|ConvertTo-Json -Depth 10)" } #EndRegion './Private/throwResponse.ps1' 3 #Region './Public/00-sfdx.ps1' 0 # sfdx wrapper function $sfdxCmd = Get-Command sfdx | Where-Object { $_.CommandType -eq 'Application' } function sfdx { [CmdletBinding(SupportsShouldProcess = $true)] param( [Parameter(Mandatory = $false, ValueFromRemainingArguments = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, HelpMessage = "arguments for sfdx")] [String[]] $argsForSfdx ) if ($PSCmdlet.ShouldProcess("$sfdxCmd $argsForSfdx")) { Write-Verbose "Running: $sfdxCmd $argsForSfdx" $result = & $sfdxCmd @argsForSfdx Write-Verbose "Finished: $sfdxCmd $argsForSfdx" if ($LASTEXITCODE) { Write-Verbose "result: $result" throw "[sfdx exit code] $LASTEXITCODE" } return $result } } #EndRegion './Public/00-sfdx.ps1' 26 #Region './Public/Build-OctopusPackage.ps1' 0 function Build-OctopusPackage { [CmdletBinding(PositionalBinding = $false, SupportsShouldProcess = $true)] param ( [Parameter(ValueFromPipeline = $false)] [Alias("u")] [string]$githubUrl, [Parameter(ValueFromPipeline = $false)] [Alias("b")] [string]$pkgBranch, [Parameter(ValueFromPipeline = $false)] [Alias("s")] [Switch]$skipCodeCoverage, [Parameter(Mandatory = $true, ValueFromPipeline = $false)] [Alias("p")] [string[]] $packages, [Parameter(Mandatory = $true, ValueFromRemainingArguments)] [string[]] $items ) rm -rf "./out" mkdir "./out" if (Test-Path "./bin/deployment/Deploy.ps1" -Type Leaf) { cp "./bin/deployment/Deploy.ps1" "./out" } if (Test-Path "./bin/deployment/DeployFailed.ps1" -Type Leaf) { cp "./bin/deployment/DeployFailed.ps1" "./out" } if (Test-Path "./bin/deployment/PreDeploy.ps1" -Type Leaf) { cp "./bin/deployment/PreDeploy.ps1" "./out" } if (Test-Path "./bin/deployment/PostDeploy.ps1" -Type Leaf) { cp "./bin/deployment/PostDeploy.ps1" "./out" } if ($items -and $items.count -gt 0) { Copy-Item -Path $items -Destination "./out" -Recurse } $work = Get-Location Set-Location "./out/" $packageDetail = ConvertTo-Json @($packages | ForEach-Object { $report = sfdx force:package:version:report --package $_ --verbose --json | ConvertFrom-Json if (!$skipCodeCoverage -and !$report.result.HasPassedCodeCoverageCheck) { throw "Code Coverage Failed: " + ($report.result.CodeCoverage | ConvertTo-Json) } return $report.result | Select-Object -Property @{ l = "Id"; e = { $_.SubscriberPackageVersionId } }, Package2Id, Tag, Branch, AncestorId, Version, AncestorVersion }) Write-Output @" { "GitHub": "$githubUrl", "Branch": "$pkgBranch", "Packages": $packageDetail } "@ > "./out/package.json" Set-Location $work } #EndRegion './Public/Build-OctopusPackage.ps1' 76 #Region './Public/Build-SFPackage.ps1' 0 function Build-SFPackage { [CmdletBinding(PositionalBinding = $false, SupportsShouldProcess = $true)] param ( [Parameter(Mandatory = $true, Position = 0)] [string] $path, [Alias("t")] [string]$pkgTag, [Alias("b")] [string]$pkgBranch, [Alias("v")] [string]$pkgVersionName, [Alias("r")] [string]$reqId, [Parameter(Mandatory = $true)] [Alias("p")] [string]$pkgPath, [Alias("w")] [int] $wait ) $path = Resolve-Path -Path $path $work = Get-Location Set-Location "$path" $result = $null if (-Not$pkgVersionName) { $pkgVersionName = $pkgBranch } if (-Not$pkgTag) { $pkgTag = $pkgVersionName } if (-Not$reqId) { $sgpId = Get-2GPId "$path/sfdx-project.json" -p $pkgPath Write-Output "::set-output name=sgp_id::$sgpId" $reqId = Create-Package $sgpId -t $pkgTag -b $pkgBranch -v $pkgVersionName } if ($wait) { $waitUntil = $((Get-Date).AddMinutes($wait) ).Ticks while ($null -eq $result -and ((Get-Date).Ticks -lt $waitUntil)) { try { $result = Get-SubscriberPackageVersionId $reqId } catch [System.Threading.Tasks.TaskCanceledException] { $reqId = Create-Package $sgpId -t $pkgTag -b $pkgBranch -v $pkgVersionName } Start-Sleep -Seconds 20 } if (-not$result) { throw "Timeout" } $version = Get-PackageVersionId $result Write-Output "::set-output name=package_version::$version" Write-Output "::set-output name=package_id::$result" } Write-Output "::set-output name=request_id::$reqId" Set-Location $work } #EndRegion './Public/Build-SFPackage.ps1' 79 #Region './Public/Create-Package.ps1' 0 function Create-Package { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string]$pkgId, [Alias("t")] [string]$pkgTag = "develop", [Alias("b")] [string]$pkgBranch, [Alias("v")] [string]$pkgVersionName ) $retry = $true while ($retry) { $createRequest = sfdx force:package:version:create --installationkeybypass --codecoverage --package $pkgId --tag $pkgTag --branch $pkgBranch --versionname $pkgVersionName --json | ConvertFrom-Json -AsHashtable | checkResponse $retry = $false # Package has only "try again" errors? if (("Error" -eq $createRequest.result.Status)) { if ($createRequest.result.Error) { $nonTryAgainErrors = $createRequest.result.Error | Where-Object { $_ -notlike "*try again*" } if ($nonTryAgainErrors) { throwResponse "Has unrecoverable errors" $createRequest } else { # Try Again $retry = $true } } else { throwResponse "Error with no detail" $createRequest } } } $createRequest.result.Id } #EndRegion './Public/Create-Package.ps1' 42 #Region './Public/Create-ScratchOrg.ps1' 0 function Create-ScratchOrg { [CmdletBinding()] param( [string]$file, [Alias("a")] [string]$alias, [Alias("d")] [int]$duration = 7 ) if ($alias){ sfdx force:org:create --definitionfile $file --setdefaultusername --setalias $alias --durationdays $duration }else{ sfdx force:org:create --definitionfile $file --setdefaultusername --durationdays $duration } } #EndRegion './Public/Create-ScratchOrg.ps1' 20 #Region './Public/Delete-ScratchOrg.ps1' 0 function Delete-ScratchOrg { [CmdletBinding()] param( $alias ) sfdx force:org:delete --noprompt --targetusername $alias } #EndRegion './Public/Delete-ScratchOrg.ps1' 6 #Region './Public/Get-2GPId.ps1' 0 function Get-2GPId { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string]$projFile, [Alias("p")] [string]$pkgPath ) $pkgList = ( Get-Content -Path $projFile | ConvertFrom-Json ).packageDirectories if ($pkgPath) { $pkgList = $pkgList | Where-Object { $_.path -eq $pkgPath } } $pkg = $pkgList | Select-Object -Last 1 if (-Not $pkg) { throw "ERROR: Unable to find package with path `"$pkgPath`" in `"$projFile`"." } if (-Not $pkg.package) { throw "ERROR: No 2gp ID for package with path `"$pkgPath`" in `"$projFile`"." } $pkg.package } #EndRegion './Public/Get-2GPId.ps1' 26 #Region './Public/Get-PackageVersionId.ps1' 0 function Get-PackageVersionId { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string]$pkgId ) $request = sfdx force:package:version:report --package $pkgId --json | ConvertFrom-Json if ($request.result.Version) { return $request.result.Version } return $null } #EndRegion './Public/Get-PackageVersionId.ps1' 17 #Region './Public/Get-SubscriberPackageVersionId.ps1' 0 function Get-SubscriberPackageVersionId { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string]$pkgId, [Alias("t")] [string]$pkgTag, [Alias("b")] [string]$pkgBranch ) $pkgList = (sfdx force:package:version:list --json --verbose --packages $pkgId --orderby CreatedDate | ConvertFrom-Json).result if ($pkgTag) { $pkgList = $pkgList | Where-Object { $_.Tag -eq $pkgTag } } if ($pkgBranch) { $pkgList = $pkgList | Where-Object { $_.Branch -eq $pkgBranch } } $pkg = $($pkgList | Select-Object -Last 1) if ($pkg) { return $pkg.SubscriberPackageVersionId }else{ return $null } } #EndRegion './Public/Get-SubscriberPackageVersionId.ps1' 31 #Region './Public/Get-SubscriberPackageVersionIdFromRequest.ps1' 0 function Get-SubscriberPackageVersionIdFromRequest { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string]$requestId ) $request = sfdx force:package:version:create:report --packagecreaterequestid $requestId --json | ConvertFrom-Json -AsHashtable | checkResponse if ($request.result.SubscriberPackageVersionId) { return $request.result.SubscriberPackageVersionId } # Package has only "try again" errors? if (("Error" -eq $request.result.Status)) { if ($request.result.Error) { $nonTryAgainErrors = $request.result.Error | Where-Object { $_ -notlike "*try again*" -and $_ -notlike "*unexpected error*" -and $_ -notlike "*Internal Salesforce Error*" } if ($nonTryAgainErrors) { throwResponse "Has unrecoverable errors" $request } else{ throw [System.Threading.Tasks.TaskCanceledException]::New('Has recoverable errors. Please try again.') } } else { throwResponse "Error with no detail" $request } } #TODO: Log this #$errors = sfdx force:data:soql:query -u devhub -t -q ("SELECT Message FROM Package2VersionCreateRequestError WHERE ParentRequest.Id in ({0}{1}{0})" -f [char]39, $createRequest.result.Id) return $null } #EndRegion './Public/Get-SubscriberPackageVersionIdFromRequest.ps1' 34 #Region './Public/Grant-PermSet.ps1' 0 function Grant-PermSet { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string]$permSet ) sfdx force:user:permset:assign --permsetname $permSet } #EndRegion './Public/Grant-PermSet.ps1' 9 #Region './Public/Import-DataPlan.ps1' 0 function Import-DataPlan { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string]$file ) sfdx force:data:tree:import --plan $file } #EndRegion './Public/Import-DataPlan.ps1' 9 #Region './Public/Import-Record.ps1' 0 function Import-Record { [CmdletBinding()] param( [Alias("k")] [string]$key, [Alias("v")] [string]$value ) sfdx force:data:record:create --sobjecttype $key --values $value } #EndRegion './Public/Import-Record.ps1' 12 #Region './Public/Import-Records.ps1' 0 function Import-Records { [CmdletBinding()] param( $file ) $records = [ordered]@{} (Get-Content $file | ConvertFrom-Json).psobject.properties | ForEach-Object { $records[$_.Name] = $_.Value } #$records | Write-Output foreach ($recordType in $records.Keys) { #$recordType | Write-Output $entries = $records[$recordType] foreach ($record in $entries) { $values = @{} $record.psobject.properties | ForEach-Object { $values[$_.Name] = $_.Value } $valuesString = [system.String]::Join(" ", ($values.GetEnumerator() | % { If ($_.Value.GetType() -eq [String]) { "$($_.Name)='$($_.Value)'" } elseif ($_.Value.GetType() -eq [bool]) { "$($_.Name)=$($_.Value.ToString().ToLowerInvariant())" } Else { "$($_.Name)=$($_.Value)" } }) ) #$valuesString | Write-Output sfdx force:data:record:create --sobjecttype $recordType --values "`"$valuesString`"" } } } #EndRegion './Public/Import-Records.ps1' 38 #Region './Public/Install-FromJson.ps1' 0 function Install-FromJson { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string]$path, [Alias("s")] [string[]] $skip , [Alias("w")] [int]$wait = 30 ) $pkg = Get-Content $path | ConvertFrom-Json -AsHashtable; foreach($item in $pkg.Packages) { if (!$skip -or (!$skip.Contains($item.Package2Id) -and !$skip.Contains($item.Id))) { Install-Package $item.Id -w $wait } } Write-Output (Get-Content $path) } #EndRegion './Public/Install-FromJson.ps1' 23 #Region './Public/Install-Package.ps1' 0 function Install-Package { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string]$package, [Alias("w")] [int]$wait = 30 ) sfdx force:package:install --package $package --wait $wait --publishwait $wait --json | ConvertFrom-Json -outVariable results Write-Output $results } #EndRegion './Public/Install-Package.ps1' 14 #Region './Public/Invoke-Step.ps1' 0 function Invoke-Step ( [Parameter(Mandatory = $true)] [string]$stepName, [Parameter(Mandatory = $true)] [scriptblock]$action ) { $stepsFile = ".completed-steps.json" $steps = @() if (Test-Path $stepsFile -PathType Leaf) { $steps = Get-Content -Raw -Path $stepsFile | ConvertFrom-Json -NoEnumerate } if ($steps.Contains($stepName)) { Write-Debug "Skipping step $stepName" } else { Write-Debug "Running step $stepName" try { $result = & $action } catch { throw $_.Exception } $steps += $stepName; } $steps | ConvertTo-Json -AsArray | Set-Content -Path $stepsFile return $result; } #EndRegion './Public/Invoke-Step.ps1' 30 #Region './Public/Push-Source.ps1' 0 function Push-Source { sfdx force:source:push } #EndRegion './Public/Push-Source.ps1' 3 #Region './Public/Rebuild-ScratchOrg.ps1' 0 function Rebuild-ScratchOrg { [CmdletBinding(PositionalBinding = $false, SupportsShouldProcess = $true)] param ( # Flag -a, -setalias set an sfdx alias for for the created scratch org [Parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, HelpMessage = "set an sfdx alias for for the created scratch org")] [Alias("a")] [string] $SetAlias, [Parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, HelpMessage = "set sfdx wait time in minutes")] [Alias("w")] [int] $Wait = 60, [Parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, HelpMessage = "path to rebuild-scratch-org configuration file - defaults to ./rebuild-scratch-org.json or {project-root}/config/rebuild-scratch-org-default.json")] [Alias("f")] [string] $RebuildScratchOrgConfigFile, # Flag -o, -open opens the scratch org when its complete [Parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, HelpMessage = "open the scratch org when its complete")] [Alias("o")] [switch] $Open, [Parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, HelpMessage = "open the scratch org when its complete to this navigation URL path")] [Alias("p")] [string] $OpenUrlPath, [Parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, HelpMessage = "duration of the scratch org (in days) (default:7, min:1, max:30)")] [Alias("d")] [String] $DurationDays, [Parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, HelpMessage = "username or alias for the dev hub org; overrides default dev hub org")] [Alias("v")] [String] $TargetDevhubUsername, [Parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, HelpMessage = "request release=Preview scratch org")] [Alias("r")] [switch] $PreviewReleaseScratchOrg, [Parameter(Mandatory = $false, ValueFromRemainingArguments = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, HelpMessage = "Package Ids to install (04t)")] [String[]] $PackageIds ) # "strict mode" best practice Set-StrictMode -Version Latest $ErrorActionPreference = "Stop" $VerbosePreference = "Continue" # Load configuration if (-Not$RebuildScratchOrgConfigFile) { if (Test-Path "./rebuild-scratch-org.json") { $RebuildScratchOrgConfigFile = "./rebuild-scratch-org.json" } else { $RebuildScratchOrgConfigFile = "$PSScriptRoot/../config/rebuild-scratch-org-default.json" } } $Config = @{ } Write-Verbose "Attempting to read rebuild-scratch-org configuration: $RebuildScratchOrgConfigFile" if (Test-Path $RebuildScratchOrgConfigFile) { (Get-Content $RebuildScratchOrgConfigFile | ConvertFrom-Json).psobject.properties | ForEach-Object { $Config[$_.Name] = $_.Value } $ConfigFolderPath = Split-Path -Parent (Resolve-Path $RebuildScratchOrgConfigFile) } else { Write-Verbose "Unable to read $RebuildScratchOrgConfigFile" } $ScratchOrgDefinitionFile = "$PSScriptRoot/../config/project-scratch-def.json" if ( $Config.ContainsKey("ScratchOrgDefinitionFile")) { $ScratchOrgDefinitionFile = Join-Path -Resolve $ConfigFolderPath $Config.ScratchOrgDefinitionFile } $ScratchOrgDefinitionFile = (Resolve-Path $ScratchOrgDefinitionFile).Path $DataRecordCreate = @{ } if ( $Config.ContainsKey("DataRecordCreate")) { $Config.DataRecordCreate.psobject.properties | ForEach-Object { $DataRecordCreate[$_.Name] = $_.Value } } $PermSets = @() if ( $Config.ContainsKey("PermSets")) { $PermSets = $Config.PermSets } $DataPlans = @() if ( $Config.ContainsKey("DataPlans")) { $DataPlans = $Config.DataPlans | ForEach-Object { Join-Path -Resolve $ConfigFolderPath $_ } } $AnonApexFiles = @() if ( $Config.ContainsKey("AnonApexFiles")) { $AnonApexFiles = $Config.AnonApexFiles | ForEach-Object { Join-Path -Resolve $ConfigFolderPath $_ } } $MdapiDeployBeforeSfdxSource = @() if ( $Config.ContainsKey("MdapiDeployBeforeSfdxSource")) { $MdapiDeployBeforeSfdxSource = $Config.MdapiDeployBeforeSfdxSource } $MdapiDeployAfterSfdxSource = @() if ( $Config.ContainsKey("MdapiDeployAfterSfdxSource")) { $MdapiDeployAfterSfdxSource = $Config.MdapiDeployAfterSfdxSource } # Only obtain PackageIds from config file when none are specified on the command line if (-Not$PackageIds) { if ( $Config.ContainsKey("PackageIds")) { $PackageIds = $Config.PackageIds } } # Validate params if ($PackageIds) { $InvalidPackageIds = $PackageIds | ForEach-Object { @($_ -split ':')[0] } | Where-Object { -not($_.StartsWith('04t') -and (@(15, 18) -contains $_.Length)) } if ($InvalidPackageIds) { throw "ERROR: Unrecognized Package Ids [$InvalidPackageIds] must begin with 04t and have a length of 15 or 18 characters." } } # sfdx wrapper function $sfdxCmd = Get-Command sfdx | Where-Object { $_.CommandType -eq 'Application' } function sfdx { [CmdletBinding(SupportsShouldProcess = $true)] param( [Parameter(Mandatory = $false, ValueFromRemainingArguments = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, HelpMessage = "arguments for sfdx")] [String[]] $argsForSfdx ) if ( $PSCmdlet.ShouldProcess("$sfdxCmd $argsForSfdx")) { Write-Verbose "Running: $sfdxCmd $argsForSfdx" & $sfdxCmd @argsForSfdx Write-Verbose "Finished: $sfdxCmd $argsForSfdx" if ($LASTEXITCODE) { throw "[sfdx exit code] $LASTEXITCODE" } } } # Spin up fresh scratch org if ($ScratchOrgDefinitionFile) { $sfdxArgs = @('--wait', $Wait, '--definitionfile', $ScratchOrgDefinitionFile, '--setdefaultusername') if ($SetAlias) { $sfdxArgs += @("description=$SetAlias", '--setalias', $SetAlias) } if ($DurationDays) { $sfdxArgs += @('--durationdays', $DurationDays) } if ($TargetDevhubUsername) { $sfdxArgs += @('--targetdevhubusername', $TargetDevhubUsername) } if ($PreviewReleaseScratchOrg) { $sfdxArgs += @('release=Preview') } sfdx force:org:create @sfdxArgs } # Install packages if ($PackageIds) { $PackageIds | ForEach-Object { $id, $key = $_ -split ':' $sfdxArgs = @('--noprompt', '--publishwait', $Wait, '--wait', $Wait, '--package', $id) if ($key) { $key = $key -join ':' $sfdxArgs += @('--installationkey', $key) } sfdx force:package:install @sfdxArgs } # "sfdx force:package:installed:list" caused build flakiness with non-overridable 2-minute # timeout with message: "ERROR: Your query request was running for too long." # Might be able to re-enable if it gains support for a "--wait" parameter ## Display installed package versions #sfdx force:package:installed:list } # Push mdapi source if ($MdapiDeployBeforeSfdxSource) { $MdapiDeployBeforeSfdxSource | ForEach-Object { sfdx force:mdapi:deploy --wait $Wait --deploydir $_ } } # Push sfdx source sfdx force:source:push --forceoverwrite # Push mdapi source if ($MdapiDeployAfterSfdxSource) { $MdapiDeployAfterSfdxSource | ForEach-Object { sfdx force:mdapi:deploy --wait $Wait --deploydir $_ } } # Configure logging and connection settings if ($DataRecordCreate) { $DataRecordCreate.Keys | Sort-Object | ForEach-Object { sfdx force:data:record:create --sobjecttype $_ --values $DataRecordCreate[$_] } } # Assign permission sets per your development / testing needs if ($PermSets) { $PermSets | ForEach-Object { sfdx force:user:permset:assign --permsetname $_ } } # Load sample data (Accounts, Wearables Products, a Wearables Price Book, and Pricebook Entries) # that corresponds to the `enosix_sap_*` SAP connections. if ($DataPlans) { $DataPlans | ForEach-Object { sfdx force:data:tree:import --plan $_ } } if ($AnonApexFiles) { $AnonApexFiles | ForEach-Object { sfdx force:apex:execute --apexcodefile $_ } } if ($OpenUrlPath) { sfdx force:org:open --path $OpenUrlPath } elseif ($Open) { sfdx force:org:open } Write-Verbose "$SetAlias Scratch org spin cycle complete!" } #EndRegion './Public/Rebuild-ScratchOrg.ps1' 307 #Region './Public/Run-Tests.ps1' 0 function Run-Tests { [CmdletBinding()] param( [bool]$throwIfFailed = $false ) sfdx force:apex:test:run --wait "$WAIT" --resultformat json | ConvertFrom-Json -outVariable testResults If ($testResults.result.summary.failing -gt 0 -And $throwIfFailed) { throw "Failed tests: $($testResults.result.summary.failing)" } $testResults } #EndRegion './Public/Run-Tests.ps1' 12 #Region './Public/Sort-CustomLabels.ps1' 0 function Sort-CustomLabels { param ( $customLabelsPath ) # "strict mode" best practice Set-StrictMode -Version Latest $ErrorActionPreference = "Stop" # Set a default value for $customLabelsPath if it was not passed in as parameter on the command line if (-Not$customLabelsPath) { $projectRoot = (Resolve-Path -LiteralPath "$PSScriptRoot/..").Path $customLabelsPath = "$projectRoot/ensxapp/force-app/main/default/labels/CustomLabels.labels-meta.xml" } if (-Not(Test-Path $customLabelsPath)) { throw "CustomLabels file does not exist: $customLabelsPath" } # Load CustomLabels xml, uniquely sort nodes by fullName, and save $xmlDoc = [xml](Get-Content $customLabelsPath) $xmlDoc.CustomLabels.labels | ForEach-Object { $null = $xmlDoc.CustomLabels.RemoveChild($_) Write-Output $_ } | Sort-Object -Unique { $_.fullName } | ForEach-Object { $null = $xmlDoc.CustomLabels.AppendChild($_) } $xmlDoc.Save($customLabelsPath) "Sorting complete: $customLabelsPath" } #EndRegion './Public/Sort-CustomLabels.ps1' 32 #Region './Public/Update-Package.ps1' 0 function Update-Package { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string]$pkgId, [Alias("t")] [string]$pkgTag = "develop", [Alias("b")] [string]$pkgBranch, [Alias("v")] [string]$pkgVersionName ) sfdx force:package:version:update --installationkeybypass --package $pkgId --tag $pkgTag --branch $pkgBranch --versionname $pkgVersionName --json | ConvertFrom-Json } #EndRegion './Public/Update-Package.ps1' 19 |