diff --git a/eng/pipelines/azure-pipelines.yml b/eng/pipelines/azure-pipelines.yml index 6977cfaea52..b2a7da2b8fe 100644 --- a/eng/pipelines/azure-pipelines.yml +++ b/eng/pipelines/azure-pipelines.yml @@ -8,6 +8,10 @@ parameters: displayName: 'Publish as Pre-Release' type: boolean default: false + - name: publishReleaseToWinGet + displayName: 'Publish release branch builds to WinGet' + type: boolean + default: false trigger: batch: true @@ -50,10 +54,34 @@ pr: variables: - template: /eng/pipelines/common-variables.yml@self - template: /eng/common/templates-official/variables/pool-providers.yml@self + + # True on main, release/*, internal/release/* — used to gate secret-group loading and WinGet publishing. + - name: _IsPublishBranch + value: ${{ or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/internal/release/')) }} + # Publish to WinGet on main (always, non-PR) or release branches (only when publishReleaseToWinGet is true) + - name: _PublishToWinGet + value: ${{ or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), and(or(startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/internal/release/')), eq(parameters.publishReleaseToWinGet, true))) }} + + # Use the release package id on release/* and internal/release/* branches, prerelease everywhere else + - ${{ if or(startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/internal/release/')) }}: + - name: _WinGetTemplateDir + value: microsoft.aspire + - name: _WinGetPackageIdentifier + value: Microsoft.Aspire + - ${{ else }}: + - name: _WinGetTemplateDir + value: microsoft.aspire.prerelease + - name: _WinGetPackageIdentifier + value: Microsoft.Aspire.Prerelease + # Variable group containing VscePublishToken for VS Code Marketplace publishing - ${{ if eq(parameters.publishVSCodeExtension, true) }}: - group: Aspire-Release-Secrets + # Load secret variable groups for WinGet publishing + - ${{ if eq(variables._IsPublishBranch, 'True') }}: + - group: Aspire-Secrets + - name: _BuildConfig value: Release - name: Build.Arcade.ArtifactsPath @@ -297,3 +325,40 @@ extends: LclPackageId: 'LCL-JUNO-PROD-ASPIRE' MirrorRepo: aspire MirrorBranch: main + + # ---------------------------------------------------------------- + # Publish WinGet manifests (Windows) + # ---------------------------------------------------------------- + - stage: publish_winget + displayName: Publish to WinGet + dependsOn: + - build + condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'), eq(variables._IsPublishBranch, 'True')) + jobs: + - template: /eng/common/templates-official/jobs/jobs.yml@self + parameters: + enableMicrobuild: false + enablePublishUsingPipelines: false + enablePublishBuildAssets: false + enablePublishBuildArtifacts: true + enableTelemetry: true + workspace: + clean: all + jobs: + - job: WinGet_Publish + timeoutInMinutes: 30 + pool: + name: NetCore1ESPool-Internal + image: 1es-windows-2022 + os: windows + steps: + - checkout: self + fetchDepth: 1 + - template: /eng/pipelines/templates/winget.yml@self + parameters: + publishToWinGet: ${{ variables._PublishToWinGet }} + wingetToken: $(aspire-winget-bot-pat) + buildConfig: $(_BuildConfig) + version: $(aspireVersion) + templateDir: ${{ variables._WinGetTemplateDir }} + packageIdentifier: ${{ variables._WinGetPackageIdentifier }} diff --git a/eng/pipelines/templates/winget.yml b/eng/pipelines/templates/winget.yml new file mode 100644 index 00000000000..213db1fa29f --- /dev/null +++ b/eng/pipelines/templates/winget.yml @@ -0,0 +1,276 @@ +parameters: + - name: publishToWinGet + type: boolean + default: false + - name: wingetToken + type: string + default: '' + - name: buildConfig + type: string + default: 'Release' + - name: version + type: string + default: '' + - name: templateDir + type: string + default: 'microsoft.aspire' + - name: packageIdentifier + type: string + default: 'Microsoft.Aspire' + +steps: + - pwsh: | + $ErrorActionPreference = 'Stop' + $version = '${{ parameters.version }}' + + if ([string]::IsNullOrWhiteSpace($version)) { + Write-Error "Version parameter is required" + exit 1 + } + + Write-Host "Version: $version" + Write-Host "##vso[task.setvariable variable=CliVersion]$version" + displayName: 🟣Set version ${{ parameters.version }} + + - pwsh: | + $ErrorActionPreference = 'Stop' + Write-Host "Downloading wingetcreate..." + Invoke-WebRequest -Uri "https://aka.ms/wingetcreate/latest" -OutFile "$(Build.StagingDirectory)/wingetcreate.exe" + Write-Host "wingetcreate downloaded successfully" + displayName: 🟣Install wingetcreate + + - pwsh: | + $ErrorActionPreference = 'Stop' + $ProgressPreference = 'SilentlyContinue' + + # Check if winget is already available + $wingetPath = Get-Command winget -ErrorAction SilentlyContinue + if ($wingetPath) { + Write-Host "winget is already installed at: $($wingetPath.Source)" + winget --version + exit 0 + } + + Write-Host "Installing Microsoft.WinGet.Client module..." + Install-Module -Name Microsoft.WinGet.Client -Repository PSGallery -Force -Scope AllUsers + + Write-Host "Installing WinGet using Repair-WinGetPackageManager..." + Repair-WinGetPackageManager -Latest -Force -AllUsers + + # Verify installation + $wingetPath = Get-Command winget -ErrorAction SilentlyContinue + if ($wingetPath) { + Write-Host "winget installed successfully at: $($wingetPath.Source)" + winget --version + } else { + Write-Error "winget installation failed - command not found" + exit 1 + } + displayName: 🟣Install winget CLI + + - pwsh: | + $ErrorActionPreference = 'Stop' + $version = '$(CliVersion)' + $outputPath = '$(Build.StagingDirectory)/winget-manifests' + $templateDir = '$(Build.SourcesDirectory)/eng/winget/${{ parameters.templateDir }}' + + Write-Host "Generating WinGet manifests for Aspire.Cli version $version" + Write-Host "Using template directory: $templateDir" + + & "$(Build.SourcesDirectory)/eng/winget/generate-manifests.ps1" ` + -Version $version ` + -TemplateDir $templateDir ` + -OutputPath $outputPath ` + -ValidateUrls + + if ($LASTEXITCODE -ne 0) { + Write-Error "generate-manifests.ps1 failed with exit code $LASTEXITCODE" + exit $LASTEXITCODE + } + + Write-Host "Manifest files generated:" + Get-ChildItem -Path $outputPath -Recurse | Format-Table FullName + displayName: 🟣Generate WinGet manifests + + - pwsh: | + $ErrorActionPreference = 'Stop' + $manifestPath = '$(Build.StagingDirectory)/winget-manifests' + $version = '$(CliVersion)' + + # Find the versioned manifest folder + $versionedManifestPath = Get-ChildItem -Path $manifestPath -Directory -Recurse | + Where-Object { $_.Name -eq $version } | + Select-Object -First 1 -ExpandProperty FullName + + if (-not $versionedManifestPath) { + $versionedManifestPath = $manifestPath + } + + Write-Host "Testing WinGet manifests at: $versionedManifestPath" + Write-Host "" + + # Enable local manifest files + Write-Host "Enabling local manifest files in winget settings..." + winget settings --enable LocalManifestFiles + if ($LASTEXITCODE -ne 0) { + Write-Host "##[warning]Failed to enable local manifests. This may require admin privileges." + } + + # Validate manifests using winget validate + Write-Host "" + Write-Host "Running winget validate..." + winget validate --manifest $versionedManifestPath + if ($LASTEXITCODE -ne 0) { + Write-Error "winget validate failed with exit code $LASTEXITCODE" + exit $LASTEXITCODE + } + + Write-Host "✅ winget validate passed" + displayName: 🟣Validate WinGet manifests + + - pwsh: | + $ErrorActionPreference = 'Stop' + $manifestPath = '$(Build.StagingDirectory)/winget-manifests' + $version = '$(CliVersion)' + + # Find the versioned manifest folder + $versionedManifestPath = Get-ChildItem -Path $manifestPath -Directory -Recurse | + Where-Object { $_.Name -eq $version } | + Select-Object -First 1 -ExpandProperty FullName + + if (-not $versionedManifestPath) { + $versionedManifestPath = $manifestPath + } + + Write-Host "Testing manifest install/uninstall at: $versionedManifestPath" + Write-Host "" + + # Verify aspire is NOT available before install + Write-Host "Verifying aspire is not already installed..." + if (Get-Command aspire -ErrorAction SilentlyContinue) { + Write-Error "aspire command is already available before install - test environment is not clean" + exit 1 + } + Write-Host " Confirmed: aspire is not in PATH" + + # Test install + Write-Host "" + Write-Host "Installing Aspire.Cli from local manifest..." + winget install --manifest $versionedManifestPath --accept-package-agreements --accept-source-agreements + if ($LASTEXITCODE -ne 0) { + Write-Error "winget install failed with exit code $LASTEXITCODE" + exit $LASTEXITCODE + } + Write-Host "✅ Install succeeded" + + # Refresh PATH from registry to pick up changes made by winget + Write-Host "" + Write-Host "Refreshing PATH environment variable..." + $env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User") + + # Verify aspire is now available in PATH. + # Use a new pwsh process so it inherits the system/user PATH that winget updated + # rather than relying on the current process's stale $env:Path. + $failed = $false + Write-Host "Verifying aspire CLI is in PATH (new process)..." + try { + $aspireInfo = pwsh -NoProfile -Command ' + $cmd = Get-Command aspire -ErrorAction SilentlyContinue + if (-not $cmd) { Write-Error "aspire not found in PATH"; exit 1 } + Write-Host " Path: $($cmd.Source)" + $v = & aspire --version 2>&1 + if ($LASTEXITCODE -ne 0) { Write-Error "aspire --version failed: $v"; exit $LASTEXITCODE } + Write-Host " Version: $v" + ' + if ($LASTEXITCODE -ne 0) { + throw "Child process exited with code $LASTEXITCODE" + } + Write-Host "✅ aspire CLI verified" + } catch { + Write-Host "##[error]Failed to verify aspire CLI: $_" + $failed = $true + } + + # Test uninstall (always attempt cleanup even if verification failed) + Write-Host "" + Write-Host "Uninstalling Aspire.Cli..." + winget uninstall --manifest $versionedManifestPath --accept-source-agreements + if ($LASTEXITCODE -ne 0) { + if ($failed) { + Write-Host "##[warning]winget uninstall also failed with exit code $LASTEXITCODE (ignoring since verification already failed)" + } else { + Write-Error "winget uninstall failed with exit code $LASTEXITCODE" + exit $LASTEXITCODE + } + } else { + Write-Host "✅ Uninstall succeeded" + } + + if ($failed) { + exit 1 + } + displayName: 🟣Test WinGet manifest install/uninstall + + - task: 1ES.PublishBuildArtifacts@1 + displayName: 🟣Publish WinGet manifests + condition: always() + inputs: + PathtoPublish: '$(Build.StagingDirectory)/winget-manifests' + ArtifactName: winget-manifests + + - ${{ if and(eq(parameters.publishToWinGet, true), ne(parameters.wingetToken, '')) }}: + - pwsh: | + $ErrorActionPreference = 'Stop' + $version = '$(CliVersion)' + $manifestPath = '$(Build.StagingDirectory)/winget-manifests' + + # Extract installer URLs from the generated manifest + $installerYaml = Get-ChildItem -Path $manifestPath -Filter "*.installer.yaml" -Recurse | Select-Object -First 1 + if (-not $installerYaml) { + Write-Error "No installer.yaml found in $manifestPath" + exit 1 + } + + $urls = (Get-Content $installerYaml.FullName | Select-String -Pattern '^\s*InstallerUrl:\s*(.+)$' -AllMatches).Matches | + ForEach-Object { $_.Groups[1].Value.Trim() } + + if ($urls.Count -eq 0) { + Write-Error "No InstallerUrl entries found in $($installerYaml.Name)" + exit 1 + } + + $token = $env:WINGET_CREATE_GITHUB_TOKEN + if ([string]::IsNullOrWhiteSpace($token)) { + Write-Error "WINGET_CREATE_GITHUB_TOKEN is not set or empty" + exit 1 + } + + Write-Host "Submitting WinGet manifest update for Aspire version $version" + Write-Host "Installer URLs: $($urls -join ', ')" + + # wingetcreate reads the token from WINGET_CREATE_GITHUB_TOKEN env var automatically + # See: https://github.com/microsoft/winget-create/blob/main/doc/token.md + $output = & "$(Build.StagingDirectory)/wingetcreate.exe" update ${{ parameters.packageIdentifier }} ` + --urls @urls ` + --version $version ` + --submit 2>&1 + + $exitCode = $LASTEXITCODE + $outputText = $output -join "`n" + Write-Host $outputText + + if ($exitCode -ne 0) { + Write-Error "wingetcreate failed with exit code $exitCode" + exit $exitCode + } + + # wingetcreate may exit 0 despite errors (e.g. invalid token) + if ($outputText -match 'Token was invalid|error|failed') { + Write-Error "wingetcreate reported errors despite exit code 0" + exit 1 + } + + Write-Host "Successfully submitted WinGet manifest update for Aspire $version" + displayName: 🟣Submit to WinGet + env: + WINGET_CREATE_GITHUB_TOKEN: ${{ parameters.wingetToken }} diff --git a/eng/winget/generate-manifests.ps1 b/eng/winget/generate-manifests.ps1 new file mode 100644 index 00000000000..c80b3d42fef --- /dev/null +++ b/eng/winget/generate-manifests.ps1 @@ -0,0 +1,273 @@ +<# +.SYNOPSIS + Generates WinGet manifest files for Aspire CLI from templates. + +.DESCRIPTION + This script generates the required WinGet manifest files (version, locale, and installer) + from templates by substituting version numbers, URLs, and computing SHA256 hashes. + Installer URLs are derived from the version and RIDs using the ci.dot.net URL pattern. + +.PARAMETER Version + The version number for the package (e.g., "13.3.0-preview.1.26111.5"). + +.PARAMETER TemplateDir + The directory containing the manifest templates to use. + Use "microsoft.aspire" for release builds or "microsoft.aspire.prerelease" for prerelease builds. + +.PARAMETER Rids + Comma-separated list of Runtime Identifiers for the installer architectures. + Defaults to "win-x64,win-arm64". + +.PARAMETER OutputPath + The directory where the manifest files will be written. + Defaults to a path derived from the PackageIdentifier in the templates, + e.g., "./manifests/m/Microsoft/Aspire/{Version}" for Microsoft.Aspire + or "./manifests/m/Microsoft/Aspire/Prerelease/{Version}" for Microsoft.Aspire.Prerelease. + +.PARAMETER ValidateUrls + When specified, verifies that all installer URLs are accessible (HTTP HEAD request) + before downloading them to compute SHA256 hashes. + +.EXAMPLE + ./generate-manifests.ps1 -Version "13.3.0-preview.1.26111.5" ` + -TemplateDir "./eng/winget/microsoft.aspire.prerelease" + +.EXAMPLE + ./generate-manifests.ps1 -Version "13.2.0" ` + -TemplateDir "./eng/winget/microsoft.aspire" ` + -Rids "win-x64,win-arm64" -ValidateUrls +#> + +[CmdletBinding()] +param( + [Parameter(Mandatory = $true)] + [string]$Version, + + [Parameter(Mandatory = $true)] + [string]$TemplateDir, + + [Parameter(Mandatory = $false)] + [string]$Rids = "win-x64,win-arm64", + + [Parameter(Mandatory = $false)] + [string]$OutputPath, + + [Parameter(Mandatory = $false)] + [switch]$ValidateUrls +) + +$ErrorActionPreference = 'Stop' + +# Determine script paths +$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path + +# Validate template directory +if (-not (Test-Path $TemplateDir)) { + Write-Error "Template directory not found: $TemplateDir" + exit 1 +} + +# Extract PackageIdentifier from the version template +$versionTemplatePath = Join-Path $TemplateDir "Aspire.yaml.template" +if (-not (Test-Path $versionTemplatePath)) { + Write-Error "Version template not found: $versionTemplatePath" + exit 1 +} + +$PackageIdentifier = $null +foreach ($line in Get-Content -Path $versionTemplatePath) { + if ($line -match '^\s*PackageIdentifier:\s*(.+)\s*$') { + $PackageIdentifier = $Matches[1].Trim() + break + } +} + +if (-not $PackageIdentifier) { + Write-Error "Could not extract PackageIdentifier from $versionTemplatePath" + exit 1 +} + +Write-Host "Package identifier: $PackageIdentifier" + +# Derive the output directory from the PackageIdentifier +# Convention: manifests/{first-letter-lowercase}/{Segment1}/{Segment2}/.../{Version} +# e.g. Microsoft.Aspire -> manifests/m/Microsoft/Aspire/{Version} +# e.g. Microsoft.Aspire.Prerelease -> manifests/m/Microsoft/Aspire/Prerelease/{Version} +if (-not $OutputPath) { + $idSegments = $PackageIdentifier.Split('.') + $firstLetter = $idSegments[0].Substring(0, 1).ToLowerInvariant() + $pathSegments = @("manifests", $firstLetter) + $idSegments + @($Version) + $OutputPath = Join-Path $ScriptDir ($pathSegments -join [System.IO.Path]::DirectorySeparatorChar) +} + +Write-Host "Generating WinGet manifests for Aspire version $Version" +Write-Host "Output directory: $OutputPath" + +# Create output directory +if (-not (Test-Path $OutputPath)) { + New-Item -ItemType Directory -Path $OutputPath -Force | Out-Null +} + +# Parse RIDs +$ridList = $Rids.Split(',') | ForEach-Object { $_.Trim() } +Write-Host "RIDs: $($ridList -join ', ')" + +# Map RID to winget architecture name +function Get-ArchitectureFromRid { + param([string]$Rid) + + # Extract the architecture portion after the OS prefix (e.g., "win-x64" -> "x64") + if ($Rid -match '^win-(.+)$') { + return $Matches[1] + } + + Write-Error "Unsupported RID format: $Rid (expected 'win-')" + exit 1 +} + +# Build installer URL from version and RID +# Pattern: https://ci.dot.net/public/aspire/{version}/aspire-cli-{rid}-{version}.zip +function Get-InstallerUrl { + param( + [string]$Version, + [string]$Rid + ) + + return "https://ci.dot.net/public/aspire/$Version/aspire-cli-$Rid-$Version.zip" +} + +# Function to compute SHA256 hash of a file downloaded from URL +function Get-RemoteFileSha256 { + param( + [string]$Url, + [string]$Description + ) + + Write-Host "Downloading $Description to compute SHA256..." + Write-Host " URL: $Url" + + $tempFile = [System.IO.Path]::GetTempFileName() + try { + $ProgressPreference = 'SilentlyContinue' + Invoke-WebRequest -Uri $Url -OutFile $tempFile -UseBasicParsing + + $hash = (Get-FileHash -Path $tempFile -Algorithm SHA256).Hash.ToUpperInvariant() + Write-Host " SHA256: $hash" + return $hash + } + finally { + if (Test-Path $tempFile) { + Remove-Item $tempFile -Force + } + } +} + +# Function to process a template file +function Process-Template { + param( + [string]$TemplatePath, + [string]$OutputFile, + [hashtable]$Substitutions + ) + + $templateName = Split-Path -Leaf $TemplatePath + Write-Host "Processing template: $templateName" + + $content = Get-Content -Path $TemplatePath -Raw + + foreach ($key in $Substitutions.Keys) { + $placeholder = "`${$key}" + $value = $Substitutions[$key] + $content = $content.Replace($placeholder, $value) + } + + Set-Content -Path $OutputFile -Value $content -NoNewline + Write-Host " Created: $OutputFile" +} + +# Build the Installers YAML block and compute hashes +Write-Host "" + +# Build all installer URLs first +$installerEntries = @() +foreach ($rid in $ridList) { + $arch = Get-ArchitectureFromRid -Rid $rid + $url = Get-InstallerUrl -Version $Version -Rid $rid + $installerEntries += @{ Rid = $rid; Architecture = $arch; Url = $url } +} + +# Validate URLs are accessible before downloading (fast-fail) +if ($ValidateUrls) { + Write-Host "Validating installer URLs..." + $failed = $false + foreach ($entry in $installerEntries) { + Write-Host " Checking: $($entry.Url)" + try { + $response = Invoke-WebRequest -Uri $entry.Url -Method Head -UseBasicParsing + Write-Host " Status: $($response.StatusCode) OK" + } + catch { + Write-Host " ERROR: URL not accessible: $($_.Exception.Message)" + $failed = $true + } + } + + if ($failed) { + Write-Error "One or more installer URLs are not accessible. Ensure the release artifacts have been published." + exit 1 + } + Write-Host "" +} + +Write-Host "Computing SHA256 hashes..." + +$installersYaml = "Installers:" +foreach ($entry in $installerEntries) { + $sha256 = Get-RemoteFileSha256 -Url $entry.Url -Description "$($entry.Rid) installer" + + $installersYaml += "`n- Architecture: $($entry.Architecture)" + $installersYaml += "`n InstallerUrl: $($entry.Url)" + $installersYaml += "`n InstallerSha256: $sha256" +} + +# Define substitutions +$today = Get-Date -Format "yyyy-MM-dd" +$year = Get-Date -Format "yyyy" +$substitutions = @{ + "VERSION" = $Version + "INSTALLERS" = $installersYaml + "RELEASE_DATE" = $today + "YEAR" = $year +} + +Write-Host "" +Write-Host "Generating manifest files..." + +# Process each template +# Output files are named {PackageIdentifier}.{type}.yaml per winget convention +$templates = @( + @{ Template = "Aspire.yaml.template"; Output = "$PackageIdentifier.yaml" }, + @{ Template = "Aspire.locale.en-US.yaml.template"; Output = "$PackageIdentifier.locale.en-US.yaml" }, + @{ Template = "Aspire.installer.yaml.template"; Output = "$PackageIdentifier.installer.yaml" } +) + +foreach ($template in $templates) { + $templatePath = Join-Path $TemplateDir $template.Template + $outputFile = Join-Path $OutputPath $template.Output + + if (-not (Test-Path $templatePath)) { + Write-Error "Template not found: $templatePath" + exit 1 + } + + Process-Template -TemplatePath $templatePath -OutputFile $outputFile -Substitutions $substitutions +} + +Write-Host "" +Write-Host "Successfully generated WinGet manifests at: $OutputPath" +Write-Host "" +Write-Host "Next steps:" +Write-Host " 1. Validate manifests: winget validate --manifest `"$OutputPath`"" +Write-Host " 2. Submit to winget-pkgs: wingetcreate submit --token YOUR_PAT `"$OutputPath`"" + +exit 0 diff --git a/eng/winget/microsoft.aspire.prerelease/Aspire.installer.yaml.template b/eng/winget/microsoft.aspire.prerelease/Aspire.installer.yaml.template new file mode 100644 index 00000000000..86df516224d --- /dev/null +++ b/eng/winget/microsoft.aspire.prerelease/Aspire.installer.yaml.template @@ -0,0 +1,18 @@ +# yaml-language-server: $schema=https://aka.ms/winget-manifest.installer.1.10.0.schema.json + +PackageIdentifier: Microsoft.Aspire.Prerelease +PackageVersion: "${VERSION}" +InstallerType: zip +NestedInstallerType: portable +NestedInstallerFiles: +- RelativeFilePath: aspire.exe + PortableCommandAlias: aspire +Commands: +- aspire +InstallModes: +- silent +UpgradeBehavior: uninstallPrevious +ReleaseDate: ${RELEASE_DATE} +${INSTALLERS} +ManifestType: installer +ManifestVersion: 1.10.0 diff --git a/eng/winget/microsoft.aspire.prerelease/Aspire.locale.en-US.yaml.template b/eng/winget/microsoft.aspire.prerelease/Aspire.locale.en-US.yaml.template new file mode 100644 index 00000000000..7eba171a8bf --- /dev/null +++ b/eng/winget/microsoft.aspire.prerelease/Aspire.locale.en-US.yaml.template @@ -0,0 +1,33 @@ +# yaml-language-server: $schema=https://aka.ms/winget-manifest.defaultLocale.1.10.0.schema.json + +PackageIdentifier: Microsoft.Aspire.Prerelease +PackageVersion: "${VERSION}" +PackageLocale: en-US +Publisher: Microsoft Corporation +PublisherUrl: https://aspire.dev/ +PublisherSupportUrl: https://github.com/dotnet/aspire/issues +PrivacyUrl: https://privacy.microsoft.com/privacystatement +PackageName: Aspire CLI (Prerelease) +PackageUrl: https://aspire.dev/ +License: MIT +LicenseUrl: https://github.com/dotnet/aspire/blob/main/LICENSE.TXT +Copyright: (c) Microsoft ${YEAR} +ShortDescription: Prerelease CLI tool for building observable, production-ready distributed applications with Aspire +Description: > + Aspire CLI (aspire) is a command-line tool for creating, running, and managing + Aspire applications. It provides commands for project scaffolding, local development, + and deployment of cloud-native distributed applications. + This is the prerelease version of the Aspire CLI. +Tags: +- dotnet +- aspire +- cloud-native +- distributed-systems +- developer-tools +- cli +- microservices +- containers +- prerelease +ReleaseNotesUrl: https://aspire.dev/whats-new/aspire-13-1/ +ManifestType: defaultLocale +ManifestVersion: 1.10.0 diff --git a/eng/winget/microsoft.aspire.prerelease/Aspire.yaml.template b/eng/winget/microsoft.aspire.prerelease/Aspire.yaml.template new file mode 100644 index 00000000000..a5f400edd78 --- /dev/null +++ b/eng/winget/microsoft.aspire.prerelease/Aspire.yaml.template @@ -0,0 +1,7 @@ +# yaml-language-server: $schema=https://aka.ms/winget-manifest.version.1.10.0.schema.json + +PackageIdentifier: Microsoft.Aspire.Prerelease +PackageVersion: "${VERSION}" +DefaultLocale: en-US +ManifestType: version +ManifestVersion: 1.10.0 diff --git a/eng/winget/microsoft.aspire/Aspire.installer.yaml.template b/eng/winget/microsoft.aspire/Aspire.installer.yaml.template new file mode 100644 index 00000000000..8f2d7050b0f --- /dev/null +++ b/eng/winget/microsoft.aspire/Aspire.installer.yaml.template @@ -0,0 +1,18 @@ +# yaml-language-server: $schema=https://aka.ms/winget-manifest.installer.1.10.0.schema.json + +PackageIdentifier: Microsoft.Aspire +PackageVersion: "${VERSION}" +InstallerType: zip +NestedInstallerType: portable +NestedInstallerFiles: +- RelativeFilePath: aspire.exe + PortableCommandAlias: aspire +Commands: +- aspire +InstallModes: +- silent +UpgradeBehavior: uninstallPrevious +ReleaseDate: ${RELEASE_DATE} +${INSTALLERS} +ManifestType: installer +ManifestVersion: 1.10.0 diff --git a/eng/winget/microsoft.aspire/Aspire.locale.en-US.yaml.template b/eng/winget/microsoft.aspire/Aspire.locale.en-US.yaml.template new file mode 100644 index 00000000000..e8a21e1de62 --- /dev/null +++ b/eng/winget/microsoft.aspire/Aspire.locale.en-US.yaml.template @@ -0,0 +1,32 @@ +# yaml-language-server: $schema=https://aka.ms/winget-manifest.defaultLocale.1.10.0.schema.json + +PackageIdentifier: Microsoft.Aspire +PackageVersion: "${VERSION}" +PackageLocale: en-US +Publisher: Microsoft Corporation +PublisherUrl: https://aspire.dev/ +PublisherSupportUrl: https://github.com/dotnet/aspire/issues +PrivacyUrl: https://privacy.microsoft.com/privacystatement +Moniker: aspire +PackageName: Aspire CLI +PackageUrl: https://aspire.dev/ +License: MIT +LicenseUrl: https://github.com/dotnet/aspire/blob/main/LICENSE.TXT +Copyright: (c) Microsoft ${YEAR} +ShortDescription: CLI tool for building observable, production-ready distributed applications with Aspire +Description: > + Aspire CLI (aspire) is a command-line tool for creating, running, and managing + Aspire applications. It provides commands for project scaffolding, local development, + and deployment of cloud-native distributed applications. +Tags: +- dotnet +- aspire +- cloud-native +- distributed-systems +- developer-tools +- cli +- microservices +- containers +ReleaseNotesUrl: https://aspire.dev/whats-new/aspire-13-1/ +ManifestType: defaultLocale +ManifestVersion: 1.10.0 diff --git a/eng/winget/microsoft.aspire/Aspire.yaml.template b/eng/winget/microsoft.aspire/Aspire.yaml.template new file mode 100644 index 00000000000..af60cb2c3e3 --- /dev/null +++ b/eng/winget/microsoft.aspire/Aspire.yaml.template @@ -0,0 +1,7 @@ +# yaml-language-server: $schema=https://aka.ms/winget-manifest.version.1.10.0.schema.json + +PackageIdentifier: Microsoft.Aspire +PackageVersion: "${VERSION}" +DefaultLocale: en-US +ManifestType: version +ManifestVersion: 1.10.0