Modules/businessdev.ALbuild.Marketplace/Public/New-BcMarketplaceSubmission.ps1
|
function New-BcMarketplaceSubmission { <# .SYNOPSIS Uploads an app package and creates a Marketplace submission (Partner Center ingestion). .DESCRIPTION Uploads the app (and optional library apps) to the product's package collection and creates a submission. The package upload uses the ingestion API: POST /packages to obtain a blob upload URL, PUT the file to that URL, then POST /submissions to create the submission. The package resource type is supplied via -ResourceType so it is explicit (no hidden default). .PARAMETER AuthContext Auth context (Partner Center scope). .PARAMETER ProductId The product id. .PARAMETER AppFile The main .app file to submit. .PARAMETER LibraryAppFile Optional dependent/library .app files to include. .PARAMETER ResourceType The ingestion package resource type for BC extension packages. .OUTPUTS The created submission object. #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'ResourceType is consumed inside the package-upload script block (closure).')] [CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory)] [PSCustomObject] $AuthContext, [Parameter(Mandatory)] [string] $ProductId, [Parameter(Mandatory)] [string] $AppFile, [string[]] $LibraryAppFile = @(), [string] $ResourceType = 'Dynamics365BusinessCentralAddOnExtensionPackage' ) if (-not (Test-Path -LiteralPath $AppFile)) { throw "App file not found: '$AppFile'." } $cleanProductId = $ProductId -replace '^product/', '' $headers = @{ Authorization = "Bearer $($AuthContext.AccessToken)"; 'Content-Type' = 'application/json' } $baseUrl = "https://api.partner.microsoft.com/v1.0/ingestion/products/$cleanProductId" $uploadPackage = { param([string] $file) $body = @{ resourceType = $ResourceType; fileName = [System.IO.Path]::GetFileName($file) } | ConvertTo-Json $package = Invoke-RestMethod -Uri "$baseUrl/packages" -Method Post -Headers $headers -Body $body -ErrorAction Stop $sasUri = $package.fileSasUri if (-not $sasUri) { throw "Package upload for '$file' did not return an upload URL." } $bytes = [System.IO.File]::ReadAllBytes((Resolve-Path -LiteralPath $file).ProviderPath) Invoke-RestMethod -Uri $sasUri -Method Put -Headers @{ 'x-ms-blob-type' = 'BlockBlob' } -Body $bytes -ContentType 'application/octet-stream' -ErrorAction Stop | Out-Null Write-ALbuildLog "Uploaded package '$([System.IO.Path]::GetFileName($file))'." return $package } if (-not $PSCmdlet.ShouldProcess($cleanProductId, "Create submission for $(Split-Path $AppFile -Leaf)")) { return } & $uploadPackage $AppFile | Out-Null foreach ($lib in $LibraryAppFile) { & $uploadPackage $lib | Out-Null } $submission = Invoke-RestMethod -Uri "$baseUrl/submissions" -Method Post -Headers $headers -Body '{}' -ErrorAction Stop Write-ALbuildLog -Level Success "Created submission $($submission.id)." return $submission } |