Repository navigation
fix(shim): update mise-shim.exe during self-update on Windows #8075
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
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -90,8 +90,13 @@ impl SelfUpdate { | |||||||||||||||||||
| let status = self.do_update()?; | ||||||||||||||||||||
|
|
||||||||||||||||||||
| if status.updated() { | ||||||||||||||||||||
| let version = style(status.version()).bright().yellow(); | ||||||||||||||||||||
| miseprintln!("Updated mise to {version}"); | ||||||||||||||||||||
| let version = status.version().to_string(); | ||||||||||||||||||||
| let styled_version = style(&version).bright().yellow(); | ||||||||||||||||||||
| miseprintln!("Updated mise to {styled_version}"); | ||||||||||||||||||||
| #[cfg(windows)] | ||||||||||||||||||||
| if let Err(e) = Self::update_mise_shim(&version) { | ||||||||||||||||||||
| warn!("Failed to update mise-shim.exe: {e}"); | ||||||||||||||||||||
| } | ||||||||||||||||||||
| } else { | ||||||||||||||||||||
| miseprintln!("mise is already up to date"); | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
@@ -167,6 +172,46 @@ impl SelfUpdate { | |||||||||||||||||||
| Ok(status) | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| #[cfg(windows)] | ||||||||||||||||||||
| fn update_mise_shim(version: &str) -> Result<()> { | ||||||||||||||||||||
| use crate::http::HTTP; | ||||||||||||||||||||
| use std::io::Read; | ||||||||||||||||||||
|
|
||||||||||||||||||||
| let url = format!( | ||||||||||||||||||||
| "https://github.com/jdx/mise/releases/download/{version}/mise-{version}-{}-{}.zip", | ||||||||||||||||||||
| *OS, *ARCH, | ||||||||||||||||||||
| ); | ||||||||||||||||||||
|
cursor[bot] marked this conversation as resolved.
Resolved
|
||||||||||||||||||||
| debug!("Downloading mise-shim.exe from {url}"); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| let temp_dir = tempfile::tempdir()?; | ||||||||||||||||||||
| let zip_path = temp_dir.path().join("mise.zip"); | ||||||||||||||||||||
| tokio::task::block_in_place(|| { | ||||||||||||||||||||
| tokio::runtime::Handle::current().block_on(HTTP.download_file(&url, &zip_path, None)) | ||||||||||||||||||||
| })?; | ||||||||||||||||||||
|
||||||||||||||||||||
| tokio::task::block_in_place(|| { | |
| tokio::runtime::Handle::current().block_on(HTTP.download_file(&url, &zip_path, None)) | |
| })?; | |
| if let Ok(handle) = tokio::runtime::Handle::try_current() { | |
| handle.block_on(HTTP.download_file(&url, &zip_path, None))?; | |
| } else { | |
| let rt = tokio::runtime::Runtime::new()?; | |
| rt.block_on(HTTP.download_file(&url, &zip_path, None))?; | |
| } |
Copilot
AI
Feb 9, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Writing the shim by buffering the entire file and then writing directly to the final destination increases the chance of leaving a partially-written mise-shim.exe if the process is interrupted mid-write. Prefer an atomic update pattern (write to a temporary file in the same directory, then rename/replace), and ideally stream from the ZIP entry into the temp file to avoid the extra buffering.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This new function has a critical bug and a potential improvement:
- Incorrect URL (Critical): The URL for downloading the release archive is constructed incorrectly. Release tags and asset names on GitHub for
miseare prefixed with av(e.g.,v2024.5.1), but theversionvariable here does not include it. This will cause downloads to fail with a 404 error. - Blocking in async context (Improvement): The function is synchronous and uses
tokio::task::block_in_place. Since it's called from anasynccontext, it's better to make itasyncandawaitthe download directly.
The suggestion below addresses both points. Note that you will also need to await the call to this function in run(), for which I've left a separate comment.
#[cfg(windows)]
async fn update_mise_shim(version: &str) -> Result<()> {
use crate::http::HTTP;
use std::io::Read;
let url = format!(
"https://github.com/jdx/mise/releases/download/v{version}/mise-v{version}-{}-{}.zip",
*OS, *ARCH,
);
debug!("Downloading mise-shim.exe from {url}");
let temp_dir = tempfile::tempdir()?;
let zip_path = temp_dir.path().join("mise.zip");
HTTP.download_file(&url, &zip_path, None).await?;
let file = fs::File::open(&zip_path)?;
let mut archive = zip::ZipArchive::new(file)?;
let mut shim_entry = match archive.by_name("mise/bin/mise-shim.exe") {
Ok(entry) => entry,
Err(_) => {
warn!("mise-shim.exe not found in release archive, skipping");
return Ok(());
}
};
let dest = env::MISE_BIN
.parent()
.expect("MISE_BIN should have a parent directory")
.join("mise-shim.exe");
let mut buf = Vec::new();
shim_entry.read_to_end(&mut buf)?;
xx::file::write(&dest, &buf)?;
debug!("Updated mise-shim.exe at {}", dest.display());
Ok(())
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To accommodate the suggested change of making
update_mise_shimanasyncfunction, this call needs to be awaited.