Automate Store Publishing (#25725)
@@ -25,6 +25,10 @@ parameters: # parameters are shown up in ADO UI in a build queue time
|
||||
displayName: Skip Copying Archives and Installers to PSInfrastructure Public Location
|
||||
type: boolean
|
||||
default: false
|
||||
- name: skipMSIXPublish
|
||||
displayName: Skip MSIX Publish
|
||||
type: boolean
|
||||
default: false
|
||||
- name: OfficialBuild
|
||||
type: boolean
|
||||
default: false
|
||||
@@ -363,13 +367,12 @@ extends:
|
||||
- stage: PublishMsix
|
||||
dependsOn: PushGitTagAndMakeDraftPublic
|
||||
displayName: Publish MSIX to store
|
||||
variables:
|
||||
ob_release_environment: Production
|
||||
jobs:
|
||||
- template: /.pipelines/templates/approvalJob.yml@self
|
||||
- template: /.pipelines/templates/release-MSIX-Publish.yml@self
|
||||
parameters:
|
||||
displayName: Publish the MSIX Bundle package to store
|
||||
jobName: PublishMsix
|
||||
instructions: |
|
||||
Ask Steve to release MSIX bundle package to Store
|
||||
skipMSIXPublish: ${{ parameters.skipMSIXPublish }}
|
||||
|
||||
- stage: PublishVPack
|
||||
dependsOn: PushGitTagAndMakeDraftPublic
|
||||
|
BIN
.pipelines/store/PDP/PDP-Media/en-US/Error.png
Normal file
After Width: | Height: | Size: 118 KiB |
BIN
.pipelines/store/PDP/PDP-Media/en-US/Experimental_Features.png
Normal file
After Width: | Height: | Size: 158 KiB |
BIN
.pipelines/store/PDP/PDP-Media/en-US/Feedback_Provider.png
Normal file
After Width: | Height: | Size: 163 KiB |
BIN
.pipelines/store/PDP/PDP-Media/en-US/Predictor_Inline.png
Normal file
After Width: | Height: | Size: 108 KiB |
BIN
.pipelines/store/PDP/PDP-Media/en-US/Predictor_ListView.png
Normal file
After Width: | Height: | Size: 143 KiB |
BIN
.pipelines/store/PDP/PDP-Media/en-US/Prompt.png
Normal file
After Width: | Height: | Size: 130 KiB |
BIN
.pipelines/store/PDP/PDP-Media/en-US/Stable_Release.png
Normal file
After Width: | Height: | Size: 175 KiB |
BIN
.pipelines/store/PDP/PDP-Media/en-US/pwshLogo.png
Normal file
After Width: | Height: | Size: 13 KiB |
176
.pipelines/store/PDP/PDP/en-US/PDP.xml
Normal file
@@ -0,0 +1,176 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ProductDescription language="en-us" xmlns="http://schemas.microsoft.com/appx/2012/ProductDescription" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xml:lang="en-us" Release="">
|
||||
<AppStoreName _locID="PowerShell-Private">
|
||||
<!-- This is optional. AppStoreName is typically extracted from your package's AppxManifest DisplayName property. -->
|
||||
<!-- Uncomment (and localize) this Store name if your application package does not contain a localization for the DisplayName in this language. -->
|
||||
<!-- Leaving this uncommented for a language that your application package DOES contain a DisplayName for will result in a submission failure with the API. -->
|
||||
<!-- _locComment_text="{MaxLength=200} App AppStoreName" -->
|
||||
<!-- Dev Home -->
|
||||
</AppStoreName>
|
||||
<Keywords>
|
||||
<!-- Valid length: 30 character limit, up to 7 elements -->
|
||||
<Keyword _locID="App_keyword1">
|
||||
<!-- _locComment_text="{MaxLength=30} App keyword 1" -->Shell</Keyword>
|
||||
<Keyword _locID="App_keyword2">
|
||||
<!-- _locComment_text="{MaxLength=30} App keyword 2" -->PowerShell</Keyword>
|
||||
<Keyword _locID="App_keyword3">
|
||||
<!-- _locComment_text="{MaxLength=30} App keyword 3" -->Terminal</Keyword>
|
||||
<Keyword _locID="App_keyword4">
|
||||
<!-- _locComment_text="{MaxLength=30} App keyword 4" -->Command Line</Keyword>
|
||||
<Keyword _locID="App_keyword5">
|
||||
<!-- _locComment_text="{MaxLength=30} App keyword 5" -->Automation</Keyword>
|
||||
<Keyword _locID="App_keyword6">
|
||||
<!-- _locComment_text="{MaxLength=30} App keyword 6" -->Task Automation</Keyword>
|
||||
<Keyword _locID="App_keyword7">
|
||||
<!-- _locComment_text="{MaxLength=30} App keyword 7" -->Scripting</Keyword>
|
||||
</Keywords>
|
||||
<Description _locID="App_Description">
|
||||
<!-- _locComment_text="{MaxLength=10000} {Locked=Windows} App Description" -->PowerShell is a task-based command-line shell and scripting language built on .NET. PowerShell helps system administrators and power-users rapidly automate task that manage operating systems (Linux, macOS, and Windows) and processes.
|
||||
|
||||
PowerShell commands let you manage computers from the command line. PowerShell providers let you access data stores, such as the registry and certificate store, as easily as you access the file system. PowerShell includes a rich expression parser and a fully developed scripting language.
|
||||
|
||||
PowerShell is Open Source. See https://github.com/powershell/powershell </Description>
|
||||
<ShortDescription _locID="App_ShortDescription">
|
||||
<!-- Only used for games. This description appears in the Information section of the Game Hub on Xbox One, and helps customers understand more about your game. -->
|
||||
<!-- _locComment_text="{MaxLength=500} App ShortDescription" -->
|
||||
</ShortDescription>
|
||||
<ShortTitle _locID="App_ShortTitle">
|
||||
<!-- A shorter version of your product's name. If provided, this shorter name may appear in various places on Xbox One (during installation, in Achievements, etc.) in place of the full title of your product. -->
|
||||
<!-- _locComment_text="{MaxLength=50} App ShortTitle" -->
|
||||
</ShortTitle>
|
||||
<SortTitle _locID="App_SortTitle">
|
||||
<!-- If your product could be alphabetized in different ways, you can enter another version here. This may help customers find the product more quickly when searching. -->
|
||||
<!-- _locComment_text="{MaxLength=255} App SortTitle" -->
|
||||
</SortTitle>
|
||||
<VoiceTitle _locID="App_VoiceTitle">
|
||||
<!-- An alternate name for your product that, if provided, may be used in the audio experience on Xbox One when using Kinect or a headset. -->
|
||||
<!-- _locComment_text="{MaxLength=255} App VoiceTitle" -->
|
||||
</VoiceTitle>
|
||||
<DevStudio _locID="App_DevStudio">
|
||||
<!-- Specify this value if you want to include a "Developed by" field in the listing. (The "Published by" field will list the publisher display name associated with your account, whether or not you provide a devStudio value.) -->
|
||||
<!-- _locComment_text="{MaxLength=255} App DevStudio" -->
|
||||
</DevStudio>
|
||||
<ReleaseNotes _locID="App_ReleaseNotes">
|
||||
<!-- _locComment_text="{MaxLength=1500} {Locked=__VERSION_NUMBER__} App Release Note" -->Please see our GitHub releases page for additional details.</ReleaseNotes>
|
||||
<ScreenshotCaptions>
|
||||
<!-- Valid length: 200 character limit, up to 9 elements per platform -->
|
||||
<!-- Valid attributes: any of DesktopImage, MobileImage, XboxImage, SurfaceHubImage, and HoloLensImage -->
|
||||
<Caption DesktopImage="Prompt.png" _locID="App_caption1">
|
||||
<!-- _locComment_text="{MaxLength=200} Screenshot caption 1" -->
|
||||
Prompt
|
||||
</Caption>
|
||||
<Caption DesktopImage="Predictor_Inline.png" _locID="App_caption2">
|
||||
<!-- _locComment_text="{MaxLength=200} Screenshot caption 2" -->
|
||||
Inline Prediction
|
||||
</Caption>
|
||||
<Caption DesktopImage="Predictor_ListView.png" _locID="App_caption3">
|
||||
<!-- _locComment_text="{MaxLength=200} Screenshot caption 3" -->
|
||||
Prediction List View
|
||||
</Caption>
|
||||
<Caption DesktopImage="Error.png" _locID="App_caption4">
|
||||
<!-- _locComment_text="{MaxLength=200} Screenshot caption 4" -->
|
||||
Error Feedback Provider
|
||||
</Caption>
|
||||
<Caption DesktopImage="Feedback_Provider.png" _locID="App_caption5">
|
||||
<!-- _locComment_text="{MaxLength=200} Screenshot caption 5" -->
|
||||
Feedback Provider
|
||||
</Caption>
|
||||
<Caption DesktopImage="Experimental_Features.png" _locID="App_caption6">
|
||||
<!-- _locComment_text="{MaxLength=200} Screenshot caption 6" -->
|
||||
Experimental Features
|
||||
</Caption>
|
||||
</ScreenshotCaptions>
|
||||
<AdditionalAssets>
|
||||
<Icon FileName="pwshLogo.png" />
|
||||
<!-- Valid elements:-->
|
||||
<!-- HeroImage414x180, HeroImage846x468, HeroImage558x756, HeroImage414x468, HeroImage558x558, HeroImage2400x1200,-->
|
||||
<!-- ScreenshotWXGA, ScreenshotHD720, ScreenshotWVGA, Doublewide, Panoramic, Square,-->
|
||||
<!-- SmallMobileTile, SmallXboxLiveTile, LargeMobileTile, LargeXboxLiveTile, Tile,-->
|
||||
<!-- DesktopIcon, Icon (use this value for the 1:1 300x300 pixels logo), AchievementIcon,-->
|
||||
<!-- ChallengePromoIcon, RewardDisplayIcon, Icon150X150, Icon71X71,-->
|
||||
<!-- BoxArt, BrandedKeyArt, PosterArt, FeaturedPromotionalArt, PromotionalArt16x9, TitledHeroArt-->
|
||||
<!-- There is no content for any of these elements, just a single attribute called FileName. -->
|
||||
</AdditionalAssets>
|
||||
<Trailers>
|
||||
</Trailers>
|
||||
<AppFeatures>
|
||||
<!-- Valid length: 200 character limit, up to 20 elements -->
|
||||
<AppFeature _locID="App_feature1">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 1" -->Interactive Shell</AppFeature>
|
||||
<AppFeature _locID="App_feature2">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 2" -->Scripting Language</AppFeature>
|
||||
<AppFeature _locID="App_feature3">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 3" -->Remote Management</AppFeature>
|
||||
<AppFeature _locID="App_feature4">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 4" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature5">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 5" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature6">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 6" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature7">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 7" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature8">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 8" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature9">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 9" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature10">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 10" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature11">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 11" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature12">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 12" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature13">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 13" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature14">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 14" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature15">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 15" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature16">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 16" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature17">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 17" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature18">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 18" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature19">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 19" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature20">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 20" -->
|
||||
</AppFeature>
|
||||
</AppFeatures>
|
||||
<RecommendedHardware>
|
||||
<!-- Valid length: 200 character limit, up to 11 elements -->
|
||||
<Recommendation _locID="App_RecommendedHW1">
|
||||
<!-- _locComment_text="{MaxLength=200} App Recommended Hardware 1" -->
|
||||
</Recommendation>
|
||||
</RecommendedHardware>
|
||||
<MinimumHardware>
|
||||
<!-- Valid length: 200 character limit, up to 11 elements -->
|
||||
</MinimumHardware>
|
||||
<CopyrightAndTrademark _locID="App_CopyrightandTrademark">
|
||||
<!-- _locComment_text="{MaxLength=200} Copyright and Trademark" -->Microsoft Corporation</CopyrightAndTrademark>
|
||||
<AdditionalLicenseTerms _locID="App_AdditionalLicenseTerms">
|
||||
<!-- _locComment_text="{MaxLength=10000} Additional License Terms" -->
|
||||
</AdditionalLicenseTerms>
|
||||
<WebsiteURL _locID="App_WebsiteURL">
|
||||
<!-- _locComment_text="{MaxLength=2048} WebsiteURL" -->https://github.com/PowerShell/PowerShell</WebsiteURL>
|
||||
<SupportContactInfo _locID="App_SupportContactInfo">
|
||||
<!-- _locComment_text="{MaxLength=2048} Support Contact Info" -->https://github.com/PowerShell/PowerShell/issues</SupportContactInfo>
|
||||
<PrivacyPolicyURL _locID="App_PrivacyURL">
|
||||
<!-- _locComment_text="{MaxLength=2048} Privacy Policy URL" -->https://go.microsoft.com/fwlink/?LinkID=521839</PrivacyPolicyURL>
|
||||
</ProductDescription>
|
67
.pipelines/store/SBConfig.json
Normal file
@@ -0,0 +1,67 @@
|
||||
{
|
||||
"helpUri": "https:\\\\aka.ms\\StoreBroker_Config",
|
||||
"schemaVersion": 2,
|
||||
"packageParameters": {
|
||||
"PDPRootPath": "",
|
||||
"Release": "",
|
||||
"PDPInclude": [],
|
||||
"PDPExclude": [],
|
||||
"LanguageExclude": [
|
||||
"default",
|
||||
"qps-ploc",
|
||||
"qps-ploca",
|
||||
"qps-plocm"
|
||||
],
|
||||
"MediaRootPath": "",
|
||||
"MediaFallbackLanguage": "en-US",
|
||||
"PackagePath": [],
|
||||
"OutPath": "",
|
||||
"OutName": "",
|
||||
"DisableAutoPackageNameFormatting": false
|
||||
},
|
||||
"appSubmission": {
|
||||
"productId": "",
|
||||
"targetPublishMode": "NotSet",
|
||||
"targetPublishDate": null,
|
||||
"visibility": "NotSet",
|
||||
"pricing": {
|
||||
"priceId": "NotAvailable",
|
||||
"trialPeriod": "NoFreeTrial",
|
||||
"marketSpecificPricings": {},
|
||||
"sales": []
|
||||
},
|
||||
"allowTargetFutureDeviceFamilies": {
|
||||
"Xbox": false,
|
||||
"Team": false,
|
||||
"Holographic": false,
|
||||
"Desktop": false,
|
||||
"Mobile": false
|
||||
},
|
||||
"allowMicrosoftDecideAppAvailabilityToFutureDeviceFamilies": false,
|
||||
"enterpriseLicensing": "None",
|
||||
"applicationCategory": "NotSet",
|
||||
"hardwarePreferences": [],
|
||||
"hasExternalInAppProducts": false,
|
||||
"meetAccessibilityGuidelines": false,
|
||||
"canInstallOnRemovableMedia": false,
|
||||
"automaticBackupEnabled": false,
|
||||
"isGameDvrEnabled": false,
|
||||
"gamingOptions": [
|
||||
{
|
||||
"genres": [],
|
||||
"isLocalMultiplayer": false,
|
||||
"isLocalCooperative": false,
|
||||
"isOnlineMultiplayer": false,
|
||||
"isOnlineCooperative": false,
|
||||
"localMultiplayerMinPlayers": 0,
|
||||
"localMultiplayerMaxPlayers": 0,
|
||||
"localCooperativeMinPlayers": 0,
|
||||
"localCooperativeMaxPlayers": 0,
|
||||
"isBroadcastingPrivilegeGranted": false,
|
||||
"isCrossPlayEnabled": false,
|
||||
"kinectDataForExternal": "Disabled"
|
||||
}
|
||||
],
|
||||
"notesForCertification": ""
|
||||
}
|
||||
}
|
31
.pipelines/templates/channelSelection.yml
Normal file
@@ -0,0 +1,31 @@
|
||||
steps:
|
||||
- pwsh: |
|
||||
# Determine LTS, Preview, or Stable
|
||||
$metadata = Get-Content "$repoRoot/tools/metadata.json" -Raw | ConvertFrom-Json
|
||||
$LTS = $metadata.LTSRelease.Latest
|
||||
$Stable = $metadata.StableRelease.Latest
|
||||
$isPreview = '$(OutputReleaseTag.releaseTag)' -match '-'
|
||||
|
||||
$IsLTS = [bool]$LTS
|
||||
$IsStable = [bool]$Stable
|
||||
$IsPreview = [bool]$isPreview
|
||||
|
||||
$channelVars = @{
|
||||
IsLTS = $IsLTS
|
||||
IsStable = $IsStable
|
||||
IsPreview = $IsPreview
|
||||
}
|
||||
|
||||
$trueCount = ($channelVars.Values | Where-Object { $_ }) | Measure-Object | Select-Object -ExpandProperty Count
|
||||
if ($trueCount -gt 1) {
|
||||
Write-Error "Only one of IsLTS, IsStable, or IsPreview can be true. Current values: IsLTS=$IsLTS, IsStable=$IsStable, IsPreview=$IsPreview"
|
||||
exit 1
|
||||
}
|
||||
|
||||
foreach ($name in $channelVars.Keys) {
|
||||
$value = if ($channelVars[$name]) { 'true' } else { 'false' }
|
||||
Write-Verbose -Message "Setting $name variable: $value" -Verbose
|
||||
Write-Host "##vso[task.setvariable variable=$name;isOutput=true]$value"
|
||||
}
|
||||
name: ChannelSelection
|
||||
displayName: Select Preview, Stable, or LTS Channel
|
@@ -7,10 +7,16 @@ jobs:
|
||||
variables:
|
||||
- group: msixTools
|
||||
- group: 'Azure Blob variable group'
|
||||
- group: 'Store Publish Variables'
|
||||
- name: ob_outputDirectory
|
||||
value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT'
|
||||
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
env:
|
||||
ob_restore_phase: true # This ensures checkout is done at the beginning of the restore phase
|
||||
|
||||
- template: release-SetReleaseTagandContainerName.yml@self
|
||||
|
||||
- task: DownloadPipelineArtifact@2
|
||||
@@ -108,3 +114,125 @@ jobs:
|
||||
Write-Verbose -Verbose "Uploaded Bundle:"
|
||||
Get-ChildItem -Path $(ob_outputDirectory) | Write-Verbose -Verbose
|
||||
displayName: Upload msixbundle to Artifacts
|
||||
|
||||
- pwsh: |
|
||||
Write-Verbose -Verbose "Pipeline.Workspace: $(Pipeline.Workspace)"
|
||||
Get-ChildItem -Path $(Pipeline.Workspace) -Recurse | Select-Object -ExpandProperty FullName
|
||||
Write-Verbose -Verbose "System.DefaultWorkingDirectory: $(System.DefaultWorkingDirectory)"
|
||||
Get-ChildItem -Path $(System.DefaultWorkingDirectory) -Recurse | Select-Object -ExpandProperty FullName
|
||||
Test-Path -Path '$(System.DefaultWorkingDirectory)/PowerShell/.pipelines/store/PDP-Private.xml' | Write-Verbose -Verbose
|
||||
displayName: Output Pipeline.Workspace and System.DefaultWorkingDirectory
|
||||
|
||||
- template: channelSelection.yml@self
|
||||
|
||||
- pwsh: |
|
||||
$IsLTS = '$(ChannelSelection.IsLTS)' -eq 'true'
|
||||
$IsStable = '$(ChannelSelection.IsStable)' -eq 'true'
|
||||
$IsPreview = '$(ChannelSelection.IsPreview)' -eq 'true'
|
||||
|
||||
Write-Verbose -Verbose "Channel Selection - LTS: $IsLTS, Stable: $IsStable, Preview: $IsPreview"
|
||||
|
||||
# Define app configurations for each channel
|
||||
$channelConfigs = @{
|
||||
'LTS' = @{
|
||||
AppStoreName = 'PowerShell-LTS'
|
||||
ProductId = '$(productId-LTS)'
|
||||
ServiceEndpoint = "StoreAppPublish-Stable"
|
||||
}
|
||||
'Stable' = @{
|
||||
AppStoreName = 'PowerShell'
|
||||
ProductId = '$(productId-Stable)'
|
||||
ServiceEndpoint = "StoreAppPublish-Stable"
|
||||
}
|
||||
'Preview' = @{
|
||||
AppStoreName = 'PowerShell (Preview)'
|
||||
ProductId = '$(productId-Preview)'
|
||||
ServiceEndpoint = "StoreAppPublish-Preview"
|
||||
}
|
||||
}
|
||||
|
||||
$currentChannel = if ($IsLTS) { 'LTS' }
|
||||
elseif ($IsStable) { 'Stable' }
|
||||
elseif ($IsPreview) { 'Preview' }
|
||||
else {
|
||||
Write-Error "No valid channel detected"
|
||||
exit 1
|
||||
}
|
||||
|
||||
$config = $channelConfigs[$currentChannel]
|
||||
Write-Verbose -Verbose "Selected channel: $currentChannel"
|
||||
Write-Verbose -Verbose "App Store Name: $($config.AppStoreName)"
|
||||
Write-Verbose -Verbose "Product ID: $($config.ProductId)"
|
||||
|
||||
# Update PDP.xml file
|
||||
$pdpPath = '$(System.DefaultWorkingDirectory)/PowerShell/.pipelines/store/PDP/PDP/en-US/PDP.xml'
|
||||
if (Test-Path $pdpPath) {
|
||||
Write-Verbose -Verbose "Updating PDP file: $pdpPath"
|
||||
|
||||
[xml]$pdpXml = Get-Content $pdpPath -Raw
|
||||
|
||||
$appStoreNameElement = $pdpXml.SelectSingleNode("//AppStoreName[@_locID]")
|
||||
if ($appStoreNameElement) {
|
||||
$appStoreNameElement.InnerText = $config.AppStoreName
|
||||
Write-Verbose -Verbose "Updated AppStoreName to: $($config.AppStoreName)"
|
||||
} else {
|
||||
Write-Warning "AppStoreName element not found in PDP file"
|
||||
}
|
||||
|
||||
$pdpXml.Save($pdpPath)
|
||||
Write-Verbose -Verbose "PDP file updated successfully"
|
||||
} else {
|
||||
Write-Error "PDP file not found: $pdpPath"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Update SBConfig.json file
|
||||
$sbConfigPath = '$(System.DefaultWorkingDirectory)/PowerShell/.pipelines/store/SBConfig.json'
|
||||
if (Test-Path $sbConfigPath) {
|
||||
Write-Verbose -Verbose "Updating SBConfig file: $sbConfigPath"
|
||||
|
||||
$sbConfigJson = Get-Content $sbConfigPath -Raw | ConvertFrom-Json
|
||||
|
||||
$sbConfigJson.appSubmission.productId = $config.ProductId
|
||||
Write-Verbose -Verbose "Updated productId to: $($config.ProductId)"
|
||||
|
||||
$sbConfigJson | ConvertTo-Json -Depth 100 | Set-Content $sbConfigPath -Encoding UTF8
|
||||
Write-Verbose -Verbose "SBConfig file updated successfully"
|
||||
} else {
|
||||
Write-Error "SBConfig file not found: $sbConfigPath"
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "##vso[task.setvariable variable=ServiceConnection]$($config.ServiceEndpoint)"
|
||||
Write-Host "##vso[task.setvariable variable=SBConfigPath]$($config.SBConfigPath)"
|
||||
name: UpdateConfigs
|
||||
displayName: Update PDPs and SBConfig.json
|
||||
|
||||
- task: MS-RDX-MRO.windows-store-publish-dev.package-task.store-package@3
|
||||
displayName: 'Create StoreBroker Package'
|
||||
inputs:
|
||||
serviceEndpoint: '$(ServiceConnection)'
|
||||
sbConfigPath: '$(SBConfigPath)'
|
||||
sourceFolder: '$(BundleDir)'
|
||||
contents: '*.msixBundle'
|
||||
outSBName: 'PowerShellStorePackage'
|
||||
pdpPath: '$(System.DefaultWorkingDirectory)/PowerShell/.pipelines/store/PDP/PDP'
|
||||
pdpMediaPath: '$(System.DefaultWorkingDirectory)/PowerShell/.pipelines/store/PDP/PDP-Media'
|
||||
|
||||
- pwsh: |
|
||||
$submissionPackageDir = "$(System.DefaultWorkingDirectory)/SBOutDir"
|
||||
$jsonFile = "$submissionPackageDir/PowerShellStorePackage.json"
|
||||
$zipFile = "$submissionPackageDir/PowerShellStorePackage.zip"
|
||||
|
||||
if ((Test-Path $jsonFile) -and (Test-Path $zipFile)) {
|
||||
Write-Verbose -Verbose "Uploading StoreBroker Package files:"
|
||||
Write-Verbose -Verbose "JSON File: $jsonFile"
|
||||
Write-Verbose -Verbose "ZIP File: $zipFile"
|
||||
|
||||
Copy-Item -Path $submissionPackageDir -Destination "$(ob_outputDirectory)" -Verbose -Recurse
|
||||
}
|
||||
|
||||
else {
|
||||
Write-Error "Required files not found in $submissionPackageDir"
|
||||
}
|
||||
displayName: 'Upload StoreBroker Package'
|
||||
|
115
.pipelines/templates/release-MSIX-Publish.yml
Normal file
@@ -0,0 +1,115 @@
|
||||
parameters:
|
||||
- name: skipMSIXPublish
|
||||
type: boolean
|
||||
|
||||
jobs:
|
||||
- job: Store_Publish_MSIX
|
||||
displayName: Publish MSIX to the Microsoft Store
|
||||
pool:
|
||||
type: release
|
||||
os: windows
|
||||
templateContext:
|
||||
inputs:
|
||||
- input: pipelineArtifact
|
||||
pipeline: PSPackagesOfficial
|
||||
artifactName: drop_msixbundle_CreateMSIXBundle
|
||||
variables:
|
||||
- group: 'Store Publish Variables'
|
||||
- template: ./variable/release-shared.yml@self
|
||||
parameters:
|
||||
RELEASETAG: $[ stageDependencies.setReleaseTagAndChangelog.setTagAndChangelog.outputs['OutputReleaseTag.releaseTag'] ]
|
||||
LTS: $[ stageDependencies.setReleaseTagAndChangelog.setTagAndChangelog.outputs['ChannelSelection.IsLTS'] ]
|
||||
STABLE: $[ stageDependencies.setReleaseTagAndChangelog.setTagAndChangelog.outputs['ChannelSelection.IsStable'] ]
|
||||
PREVIEW: $[ stageDependencies.setReleaseTagAndChangelog.setTagAndChangelog.outputs['ChannelSelection.IsPreview'] ]
|
||||
steps:
|
||||
- task: PowerShell@2
|
||||
inputs:
|
||||
targetType: inline
|
||||
script: |
|
||||
Write-Verbose -Verbose "Release Tag: $(ReleaseTag)"
|
||||
Get-ChildItem $(Pipeline.Workspace) -Recurse | Select-Object -ExpandProperty FullName
|
||||
displayName: 'Capture ReleaseTag and Downloaded Packages'
|
||||
|
||||
- task: PowerShell@2
|
||||
inputs:
|
||||
targetType: inline
|
||||
script: |
|
||||
if ("$(ReleaseTag)" -eq '') {
|
||||
Write-Error "ReleaseTag is not set. Cannot proceed with publishing to the Store."
|
||||
exit 1
|
||||
}
|
||||
$middleURL = ''
|
||||
$tagString = "$(ReleaseTag)"
|
||||
if ($tagString -match '-') {
|
||||
$middleURL = "preview"
|
||||
}
|
||||
elseif ($tagString -match '(\d+\.\d+)') {
|
||||
$middleURL = $matches[1]
|
||||
}
|
||||
|
||||
$endURL = $tagString -replace '[v\.]',''
|
||||
$message = "Changelog: https://github.com/PowerShell/PowerShell/blob/master/CHANGELOG/$middleURL.md#$endURL"
|
||||
Write-Verbose -Verbose "Release Notes for the Store:"
|
||||
Write-Verbose -Verbose "$message"
|
||||
$jsonPath = "$(Pipeline.Workspace)\SBOutDir\PowerShellStorePackage.json"
|
||||
$json = Get-Content $jsonPath -Raw | ConvertFrom-Json
|
||||
|
||||
$json.listings.'en-us'.baseListing.releaseNotes = $message
|
||||
|
||||
$json | ConvertTo-Json -Depth 100 | Set-Content $jsonPath -Encoding UTF8
|
||||
displayName: 'Update Release Notes in JSON'
|
||||
|
||||
- task: PowerShell@2
|
||||
inputs:
|
||||
targetType: inline
|
||||
script: |
|
||||
Write-Verbose -Verbose "Channel Selection - LTS: $(LTS), Stable: $(Stable), Preview: $(Preview)"
|
||||
|
||||
# Define app configurations for each channel using secret variables
|
||||
$channelConfigs = @{
|
||||
'LTS' = @{
|
||||
AppId = '$(AppID-LTS)'
|
||||
ServiceEndpoint = 'StoreAppPublish-Stable'
|
||||
}
|
||||
'Stable' = @{
|
||||
AppId = '$(AppID-Stable)'
|
||||
ServiceEndpoint = 'StoreAppPublish-Stable'
|
||||
}
|
||||
'Preview' = @{
|
||||
AppId = '$(AppID-Preview)'
|
||||
ServiceEndpoint = 'StoreAppPublish-Preview'
|
||||
}
|
||||
}
|
||||
|
||||
# Determine the current channel
|
||||
$currentChannel = if ($IsLTS) { 'LTS' }
|
||||
elseif ($IsStable) { 'Stable' }
|
||||
elseif ($IsPreview) { 'Preview' }
|
||||
else {
|
||||
Write-Error "No valid channel detected"
|
||||
exit 1
|
||||
}
|
||||
|
||||
$config = $channelConfigs[$currentChannel]
|
||||
Write-Verbose -Verbose "Selected channel: $currentChannel"
|
||||
Write-Verbose -Verbose "App ID: $($config.AppId)"
|
||||
Write-Verbose -Verbose "Service Endpoint: $($config.ServiceEndpoint)"
|
||||
|
||||
# Set pipeline variables for use in the store-publish task
|
||||
Write-Host "##vso[task.setvariable variable=SelectedAppId]$($config.AppId)"
|
||||
Write-Host "##vso[task.setvariable variable=SelectedServiceEndpoint]$($config.ServiceEndpoint)"
|
||||
Write-Host "##vso[task.setvariable variable=SelectedChannel]$currentChannel"
|
||||
displayName: 'Set StoreBroker Configurations'
|
||||
|
||||
- task: MS-RDX-MRO.windows-store-publish.publish-task.store-publish@3
|
||||
displayName: 'Publish LTS StoreBroker Package'
|
||||
condition: ne('${{ parameters.skipMSIXPublish }}', 'true')
|
||||
inputs:
|
||||
serviceEndpoint: '$(SelectedServiceEndpoint)'
|
||||
appId: '$(SelectedAppId)'
|
||||
inputMethod: JsonAndZip
|
||||
jsonPath: '$(Pipeline.Workspace)\SBOutDir\PowerShellStorePackage.json'
|
||||
zipPath: '$(Pipeline.Workspace)\SBOutDir\PowerShellStorePackage.zip'
|
||||
numberOfPackagesToKeep: 2
|
||||
jsonZipUpdateMetadata: true
|
||||
targetPublishMode: 'Immediate'
|
@@ -19,7 +19,7 @@ jobs:
|
||||
clean: true
|
||||
env:
|
||||
ob_restore_phase: true
|
||||
|
||||
|
||||
- pwsh: |
|
||||
Write-Verbose -Verbose "Release Tag: $(OutputReleaseTag.releaseTag)"
|
||||
$releaseVersion = '$(OutputReleaseTag.releaseTag)' -replace '^v',''
|
||||
@@ -47,3 +47,5 @@ jobs:
|
||||
New-Item -Path $(ob_outputDirectory)/CHANGELOG -ItemType Directory -Force
|
||||
Copy-Item -Path $filePath -Destination $(ob_outputDirectory)/CHANGELOG
|
||||
displayName: Upload Changelog
|
||||
|
||||
- template: channelSelection.yml@self
|
||||
|
@@ -515,6 +515,7 @@ function Start-PSPackage {
|
||||
Architecture = $WindowsRuntime.Split('-')[1]
|
||||
Force = $Force
|
||||
Private = $Private
|
||||
LTS = $LTS
|
||||
}
|
||||
|
||||
if ($PSCmdlet.ShouldProcess("Create MSIX Package")) {
|
||||
@@ -3670,6 +3671,9 @@ function New-MSIXPackage
|
||||
# Produce private package for testing in Store
|
||||
[Switch] $Private,
|
||||
|
||||
# Produce LTS package
|
||||
[Switch] $LTS,
|
||||
|
||||
# Force overwrite of package
|
||||
[Switch] $Force,
|
||||
|
||||
@@ -3714,6 +3718,9 @@ function New-MSIXPackage
|
||||
} elseif ($ProductSemanticVersion.Contains('-')) {
|
||||
$ProductName += 'Preview'
|
||||
$displayName += ' Preview'
|
||||
} elseif ($LTS) {
|
||||
$ProductName += '-LTS'
|
||||
$displayName += '-LTS'
|
||||
}
|
||||
|
||||
Write-Verbose -Verbose "ProductName: $productName"
|
||||
@@ -3733,6 +3740,10 @@ function New-MSIXPackage
|
||||
# This is the PhoneProductId for the "Microsoft.PowerShellPreview" package.
|
||||
$PhoneProductId = "67859fd2-b02a-45be-8fb5-62c569a3e8bf"
|
||||
Write-Verbose "Using Preview assets" -Verbose
|
||||
} elseif ($LTS) {
|
||||
# This is the PhoneProductId for the "Microsoft.PowerShell-LTS" package.
|
||||
$PhoneProductId = "a9af273a-c636-47ac-bc2a-775edf80b2b9"
|
||||
Write-Verbose "Using LTS assets" -Verbose
|
||||
}
|
||||
|
||||
# Appx manifest needs to be in root of source path, but the embedded version needs to be updated
|
||||
|