Closed Arthurvdv closed 11 months ago
We will look into the API's from Partner Center, but relying on undocumented, unsupported, ever-changing powershell scripts from 1 guy, is something that has failed on us more than once :(.
We can't seem to find the API documentation for AppSource submission - if you have any references, that would be really helpful.
While I can understand your restraint, I think we both can agree on that it would be awesome if ALOps could support this.
There is a Swagger file over here: https://ingestionapi-swagger.azureedge.net.
In the podcast Window on Technology - Freddy Kristiansen - CI/CD and Containers Freddy explains that the frontend of Partner Center also uses this ingestion API als backend. He contacted the team that created the API, figured out how the API works and implemented this in the BcContainerHelper.
We could reach out to Freddy or reverse engineer the API-calls from the BcContainerHelper?
I would be in favor of option 2 (ALOps providing a wrapper around BCCH). I'd suppose MS would also use the BCCH commandlets to improve their own AL-Go on github, so seems logic that ALOps would build further on top of these commands so we can close the last gap for automated AppSource releases ;)
For now we've decided to use the BcContainerHelper with some PowerShell scripting to implement this feature.
I'm not a PowerShell-guru, but tried to make the code als readable as possible. There are some assumptions in the example below, so can't guarantee this wil work for everybody. Also there are some custom steps above that grabs all the dependency apps from our Azure DevOps Artifacts Feed and places these in the subfolder Library.
We decided that the Alias (in the Offer Setup) needs to match with the name in the App.json to prevent a mapping table somewhere between the AppId and the OfferId from the Marketplace (and needs to be unique). If there's a better way of handeling this I would love to know.
Posting it here to share with the community!
- task: PowerShell@2
displayName: 'New AppSource Submission'
condition: succeeded()
env:
BUILD_BINARIESDIRECTORY: $(Build.BinariesDirectory)
inputs:
targetType: 'inline'
script: |
Import-Module 'D365BCAppHelper'
Import-Module 'BcContainerHelper'
$appFile = Get-ChildItem -Path $env:BUILD_BINARIESDIRECTORY -Depth 0 -Filter *.app | Select-Object -First 1 | % { $_.FullName }
if (!(Test-Path $appFile)) {
throw "Unable to find $appFile"
}
Write-Host "Extracting App manifest from $appFile"
$xmlManifest = Get-D365BCManifestFromAppFile -Filename $appFile
Write-Host "**************************************"
Write-Host "$($spaces)* App File = [$($appFile)]"
Write-Host "$($spaces)"
Write-Host "$($spaces)* App.ID = $($xmlManifest.App.Id)"
Write-Host "$($spaces)* App.Name = $($xmlManifest.App.Name)"
Write-Host "$($spaces)* App.Publisher = $($xmlManifest.App.Publisher)"
Write-Host "$($spaces)* App.Version = $($xmlManifest.App.Version)"
Write-Host "$($spaces)"
Write-Host "$($spaces)"
Write-Host "Search for '$($xmlManifest.App.Name)' in Marketplace offers on Microsoft Partner Center"
$authcontext = New-BcAuthContext `
-clientID $clientId `
-clientSecret $clientSecret `
-tenantID $tenantId `
-scopes 'https://api.partner.microsoft.com/.default'
$products = Get-AppSourceProduct -authContext $authcontext -silent
$product = ($products | Where-Object { $_.name -eq "$($xmlManifest.App.Name)" -and $_.resourceType -eq 'AzureDynamics365BusinessCentral' })
if ($null -eq $product) {
throw "No Marketplace offer with the name '$($xmlManifest.App.Name)' found on Microsoft Partner Center."
}
else {
Write-Host "Found marketplace offer id '$($product.Id)' for App '$($xmlManifest.App.Name)'"
}
$appHasLibraryApps = $false
$libraryAppsFolder = Join-Path $env:BUILD_BINARIESDIRECTORY 'Library'
if (Test-Path $libraryAppsFolder) {
$apps = Get-ChildItem -Path $libraryAppsFolder -Filter *.app -Recurse
if ($apps.Count -ne 0) {
$appHasLibraryApps = $true
}
$libraryAppFiles = @()
$apps | % { $libraryAppFiles += $($_.FullName) }
}
if ($appHasLibraryApps) {
# App with Library apps
Write-Host "New-AppSourceSubmission -authContext $authcontext -productId $($product.Id) -appFile $appFile -libraryAppFiles $libraryAppFiles -autoPromote -doNotWait"
New-AppSourceSubmission -authContext $authcontext -productId $($product.Id) -appFile $appFile -libraryAppFiles $libraryAppFiles -autoPromote -doNotWait
}
else {
# App without Library apps
Write-Host "New-AppSourceSubmission -authContext $authcontext -productId $($product.Id) -appFile $appFile -autoPromote -doNotWait"
New-AppSourceSubmission -authContext $authcontext -productId $($product.Id) -appFile $appFile -autoPromote -doNotWait
}
Thanks for this.
We'll look into the Swagger and see what we can do from there!
@waldo1001 Any progress in this
In fact - we finally have a working prototype.. . Good things are coming ..
The provided information in this post was very helpful. Thanks so much.
Hi @waldo1001, Just curious, what's the status of this ticket? I had to do a submission today.
We're testing the first alfa version of this on our own AppSource apps .. so we're finalizing...
@waldo1001 are we now in beta test ?
We tested it, it failed (minimal changes) - and we're about to re-test - so yes, we're in beta. Almost there...
Good news: AppSource update is coming to the next version.
Version 4.0.0 of the BcContainerHelper comes with a set of functions to automate the release to AppSource process.
What is the best approach for us as ALOps customer?