From 72e7df702d0050fabd32b20388de8250a07eca04 Mon Sep 17 00:00:00 2001 From: Ruslan Ibrahimau <493656+IRus@users.noreply.github.com> Date: Sun, 18 Oct 2026 03:14:24 +0300 Subject: [PATCH 1/2] Test Windows wrapper bootstrap from PowerShell 7 --- scripts/test-wrappers.main.kts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/scripts/test-wrappers.main.kts b/scripts/test-wrappers.main.kts index 9a6817a..9cb5fea 100755 --- a/scripts/test-wrappers.main.kts +++ b/scripts/test-wrappers.main.kts @@ -69,7 +69,8 @@ val target = when { System.getProperty("os.arch") in setOf("aarch64", "arm64") -> "linux-arm64" else -> "linux-x64" } -temporary("ktc wrapper test ") { tmp -> +for (shell in if (windows) listOf("cmd", "pwsh") else listOf("sh")) temporary("ktc $shell wrapper test ") { tmp -> + println("Testing wrapper from $shell") val binaries = tmp.resolve("input").apply { mkdir() } for (platform in listOf("macos-arm64", "linux-x64", "linux-arm64", "windows-x64")) { binary.copyTo(binaries.resolve("ktc-plugins-$version-$platform" + if (platform == "windows-x64") ".exe" else "")) @@ -87,7 +88,16 @@ temporary("ktc wrapper test ") { tmp -> if (!windows) check(cachedBinary.setExecutable(true, false)) val environment = mutableMapOf("KTC_PLUGINS_BINARY_CACHE" to tmp.resolve("offline binary cache").path, "KTC_PLUGINS_BINARY" to null) val wrapper = output.resolve(if (windows) "ktc-plugins.bat" else "ktc-plugins").path - fun run(vararg arguments: String) = command(tmp, if (windows) batch(wrapper, arguments.toList()) else listOf(wrapper) + arguments, environment) + fun run(vararg arguments: String): CommandResult { + val invocation = when (shell) { + "cmd" -> batch(wrapper, arguments.toList()) + // Keep PowerShell 7's real environment when it starts the batch wrapper. + "pwsh" -> listOf("pwsh", "-NoLogo", "-NoProfile", "-NonInteractive", "-Command", + "& " + (listOf(wrapper) + arguments).joinToString(" ") { "'${it.replace("'", "''")}'" } + "; exit \$LASTEXITCODE") + else -> listOf(wrapper) + arguments + } + return command(tmp, invocation, environment) + } fun concurrentVersions() { java.util.concurrent.Executors.newFixedThreadPool(4).use { pool -> val futures = (1..4).map { pool.submit { run("--version") } } From 115578f050bfbfba975b6996afa81e4725152038 Mon Sep 17 00:00:00 2001 From: Ruslan Ibrahimau <493656+IRus@users.noreply.github.com> Date: Sun, 18 Oct 2026 03:17:36 +0300 Subject: [PATCH 2/2] Fix inherited PowerShell module paths and prepare 0.3.1 --- .github/workflows/ci.yaml | 2 +- CHANGELOG.md | 19 ++++++++++++++++++- README.md | 18 +++++++++--------- core/src/Cli.kt | 2 +- ktc-plugins | 2 +- ktc-plugins.bat | 4 +++- 6 files changed, 33 insertions(+), 14 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 70c0417..08ab9bd 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -6,7 +6,7 @@ on: pull_request: workflow_dispatch: env: - KTC_PLUGINS_VERSION: 0.3.0 + KTC_PLUGINS_VERSION: 0.3.1 permissions: contents: read jobs: diff --git a/CHANGELOG.md b/CHANGELOG.md index 6333424..5b1999d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,22 @@ separately from tagged releases. ## [Unreleased] +## [0.3.1] - 2026-10-18 + +### Fixed + +- Windows wrapper bootstrap clears the inherited `PSModulePath` before starting + Windows PowerShell, so launches from PowerShell 7 can resolve `Get-FileHash` + and verify the downloaded or cached executable. The change is local to the wrapper. +- Windows wrapper tests run through both `cmd.exe` and `pwsh`, covering cached + launches, argument forwarding, empty-cache downloads, concurrent bootstrap and + corrupt-download rejection. + +### Compatibility + +- CLI commands, plugin manifests and lockfiles are unchanged. Update both consumer + launchers to receive the Windows bootstrap fix. + ## [0.3.0] - 2026-10-08 ### Changed @@ -97,7 +113,8 @@ separately from tagged releases. - Unix and Windows launchers with pinned SHA-256 verification, native release binaries, checksums and CI checks across all four runtime targets. -[Unreleased]: https://github.com/Heapy/ktc-plugins/compare/v0.3.0...HEAD +[Unreleased]: https://github.com/Heapy/ktc-plugins/compare/v0.3.1...HEAD +[0.3.1]: https://github.com/Heapy/ktc-plugins/compare/v0.3.0...v0.3.1 [0.3.0]: https://github.com/Heapy/ktc-plugins/compare/v0.2.0...v0.3.0 [0.2.0]: https://github.com/Heapy/ktc-plugins/compare/v0.1.0...v0.2.0 [0.1.0]: https://github.com/Heapy/ktc-plugins/releases/tag/v0.1.0 diff --git a/README.md b/README.md index f7783cc..ad86f0f 100644 --- a/README.md +++ b/README.md @@ -6,16 +6,16 @@ installs a self-contained plugin module, and registers it in your project. See [CHANGELOG.md](CHANGELOG.md) for release history and compatibility notes. -## Get version 0.3.0 +## Get version 0.3.1 -Download the generated launchers from the [0.3.0 release](https://github.com/Heapy/ktc-plugins/releases/tag/v0.3.0) +Download the generated launchers from the [0.3.1 release](https://github.com/Heapy/ktc-plugins/releases/tag/v0.3.1) into your consumer project and commit them: ```sh curl --fail --location --output ktc-plugins \ - https://github.com/Heapy/ktc-plugins/releases/download/v0.3.0/ktc-plugins + https://github.com/Heapy/ktc-plugins/releases/download/v0.3.1/ktc-plugins curl --fail --location --output ktc-plugins.bat \ - https://github.com/Heapy/ktc-plugins/releases/download/v0.3.0/ktc-plugins.bat + https://github.com/Heapy/ktc-plugins/releases/download/v0.3.1/ktc-plugins.bat chmod +x ktc-plugins ./ktc-plugins --help ``` @@ -154,8 +154,8 @@ The installer changes no Git index entries; commit vendored deletions yourself. ## Update project launchers ```sh -./ktc-plugins wrapper update --version 0.3.0 --dry-run -./ktc-plugins wrapper update --version 0.3.0 +./ktc-plugins wrapper update --version 0.3.1 --dry-run +./ktc-plugins wrapper update --version 0.3.1 ``` Choose an exact **published stable** version. The updater verifies GitHub asset digests, @@ -364,10 +364,10 @@ merging remain unsupported. Installation does not execute plugin code; subsequen ./kotlin test -m core --platform jvm --platform macosArm64 ./kotlin build -m cli-macos -m cli-linux -m cli-windows -v release kotlinr scripts/stage-binaries.main.kts macosArm64 linuxX64 linuxArm64 mingwX64 -kotlinr scripts/package-release.main.kts --version 0.3.0 \ +kotlinr scripts/package-release.main.kts --version 0.3.1 \ --binaries build/binaries --output build/release -kotlinr scripts/smoke.main.kts build/binaries/ktc-plugins-0.3.0-macos-arm64 -kotlinr scripts/test-wrappers.main.kts build/binaries/ktc-plugins-0.3.0-macos-arm64 +kotlinr scripts/smoke.main.kts build/binaries/ktc-plugins-0.3.1-macos-arm64 +kotlinr scripts/test-wrappers.main.kts build/binaries/ktc-plugins-0.3.1-macos-arm64 ``` Cross-compilation requires a supported Toolchain compiler host. Build individual diff --git a/core/src/Cli.kt b/core/src/Cli.kt index ebdbd95..8a650e8 100644 --- a/core/src/Cli.kt +++ b/core/src/Cli.kt @@ -1,7 +1,7 @@ package io.heapy.ktcplugins -const val VERSION = "0.3.0" +const val VERSION = "0.3.1" private val usage = """ ktc-plugins $VERSION — install GitHub sources as local Kotlin Toolchain plugins diff --git a/ktc-plugins b/ktc-plugins index 3a12e4b..4fdc994 100755 --- a/ktc-plugins +++ b/ktc-plugins @@ -1,7 +1,7 @@ #!/bin/sh set -eu umask 077 -version='0.3.0' # VERSION +version='0.3.1' # VERSION fail() { printf '%s\n' "ktc-plugins: $*" >&2; exit 1; } # Explicit development override; published wrappers always verify the pinned artifact. if [ -n "${KTC_PLUGINS_BINARY:-}" ]; then diff --git a/ktc-plugins.bat b/ktc-plugins.bat index fd0fe6f..b0ad3bc 100644 --- a/ktc-plugins.bat +++ b/ktc-plugins.bat @@ -1,10 +1,12 @@ @echo off setlocal DisableDelayedExpansion -set "ktc_version=0.3.0" +set "ktc_version=0.3.1" if defined KTC_PLUGINS_BINARY goto run if not defined KTC_PLUGINS_BINARY_CACHE set "KTC_PLUGINS_BINARY_CACHE=%LOCALAPPDATA%\ktc-plugins\binaries" set "KTC_PLUGINS_BINARY=%KTC_PLUGINS_BINARY_CACHE%\%ktc_version%\windows-x64\ktc-plugins-%ktc_version%-windows-x64.exe" set "KTC_PLUGINS_WRAPPER=%~f0" +rem Rebuild Windows PowerShell's module path when called through PowerShell 7. +set "PSModulePath=" powershell.exe -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command "$t=[IO.File]::ReadAllText($env:KTC_PLUGINS_WRAPPER); & ([scriptblock]::Create($t.Substring($t.LastIndexOf('# POWERSHELL')+12)))" if errorlevel 1 exit /b 1 :run