Remove Spotify and simplify Windows winget flow

This commit is contained in:
Fabio Scotto di Santolo
2026-04-02 16:36:04 +02:00
parent 27025126b3
commit 019b7f3122
2 changed files with 7 additions and 111 deletions

View File

@@ -29,9 +29,6 @@ windows_winget_packages:
name: Windows Terminal
- id: Postman.Postman
name: Postman
- id: Spotify.Spotify
name: Spotify
scope: user
- id: Telegram.TelegramDesktop
name: Telegram Desktop

View File

@@ -128,116 +128,15 @@
script: |
$packageId = '{{ item.id }}'
$packageName = '{{ item.name | default(item.id) }}'
$packageScope = '{{ item.scope | default('' ) }}'
$packageIdRegex = [regex]::Escape($packageId)
$installArgs = @(
'install'
'--id', $packageId
'--exact'
'--silent'
'--accept-package-agreements'
'--accept-source-agreements'
'--disable-interactivity'
)
if (-not [string]::IsNullOrWhiteSpace($packageScope)) {
$installArgs += @('--scope', $packageScope)
$installed = & winget list --id $packageId --exact --accept-source-agreements --disable-interactivity 2>$null
if ($LASTEXITCODE -eq 0 -and $installed -match [regex]::Escape($packageId)) {
$Ansible.Changed = $false
return
}
if ($packageScope -ne 'user') {
$installed = & winget list --id $packageId --exact --accept-source-agreements --disable-interactivity 2>$null
if ($LASTEXITCODE -eq 0 -and $installed -match $packageIdRegex) {
$Ansible.Changed = $false
return
}
}
if ($packageScope -eq 'user') {
$interactiveUser = (Get-CimInstance Win32_ComputerSystem).UserName
if ([string]::IsNullOrWhiteSpace($interactiveUser)) {
throw "Failed to install $packageName with winget: no interactive Windows user session is available for a user-scoped install."
}
$taskName = "AnsibleWinget-$($packageId -replace '[^A-Za-z0-9.-]', '-')"
$taskScriptPath = Join-Path $env:TEMP "$taskName.ps1"
$stdoutPath = Join-Path $env:TEMP "$taskName.stdout.log"
$stderrPath = Join-Path $env:TEMP "$taskName.stderr.log"
$resultPath = Join-Path $env:TEMP "$taskName.result.json"
$quotedArgs = ($installArgs | ForEach-Object { '"' + ($_ -replace '"', '""') + '"' }) -join ', '
$taskScript = @(
"`$ErrorActionPreference = 'Stop'",
"function Test-PackageInstalled {",
" `$installed = & winget.exe list --id '$packageId' --exact --accept-source-agreements --disable-interactivity 2>`$null",
" return (`$LASTEXITCODE -eq 0 -and `$installed -match '$packageIdRegex')",
"}",
"`$result = @{ changed = `$false; installed = `$false }",
"if (-not (Test-PackageInstalled)) {",
"`$installArgs = @($quotedArgs)",
"`$process = Start-Process -FilePath 'winget.exe' -ArgumentList `$installArgs -Wait -PassThru -NoNewWindow -RedirectStandardOutput '$stdoutPath' -RedirectStandardError '$stderrPath'",
" if (`$process.ExitCode -ne 0) { exit `$process.ExitCode }",
" `$deadline = (Get-Date).AddMinutes(2)",
" do {",
" Start-Sleep -Seconds 2",
" `$result.installed = Test-PackageInstalled",
" } while ((Get-Date) -lt `$deadline -and -not `$result.installed)",
" if (-not `$result.installed) { throw 'Package was not detected after the user-scoped install completed.' }",
" `$result.changed = `$true",
"}",
"else {",
" `$result.installed = `$true",
"}",
"`$result | ConvertTo-Json -Compress | Set-Content -Path '$resultPath' -Encoding Ascii"
) -join [Environment]::NewLine
Set-Content -Path $taskScriptPath -Value $taskScript -Encoding Ascii
try {
$action = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument "-NoProfile -ExecutionPolicy Bypass -File `"$taskScriptPath`""
$principal = New-ScheduledTaskPrincipal -UserId $interactiveUser -LogonType InteractiveToken -RunLevel Limited
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -StartWhenAvailable
Register-ScheduledTask -TaskName $taskName -Action $action -Principal $principal -Settings $settings -Force | Out-Null
Start-ScheduledTask -TaskName $taskName
$deadline = (Get-Date).AddMinutes(10)
do {
Start-Sleep -Seconds 2
$task = Get-ScheduledTask -TaskName $taskName
$taskInfo = Get-ScheduledTaskInfo -TaskName $taskName
} while ((Get-Date) -lt $deadline -and ($task.State -ne 'Ready' -or $taskInfo.LastRunTime -eq [datetime]::MinValue))
if ($task.State -ne 'Ready' -or $taskInfo.LastRunTime -eq [datetime]::MinValue) {
throw "Failed to install $packageName with winget: timed out waiting for the user-scoped scheduled task to finish."
}
if ($taskInfo.LastTaskResult -ne 0) {
$stderr = if (Test-Path $stderrPath) { Get-Content -Path $stderrPath -Raw } else { '' }
$stdout = if (Test-Path $stdoutPath) { Get-Content -Path $stdoutPath -Raw } else { '' }
throw "Failed to install $packageName with winget. Exit code: $($taskInfo.LastTaskResult). Stdout: $stdout Stderr: $stderr"
}
if (-not (Test-Path $resultPath)) {
throw "Failed to install $packageName with winget: no result file was produced by the user-scoped scheduled task."
}
$result = Get-Content -Path $resultPath -Raw | ConvertFrom-Json
if (-not $result.installed) {
throw "Failed to install $packageName with winget: the package is still not detected after the user-scoped install task finished."
}
$Ansible.Changed = [bool]$result.changed
return
}
finally {
Unregister-ScheduledTask -TaskName $taskName -Confirm:$false -ErrorAction SilentlyContinue
Remove-Item -Path $taskScriptPath, $stdoutPath, $stderrPath, $resultPath -Force -ErrorAction SilentlyContinue
}
}
else {
& winget @installArgs
if ($LASTEXITCODE -ne 0) {
throw "Failed to install $packageName with winget"
}
& winget install --id $packageId --exact --silent --accept-package-agreements --accept-source-agreements --disable-interactivity
if ($LASTEXITCODE -ne 0) {
throw "Failed to install $packageName with winget"
}
$Ansible.Changed = $true