Skip to content

Winget manifest uploader #620

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 21 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .github/workflows/winget.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Publish to Winget

on:
release:
types: [published]
Comment on lines +3 to +5

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
on:
release:
types: [published]
on:
workflow_dispatch:
release:
types: [published]

Let's add workflow_dispatch so that the job can be re-run manually from the Actions tab



env:
REGEX: 'DSC-(\d+\.\d+\.\d+(?:-preview\.\d+)?)-(?:x86_64|aarch64)-pc-windows-msvc\.zip'
Comment on lines +8 to +9

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
env:
REGEX: 'DSC-(\d+\.\d+\.\d+(?:-preview\.\d+)?)-(?:x86_64|aarch64)-pc-windows-msvc\.zip'
env:
WINGET_CREATE_GITHUB_TOKEN: ${{ secrets.WINGET_CREATE_GITHUB_TOKEN }}

removing REGEX env variable as not needed (assuming you agree with my suggestions above). Adding the WINGET_CREATE_GITHUB_TOKEN environment variable to be used for submission


jobs:
publish:
runs-on: windows-latest # Action can only run on Windows
steps:
- name: Publish Microsoft.DSC ${{ github.event.release.prerelease && 'Preview' || 'Stable' }}
run: |
$assets = '${{ toJSON(github.event.release.assets) }}' | ConvertFrom-Json
$wingetRelevantAsset = $assets | Where-Object { $_.name -like '*.zip' -and $_.name -like '*.msixbundle' } | Select-Object -First 1

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code looks like it's either only gonna get the zip URL OR the MSIX URL, and we don't know which will it be?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
$wingetRelevantAsset = $assets | Where-Object { $_.name -like '*.zip' -and $_.name -like '*.msixbundle' } | Select-Object -First 1
$x64ZIPInstallerUrl = $assets | Where-Object -Property name -like '*x86_64-pc-windows-msvc.zip' | Select-Object -ExpandProperty browser_download_url
$arm64InstallerUrl = $assets | Where-Object -Property name -like '*aarch64-pc-windows-msvc.zip' | Select-Object -ExpandProperty browser_download_url
$msixInstallerURL = $assets | Where-Object -Property name -like '*Win.msixbundle' | Select-Object -ExpandProperty browser_download_url

As I mentioned in a comment previously, the current code looks like it's either only gonna get the zip URL OR the MSIX URL, and we don't know which will it be. We should get URLs something like this instead

$regex = [Regex]::New($env:REGEX)
$version = $regex.Match($wingetRelevantAsset.name).Groups[1].Value
Comment on lines +19 to +20

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
$regex = [Regex]::New($env:REGEX)
$version = $regex.Match($wingetRelevantAsset.name).Groups[1].Value
$version = (${{ toJSON(github.event.release.tag_name) }}).Trim('v')

We don't need to perform regex matching. The version info is already available in the GitHub release event

$wingetPackage = "Microsoft.DSC${{ github.event.release.prerelease && '.Preview' || '' }}"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
$wingetPackage = "Microsoft.DSC${{ github.event.release.prerelease && '.Preview' || '' }}"
$wingetPackage = "Microsoft.DSC"

Personally I would suggest not handling Preview releases for now to get this merged & handle preview in a future PR. The issue is that WinGet pipelines enforce that the PackageVersion should exactly match the MSIX version. For reference, the GitHub version for the latest preview is 3.2.0-preview.2, but the MSIX version is actually 3.2.2. Would need to add some logic to modify the version only for preview to get the MSIX version. You may do it here if you want, but I would suggest a separate PR since there are enough comments in this one already :D

& curl.exe -JLO https://aka.ms/wingetcreate/latest
& .\wingetcreate.exe update $wingetPackage -s -v $version -u $wingetRelevantAsset.browser_download_url -t "${{ secrets.WINGET_TOKEN }}"
Comment on lines +25 to +26

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
& .\wingetcreate.exe update $wingetPackage -s -v $version -u $wingetRelevantAsset.browser_download_url -t "${{ secrets.WINGET_TOKEN }}"
& .\wingetcreate.exe update $wingetPackage --version $version --urls $x64ZIPInstallerUrl $arm64InstallerUrl $msixInstallerURL --submit

