Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package topgrade for openSUSE:Factory checked in at 2026-05-25 21:54:47 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/topgrade (Old) and /work/SRC/openSUSE:Factory/.topgrade.new.2084 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "topgrade" Mon May 25 21:54:47 2026 rev:25 rq:1354989 version:17.5.1 Changes: -------- --- /work/SRC/openSUSE:Factory/topgrade/topgrade.changes 2026-05-16 19:26:32.659000524 +0200 +++ /work/SRC/openSUSE:Factory/.topgrade.new.2084/topgrade.changes 2026-05-25 21:58:45.829803001 +0200 @@ -1,0 +2,11 @@ +Sun May 24 23:09:44 UTC 2026 - Gerald Chen <[email protected]> + +- Update to version 17.5.1: + * chore: release v17.5.1 (#2025) + * fix(install-release): remove ir alias to avoid conflict with mono-mdk (#2036) + * chore(pre-commit): autoupdate (#2035) + * chore(deps): update github/codeql-action action to v4.35.5 (#2017) + * chore(deps): lock file maintenance (#2032) + * fix(powershell): handle unavailable Update-Module (#1993) + +------------------------------------------------------------------- Old: ---- topgrade-17.5.0.tar.zst New: ---- topgrade-17.5.1.tar.zst ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ topgrade.spec ++++++ --- /var/tmp/diff_new_pack.Sw8gBw/_old 2026-05-25 21:58:47.229860594 +0200 +++ /var/tmp/diff_new_pack.Sw8gBw/_new 2026-05-25 21:58:47.233860759 +0200 @@ -17,7 +17,7 @@ Name: topgrade -Version: 17.5.0 +Version: 17.5.1 Release: 0 Summary: Upgrade all the things License: GPL-3.0-only ++++++ _service ++++++ --- /var/tmp/diff_new_pack.Sw8gBw/_old 2026-05-25 21:58:47.269862240 +0200 +++ /var/tmp/diff_new_pack.Sw8gBw/_new 2026-05-25 21:58:47.273862404 +0200 @@ -3,7 +3,7 @@ <param name="url">https://github.com/topgrade-rs/topgrade.git</param> <param name="versionformat">@PARENT_TAG@</param> <param name="scm">git</param> - <param name="revision">v17.5.0</param> + <param name="revision">v17.5.1</param> <param name="match-tag">*</param> <param name="versionrewrite-pattern">v(\d+\.\d+\.\d+)</param> <param name="versionrewrite-replacement">\1</param> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.Sw8gBw/_old 2026-05-25 21:58:47.297863392 +0200 +++ /var/tmp/diff_new_pack.Sw8gBw/_new 2026-05-25 21:58:47.301863556 +0200 @@ -1,7 +1,7 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/topgrade-rs/topgrade.git</param> - <param name="changesrevision">4de8767a6753bf66dd744907009cab9cfb95249d</param></service><service name="tar_scm"> + <param name="changesrevision">efe095e8c5a587c7e97236e8754de7230306b044</param></service><service name="tar_scm"> <param name="url">https://ghproxy.net/https://github.com/topgrade-rs/topgrade.git</param> <param name="changesrevision">ef0a0d69bbe0cb08d6c4930ee18b734e03c215fb</param></service></servicedata> (No newline at EOF) ++++++ topgrade-17.5.0.tar.zst -> topgrade-17.5.1.tar.zst ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/topgrade-17.5.0/.github/workflows/check_security_vulnerability.yml new/topgrade-17.5.1/.github/workflows/check_security_vulnerability.yml --- old/topgrade-17.5.0/.github/workflows/check_security_vulnerability.yml 2026-05-15 20:54:34.000000000 +0200 +++ new/topgrade-17.5.1/.github/workflows/check_security_vulnerability.yml 2026-05-20 09:19:01.000000000 +0200 @@ -32,6 +32,6 @@ uses: microsoft/DevSkim-Action@4b5047945a44163b94642a1cecc0d93a3f428cc6 # v1.0.16 - name: Upload DevSkim scan results to GitHub Security tab - uses: github/codeql-action/upload-sarif@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4 + uses: github/codeql-action/upload-sarif@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5 with: sarif_file: devskim-results.sarif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/topgrade-17.5.0/.github/workflows/scorecards.yml new/topgrade-17.5.1/.github/workflows/scorecards.yml --- old/topgrade-17.5.0/.github/workflows/scorecards.yml 2026-05-15 20:54:34.000000000 +0200 +++ new/topgrade-17.5.1/.github/workflows/scorecards.yml 2026-05-20 09:19:01.000000000 +0200 @@ -71,6 +71,6 @@ # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4 + uses: github/codeql-action/upload-sarif@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5 with: sarif_file: results.sarif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/topgrade-17.5.0/.pre-commit-config.yaml new/topgrade-17.5.1/.pre-commit-config.yaml --- old/topgrade-17.5.0/.pre-commit-config.yaml 2026-05-15 20:54:34.000000000 +0200 +++ new/topgrade-17.5.1/.pre-commit-config.yaml 2026-05-20 09:19:01.000000000 +0200 @@ -17,7 +17,7 @@ - id: trailing-whitespace - repo: https://github.com/adhtruong/mirrors-typos - rev: v1.46.1 + rev: v1.46.2 hooks: - id: typos args: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/topgrade-17.5.0/CHANGELOG.md new/topgrade-17.5.1/CHANGELOG.md --- old/topgrade-17.5.0/CHANGELOG.md 2026-05-15 20:54:34.000000000 +0200 +++ new/topgrade-17.5.1/CHANGELOG.md 2026-05-20 09:19:01.000000000 +0200 @@ -7,6 +7,13 @@ ## [Unreleased] +## [17.5.1](https://github.com/topgrade-rs/topgrade/compare/v17.5.0...v17.5.1) - 2026-05-20 + +### Fixed + +- *(install-release)* remove ir alias to avoid conflict with mono-mdk ([#2036](https://github.com/topgrade-rs/topgrade/pull/2036)) +- *(powershell)* handle unavailable Update-Module ([#1993](https://github.com/topgrade-rs/topgrade/pull/1993)) + ## [17.5.0](https://github.com/topgrade-rs/topgrade/compare/v17.4.0...v17.5.0) - 2026-05-15 ### Added diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/topgrade-17.5.0/Cargo.lock new/topgrade-17.5.1/Cargo.lock --- old/topgrade-17.5.0/Cargo.lock 2026-05-15 20:54:34.000000000 +0200 +++ new/topgrade-17.5.1/Cargo.lock 2026-05-20 09:19:01.000000000 +0200 @@ -254,9 +254,9 @@ [[package]] name = "aws-lc-rs" -version = "1.16.3" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ec6fb3fe69024a75fa7e1bfb48aa6cf59706a101658ea01bfd33b2b248a038f" +checksum = "5ec2f1fc3ec205783a5da9a7e6c1509cc69dedf09a1949e412c1e18469326d00" dependencies = [ "aws-lc-sys", "zeroize", @@ -264,9 +264,9 @@ [[package]] name = "aws-lc-sys" -version = "0.40.0" +version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f50037ee5e1e41e7b8f9d161680a725bd1626cb6f8c7e901f91f942850852fe7" +checksum = "1a2f9779ce85b93ab6170dd940ad0169b5766ff848247aff13bb788b832fe3f4" dependencies = [ "cc", "cmake", @@ -450,9 +450,9 @@ [[package]] name = "clap_complete" -version = "4.6.4" +version = "4.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3e962dae2b1e5007fe9e3db363ddc43a8bf25546d279f7a8a4401204690e80c" +checksum = "e0a7a9bfdb35811f9e59832f0f05975114d2251b415fb534108e6f34060fd772" dependencies = [ "clap", ] @@ -1013,9 +1013,9 @@ [[package]] name = "filetime" -version = "0.2.28" +version = "0.2.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d5b2eef6fafbf69f877e55509ce5b11a760690ac9700a2921be067aa6afaef6" +checksum = "5c287a33c7f0a620c38e641e7f60827713987b3c0f26e8ddc9462cc69cf75759" dependencies = [ "cfg-if", "libc", @@ -1894,9 +1894,9 @@ [[package]] name = "nix" -version = "0.31.2" +version = "0.31.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d6d0705320c1e6ba1d912b5e37cf18071b6c2e9b7fa8215a1e8a7651966f5d3" +checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d" dependencies = [ "bitflags 2.11.1", "cfg-if", @@ -3339,7 +3339,7 @@ "toml_datetime 1.1.1+spec-1.1.0", "toml_parser", "toml_writer", - "winnow 1.0.2", + "winnow 1.0.3", ] [[package]] @@ -3383,7 +3383,7 @@ "indexmap", "toml_datetime 1.1.1+spec-1.1.0", "toml_parser", - "winnow 1.0.2", + "winnow 1.0.3", ] [[package]] @@ -3392,7 +3392,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" dependencies = [ - "winnow 1.0.2", + "winnow 1.0.3", ] [[package]] @@ -3409,7 +3409,7 @@ [[package]] name = "topgrade" -version = "17.5.0" +version = "17.5.1" dependencies = [ "chrono", "clap", @@ -4374,9 +4374,9 @@ [[package]] name = "winnow" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ee1708bef14716a11bae175f579062d4554d95be2c6829f518df847b7b3fdd0" +checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" dependencies = [ "memchr", ] @@ -4549,7 +4549,7 @@ "uds_windows", "uuid", "windows-sys 0.61.2", - "winnow 1.0.2", + "winnow 1.0.3", "zbus_macros", "zbus_names", "zvariant", @@ -4577,7 +4577,7 @@ checksum = "7074f3e50b894eac91750142016d30d0a89be8e67dbfd9704fb875825760e52d" dependencies = [ "serde", - "winnow 1.0.2", + "winnow 1.0.3", "zvariant", ] @@ -4603,9 +4603,9 @@ [[package]] name = "zerofrom" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" dependencies = [ "zerofrom-derive", ] @@ -4720,7 +4720,7 @@ "endi", "enumflags2", "serde", - "winnow 1.0.2", + "winnow 1.0.3", "zvariant_derive", "zvariant_utils", ] @@ -4748,5 +4748,5 @@ "quote", "serde", "syn", - "winnow 1.0.2", + "winnow 1.0.3", ] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/topgrade-17.5.0/Cargo.toml new/topgrade-17.5.1/Cargo.toml --- old/topgrade-17.5.0/Cargo.toml 2026-05-15 20:54:34.000000000 +0200 +++ new/topgrade-17.5.1/Cargo.toml 2026-05-20 09:19:01.000000000 +0200 @@ -6,7 +6,7 @@ license = "GPL-3.0-or-later" repository = "https://github.com/topgrade-rs/topgrade" rust-version = "1.88.0" -version = "17.5.0" +version = "17.5.1" exclude = ["doc/screenshot.gif", "BREAKINGCHANGES_dev.md"] edition = "2024" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/topgrade-17.5.0/locales/app.yml new/topgrade-17.5.1/locales/app.yml --- old/topgrade-17.5.0/locales/app.yml 2026-05-15 20:54:34.000000000 +0200 +++ new/topgrade-17.5.1/locales/app.yml 2026-05-20 09:19:01.000000000 +0200 @@ -152,6 +152,14 @@ zh_CN: "未安装 Powershell" zh_TW: "未安裝 Powershell" de: "Powershell ist nicht installiert" +"PowerShellGet Update-Module is unavailable or could not be loaded. Skipping PowerShell module updates.": + en: "PowerShellGet Update-Module is unavailable or could not be loaded. Skipping PowerShell module updates." + lt: "PowerShellGet Update-Module nepasiekiama arba jos nepavyko įkelti. Praleidžiamas PowerShell modulių atnaujinimas." + es: "PowerShellGet Update-Module no está disponible o no se pudo cargar. Se omite la actualización de módulos de PowerShell." + fr: "PowerShellGet Update-Module n'est pas disponible ou n'a pas pu être chargé. Mise à jour des modules PowerShell ignorée." + zh_CN: "PowerShellGet Update-Module 不可用或无法加载。正在跳过 PowerShell 模块更新。" + zh_TW: "PowerShellGet Update-Module 無法使用或無法載入。正在略過 PowerShell 模組更新。" + de: "PowerShellGet Update-Module ist nicht verfügbar oder konnte nicht geladen werden. PowerShell-Modulaktualisierung wird übersprungen." "Error detecting current distribution: {error}": en: "Error detecting current distribution: %{error}" lt: "Klaida nustatant dabartinę distribuciją: %{error}" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/topgrade-17.5.0/src/steps/generic.rs new/topgrade-17.5.1/src/steps/generic.rs --- old/topgrade-17.5.0/src/steps/generic.rs 2026-05-15 20:54:34.000000000 +0200 +++ new/topgrade-17.5.1/src/steps/generic.rs 2026-05-20 09:19:01.000000000 +0200 @@ -1206,25 +1206,70 @@ print_separator(t!("Powershell Modules Update")); - let mut cmd = "Update-Module".to_string(); + // For PowerShell Core, run without sudo (defaults to CurrentUser scope). + // For Windows PowerShell, use sudo (defaults to AllUsers scope). + let use_sudo = !powershell.is_pwsh(); + + if !powershell.has_command(ctx, "Update-Module", use_sudo)? { + let message = t!( + "PowerShellGet Update-Module is unavailable or could not be loaded. Skipping PowerShell module updates." + ) + .to_string(); + print_warning(&message); + return Err(SkipStep(message).into()); + } + + let cmd = powershell_update_modules_command(ctx.config().verbose(), ctx.config().yes(Step::Powershell)); + + println!("{}", t!("Updating modules...")); + + powershell.build_command(ctx, &cmd, use_sudo)?.status_checked() +} - if ctx.config().verbose() { - cmd.push_str(" -Verbose"); +fn powershell_update_modules_command(verbose: bool, assume_yes: bool) -> String { + let mut cmd = "$params = @{};".to_string(); + cmd.push_str(" $updateModule = Get-Command Update-Module -ErrorAction Stop;"); + + if verbose { + cmd.push_str(" $params['Verbose'] = $true;"); } - if ctx.config().yes(Step::Powershell) { - cmd.push_str(" -Force"); + if assume_yes { + // Avoid -Force here: PowerShellGet uses it to reinstall already-current modules, + // which can lock PackageManagement in the running Windows PowerShell session. + cmd.push_str(" $params['Confirm'] = $false;"); + cmd.push_str( + " if ($updateModule.Parameters.ContainsKey('AcceptLicense')) { $params['AcceptLicense'] = $true; }", + ); } - println!("{}", t!("Updating modules...")); + cmd.push_str(" & $updateModule @params"); + cmd +} + +#[cfg(test)] +mod powershell_tests { + use super::powershell_update_modules_command; + + #[test] + fn assume_yes_suppresses_confirmation_without_force() { + let cmd = powershell_update_modules_command(false, true); + + assert!(cmd.contains("$params['Confirm'] = $false")); + assert!(cmd.contains("$updateModule.Parameters.ContainsKey('AcceptLicense')")); + assert!(cmd.contains("$params['AcceptLicense'] = $true")); + assert!(cmd.contains("Get-Command Update-Module -ErrorAction Stop")); + assert!(cmd.contains("& $updateModule @params")); + assert!(!cmd.contains("-Force")); + assert!(!cmd.contains("exit 0")); + assert!(!cmd.contains("topgradeUpdateModule")); + } + + #[test] + fn verbose_sets_verbose_parameter() { + let cmd = powershell_update_modules_command(true, false); - if powershell.is_pwsh() { - // For PowerShell Core, run Update-Module without sudo since it defaults to CurrentUser scope - // and Update-Module updates all modules regardless of their original installation scope - powershell.build_command(ctx, &cmd, false)?.status_checked() - } else { - // For (Windows) PowerShell, use sudo since it defaults to AllUsers scope - // and may need administrator privileges - powershell.build_command(ctx, &cmd, true)?.status_checked() + assert!(cmd.contains("$params['Verbose'] = $true")); + assert!(!cmd.contains("AcceptLicense")); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/topgrade-17.5.0/src/steps/os/unix.rs new/topgrade-17.5.1/src/steps/os/unix.rs --- old/topgrade-17.5.0/src/steps/os/unix.rs 2026-05-15 20:54:34.000000000 +0200 +++ new/topgrade-17.5.1/src/steps/os/unix.rs 2026-05-20 09:19:01.000000000 +0200 @@ -1125,7 +1125,7 @@ /// See: <https://github.com/Rishang/install-release> pub fn run_install_release(ctx: &ExecutionContext) -> Result<()> { - let ir = require_one(["ir", "install-release"])?; + let ir = require("install-release")?; print_separator("Install Release"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/topgrade-17.5.0/src/steps/powershell.rs new/topgrade-17.5.1/src/steps/powershell.rs --- old/topgrade-17.5.0/src/steps/powershell.rs 2026-05-15 20:54:34.000000000 +0200 +++ new/topgrade-17.5.1/src/steps/powershell.rs 2026-05-20 09:19:01.000000000 +0200 @@ -1,3 +1,4 @@ +use std::ffi::OsStr; use std::path::PathBuf; use color_eyre::eyre::Result; @@ -58,12 +59,41 @@ self.is_pwsh } + pub fn has_command(&self, ctx: &ExecutionContext, command_name: &str, use_sudo: bool) -> Result<bool> { + let cmd = "& { param($command); if (Get-Command -Name $command -ErrorAction SilentlyContinue) { Write-Output 'true' } }"; + + let output = if use_sudo { + self.build_command_with_args(ctx, cmd, [command_name], true)? + .always() + .output_checked_utf8()? + } else { + self.build_command_internal_with_args(ctx, cmd, [command_name]) + .output_checked_utf8()? + }; + + Ok(output.stdout.trim().eq_ignore_ascii_case("true")) + } + /// Builds an "internal" powershell command pub fn build_command_internal(&self, ctx: &ExecutionContext, cmd: &str) -> Executor { + self.build_command_internal_with_args(ctx, cmd, std::iter::empty::<&str>()) + } + + /// Builds an "internal" powershell command with arguments passed after `-Command` + pub fn build_command_internal_with_args<S>( + &self, + ctx: &ExecutionContext, + cmd: &str, + args: impl IntoIterator<Item = S>, + ) -> Executor + where + S: AsRef<OsStr>, + { let mut command = ctx.execute(&self.path).always(); command.args(["-NoProfile", "-Command"]); command.arg(cmd); + command.args(args); // If topgrade was run from pwsh, but we are trying to run powershell, then // the inherited PSModulePath breaks module imports @@ -76,12 +106,20 @@ /// Builds a "primary" powershell command (uses dry-run if required): /// {powershell} -NoProfile -Command {cmd} - pub fn build_command<'a>( + pub fn build_command(&self, ctx: &ExecutionContext, cmd: &str, use_sudo: bool) -> Result<Executor> { + self.build_command_with_args(ctx, cmd, std::iter::empty::<&str>(), use_sudo) + } + + pub fn build_command_with_args<S>( &self, - ctx: &'a ExecutionContext, + ctx: &ExecutionContext, cmd: &str, + args: impl IntoIterator<Item = S>, use_sudo: bool, - ) -> Result<impl CommandExt + 'a> { + ) -> Result<Executor> + where + S: AsRef<OsStr>, + { let mut command = if use_sudo { let sudo = ctx.require_sudo()?; sudo.execute(ctx, &self.path)? @@ -97,6 +135,7 @@ command.args(["-NoProfile", "-Command"]); command.arg(cmd); + command.args(args); // If topgrade was run from pwsh, but we are trying to run powershell, then // the inherited PSModulePath breaks module imports ++++++ vendor.tar.zst ++++++ /work/SRC/openSUSE:Factory/topgrade/vendor.tar.zst /work/SRC/openSUSE:Factory/.topgrade.new.2084/vendor.tar.zst differ: char 7, line 1