Suggested changes to the command based on feedback above. Use of --token param is deprecated in winget-create. We should be using the WINGET_CREATE_GITHUB_TOKEN environment variable instead.

116 changes: 72 additions & 44 deletions build.ps1
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@

param(
[switch]$Release,
[ValidateSet('current','aarch64-pc-windows-msvc','x86_64-pc-windows-msvc','aarch64-apple-darwin','x86_64-apple-darwin','aarch64-unknown-linux-gnu','aarch64-unknown-linux-musl','x86_64-unknown-linux-gnu','x86_64-unknown-linux-musl')]
[ValidateSet('current', 'aarch64-pc-windows-msvc', 'x86_64-pc-windows-msvc', 'aarch64-apple-darwin', 'x86_64-apple-darwin', 'aarch64-unknown-linux-gnu', 'aarch64-unknown-linux-musl', 'x86_64-unknown-linux-gnu', 'x86_64-unknown-linux-musl')]
$architecture = 'current',
[switch]$Clippy,
[switch]$SkipBuild,
[ValidateSet('msix','msix-private','msixbundle','tgz','zip')]
[ValidateSet('msix', 'msix-private', 'msixbundle', 'tgz', 'zip')]
$packageType,
[switch]$Test,
[switch]$GetPackageVersion,
Expand All @@ -19,6 +19,9 @@ param(
[switch]$UpdateLockFile,
[switch]$Audit,
[switch]$UseCFSAuth,
[switch]$SubmitWinGetManifest,
[switch]$PreRelease,
[string]$GitToken,
[switch]$Clean,
[switch]$Verbose
)
Expand Down Expand Up @@ -142,8 +145,7 @@ function Find-LinkExe {
$linkexe = (Get-Location).Path
Write-Verbose -Verbose "Using $linkexe"
$linkexe
}
finally {
} finally {
Pop-Location
}
}
Expand All @@ -170,8 +172,7 @@ if ($null -ne $packageType) {
if (!$IsWindows) {
curl https://sh.rustup.rs -sSf | sh -s -- -y
$env:PATH += ":$env:HOME/.cargo/bin"
}
else {
} else {
Invoke-WebRequest 'https://static.rust-lang.org/rustup/dist/i686-pc-windows-gnu/rustup-init.exe' -OutFile 'temp:/rustup-init.exe'
Write-Verbose -Verbose "Use the default settings to ensure build works"
& 'temp:/rustup-init.exe' -y
Expand Down Expand Up @@ -214,9 +215,9 @@ if (!$SkipBuild -and !$SkipLinkCheck -and $IsWindows -and !(Get-Command 'link.ex
if (!(Test-Path $BuildToolsPath)) {
Write-Verbose -Verbose "link.exe not found, installing C++ build tools"
Invoke-WebRequest 'https://aka.ms/vs/17/release/vs_BuildTools.exe' -OutFile 'temp:/vs_buildtools.exe'
$arg = @('--passive','--add','Microsoft.VisualStudio.Workload.VCTools','--includerecommended')
$arg = @('--passive', '--add', 'Microsoft.VisualStudio.Workload.VCTools', '--includerecommended')
if ($env:PROCESSOR_ARCHITECTURE -eq 'ARM64') {
$arg += '--add','Microsoft.VisualStudio.Component.VC.Tools.ARM64'
$arg += '--add', 'Microsoft.VisualStudio.Component.VC.Tools.ARM64'
}
Start-Process -FilePath 'temp:/vs_buildtools.exe' -ArgumentList $arg -Wait
Remove-Item temp:/vs_installer.exe -ErrorAction Ignore
Expand Down Expand Up @@ -246,8 +247,7 @@ $flags = @($Release ? '-r' : $null)
if ($architecture -eq 'current') {
$path = ".\target\$configuration"
$target = Join-Path $PSScriptRoot 'bin' $configuration
}
else {
} else {
$flags += '--target'
$flags += $architecture
$path = ".\target\$architecture\$configuration"
Expand Down Expand Up @@ -290,8 +290,7 @@ if (!$SkipBuild) {
$env:CARGO_REGISTRIES_POWERSHELL_CREDENTIAL_PROVIDER = 'cargo:token'
$env:CARGO_REGISTRIES_POWERSHELL_INDEX = "sparse+https://pkgs.dev.azure.com/powershell/PowerShell/_packaging/powershell~force-auth/Cargo/index/"
}
}
else {
} else {
Write-Warning "Azure CLI not found, proceeding with anonymous access."
}
}
Expand Down Expand Up @@ -348,8 +347,7 @@ if (!$SkipBuild) {
if (($project -eq 'tree-sitter-dscexpression') -or ($project -eq 'tree-sitter-ssh-server-config')) {
if ($UpdateLockFile) {
cargo generate-lockfile
}
else {
} else {
if ($Audit) {
if ($null -eq (Get-Command cargo-audit -ErrorAction Ignore)) {
cargo install cargo-audit --features=fix
Expand All @@ -362,26 +360,21 @@ if (!$SkipBuild) {
}
}

if (Test-Path "./Cargo.toml")
{
if (Test-Path "./Cargo.toml") {
if ($Clippy) {
if ($clippy_unclean_projects -contains $project) {
Write-Verbose -Verbose "Skipping clippy for $project"
}
elseif ($pedantic_unclean_projects -contains $project) {
} elseif ($pedantic_unclean_projects -contains $project) {
Write-Verbose -Verbose "Running clippy for $project"
cargo clippy @flags -- -Dwarnings
}
else {
} else {
Write-Verbose -Verbose "Running clippy with pedantic for $project"
cargo clippy @flags --% -- -Dwarnings -Dclippy::pedantic
}
}
else {
} else {
if ($UpdateLockFile) {
cargo generate-lockfile
}
else {
} else {
if ($Audit) {
if ($null -eq (Get-Command cargo-audit -ErrorAction Ignore)) {
cargo install cargo-audit --features=fix
Expand Down Expand Up @@ -409,8 +402,7 @@ if (!$SkipBuild) {
if ($IsWindows) {
Copy-Item "$path/$binary.exe" $target -ErrorAction Ignore -Verbose
Copy-Item "$path/$binary.pdb" $target -ErrorAction Ignore -Verbose
}
else {
} else {
Copy-Item "$path/$binary" $target -ErrorAction Ignore -Verbose
}

Expand Down Expand Up @@ -468,8 +460,7 @@ if (!$Clippy -and !$SkipBuild) {
$dirSeparator = [System.IO.Path]::DirectorySeparatorChar
if ($Release) {
$oldTarget = $target.Replace($dirSeparator + 'release', $dirSeparator + 'debug')
}
else {
} else {
$oldTarget = $target.Replace($dirSeparator + 'debug', $dirSeparator + 'release')
}
$env:PATH = $env:PATH.Replace($oldTarget, '')
Expand Down Expand Up @@ -508,15 +499,14 @@ if ($Test) {

if ($IsWindows) {
# PSDesiredStateConfiguration module is needed for Microsoft.Windows/WindowsPowerShell adapter
$FullyQualifiedName = @{ModuleName="PSDesiredStateConfiguration";ModuleVersion="2.0.7"}
if (-not(Get-Module -ListAvailable -FullyQualifiedName $FullyQualifiedName))
{
$FullyQualifiedName = @{ModuleName = "PSDesiredStateConfiguration"; ModuleVersion = "2.0.7" }
if (-not(Get-Module -ListAvailable -FullyQualifiedName $FullyQualifiedName)) {
Install-PSResource -Name PSDesiredStateConfiguration -Version 2.0.7 -Repository $repository -TrustRepository
}
}

if (-not(Get-Module -ListAvailable -Name Pester))
{ "Installing module Pester"
if (-not(Get-Module -ListAvailable -Name Pester)) {
"Installing module Pester"
Install-PSResource Pester -WarningAction Ignore -Repository $repository -TrustRepository
}

Expand All @@ -529,8 +519,7 @@ if ($Test) {
Write-Host -ForegroundColor Cyan "Testing $project ..."
try {
Push-Location "$PSScriptRoot/$project"
if (Test-Path "./Cargo.toml")
{
if (Test-Path "./Cargo.toml") {
cargo test

if ($LASTEXITCODE -ne 0) {
Expand Down Expand Up @@ -559,8 +548,8 @@ if ($Test) {
"Updated PSModulePath is:"
$env:PSModulePath

if (-not(Get-Module -ListAvailable -Name Pester))
{ "Installing module Pester"
if (-not(Get-Module -ListAvailable -Name Pester)) {
"Installing module Pester"
$InstallTargetDir = ($env:PSModulePath -split ";")[0]
Find-PSResource -Name 'Pester' -Repository $repository | Save-PSResource -Path $InstallTargetDir -TrustRepository
}
Expand All @@ -582,8 +571,7 @@ function Find-MakeAppx() {
# try to find
if (!$UseX64MakeAppx -and $architecture -eq 'aarch64-pc-windows-msvc') {
$arch = 'arm64'
}
else {
} else {
$arch = 'x64'
}

Expand Down Expand Up @@ -628,8 +616,7 @@ if ($packageType -eq 'msixbundle') {
Write-Verbose -Verbose "Preview version detected"
if ($isPrivate) {
$productName += "-Private"
}
else {
} else {
$productName += "-Preview"
}
# save preview number
Expand All @@ -646,8 +633,7 @@ if ($packageType -eq 'msixbundle') {

if ($isPrivate) {
$displayName += "-Private"
}
else {
} else {
$displayName += "-Preview"
}
}
Expand Down Expand Up @@ -797,4 +783,46 @@ if ($packageType -eq 'msixbundle') {
Write-Host -ForegroundColor Green "`ntar.gz file is created at $tarFile"
}

$env:RUST_BACKTRACE=1
function Submit-DSCWinGetAssets {
param(
[string]$GitToken,
[switch] $IsPreRelease
)

$project = 'PowerShell/DSC'
$packageId = 'Microsoft.DSC'
$restParameters = @{
SslProtocol = 'Tls13'
Headers = @{'X-GitHub-Api-Version' = '2022-11-28' }
}

$assets = ((Invoke-RestMethod -uri "https://api.github.com/repos/$Project/releases" -Headers $restParameters) |
Where-Object -Property prerelease -EQ $IsPreRelease.IsPresent |
Select-Object -First 1 -Property assets).assets # ExpandProperty did not work
# Grab the download URLs for supported WinGet

$downloadUrls = $assets.Where({ $_.content_type -in @('application/zip', 'application/octet-stream') }).browser_download_url

if (-not (Get-Command wingetcreate -ErrorAction SilentlyContinue)) {
Invoke-RestMethod https://aka.ms/wingetcreate/latest -OutFile wingetcreate.exe
}

# TODO: Version number might change in the future
$url = $downloadUrls[0]
if ($url -match 'v(\d+\.\d+\.\d+)-preview\.(\d+)') {
$firstPart = $matches[1].Remove(3) # Remove the last digit
$lastPart = $matches[2] + ".0"
$version = "$firstPart.$lastPart"

$packageId = "$packageId.Preview"
}


& wingetcreate.exe update $packageId --version $version --urls $downloadUrls --submit --token $GitToken
}

if ($SubmitWinGetManifest) {
Submit-DSCWinGetAssets -GitToken $GitToken -IsPreRelease:$PreRelease
}

$env:RUST_BACKTRACE = 1
Loading