Skip to content

fix(zig): resolve master channel to the concrete nightly version#10423

Merged
jdx merged 1 commit into
jdx:mainfrom
JamBalaya56562:fix-zig-master-channel
Jun 14, 2026
Merged

fix(zig): resolve master channel to the concrete nightly version#10423
jdx merged 1 commit into
jdx:mainfrom
JamBalaya56562:fix-zig-master-channel

Conversation

@JamBalaya56562

@JamBalaya56562 JamBalaya56562 commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

What

zig@master was effectively frozen: mise resolved it to the literal "master", installed it under installs/zig/master, and never re-resolved it. So mise upgrade / mise outdated compared "master" == "master" and never picked up newer nightlies — a master install could sit weeks out of date (reported in #10251, stuck on a 23-day-old nightly).

Zig publishes master as a rolling channel in its download index (ziglang.org/download/index.json), whose version field points at the current nightly (e.g. 0.17.0-dev.836+...), with the build hosted under ziglang.org/builds/ (not on the source forge).

Fix

Resolve rolling channels to their concrete version at resolution time — like latest — so installs land in versioned dirs and mise upgrade/outdated track new builds:

  • Add Backend::is_rolling_channel, Backend::latest_installed_channel_version, and Backend::resolve_channel_version hooks (default no-op).
  • In ToolVersion::resolve_version, handle a channel like latest: reuse an installed build of that channel (never an unrelated installed release, so zig@master is not short-circuited to an installed stable) to keep hook-env/exec network-free; otherwise re-resolve via the backend; offline falls back to the literal channel.
  • Implement for zig master: read /master/version from the index, reuse the latest installed -dev nightly, and build the /builds/ tarball URL for the resolved dev version (not a top-level index key) in get_tarball_url / resolve_lock_info. minisign verification is unchanged.

mach-latest is left as a follow-up (the machengine index format is unverified).

Tests

  • e2e/core/test_zig_slow: with only a stable Zig installed, zig@master must resolve to a -dev nightly (not short-circuit to the stable), install under a versioned dir, and not create a frozen installs/zig/master.

Addresses discussion #10251.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Treats Zig master as a rolling release channel that resolves to concrete nightly/dev builds, so installs and upgrades automatically follow newer nightly versions.
    • Reuses the latest already-installed nightly when available to reduce network reliance during install/exec.
  • Documentation

    • Expanded Zig docs to clarify zig@master resolution and how upgrades keep moving forward.
  • Bug Fixes

    • Improved dev/nightly download resolution and lock handling so nightly installs use the correct build URLs.
  • Tests

    • Added slow end-to-end assertions covering zig@master nightly/dev behavior and naming.

@coderabbitai

coderabbitai Bot commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 7e929668-b00f-4d25-9e14-6b6eedb50bd4

📥 Commits

Reviewing files that changed from the base of the PR and between 875cff8 and a64ff0d.

📒 Files selected for processing (5)
  • docs/lang/zig.md
  • e2e/core/test_zig_slow
  • src/backend/mod.rs
  • src/plugins/core/zig.rs
  • src/toolset/tool_version.rs
✅ Files skipped from review due to trivial changes (1)
  • docs/lang/zig.md
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/toolset/tool_version.rs
  • e2e/core/test_zig_slow
  • src/backend/mod.rs
  • src/plugins/core/zig.rs

📝 Walkthrough

Walkthrough

The PR adds rolling release channel support for zig@master. The Backend trait gains three new default-stub methods for channel detection, installed-version lookup, and online resolution. ZigPlugin implements these to query ziglang.org/download/index.json and map master to a concrete -dev. nightly version, introduces a shared helper for nightly download URLs, and extends tarball URL and lock info resolution for dev builds. ToolVersion::resolve_version gains a new decision path that orchestrates these hooks. E2e tests and documentation cover the new behavior.

Changes

Zig Master Rolling Channel Support

Layer / File(s) Summary
Backend trait rolling channel hooks
src/backend/mod.rs
Adds is_rolling_channel, latest_installed_channel_version, and async resolve_channel_version to the Backend trait, each with a default stub implementation returning false, None, and Ok(None) respectively.
ZigPlugin rolling channel resolution and nightly URL construction
src/plugins/core/zig.rs
Implements the three Backend hooks for ZigPlugin (recognizing master as rolling, fetching the concrete version from ziglang.org/download/index.json, finding the latest -dev. install). Introduces nightly_tarball_url helper and extends get_tarball_url and resolve_lock_info to build /builds/ URLs for -dev. version strings.
ToolVersion rolling channel orchestration
src/toolset/tool_version.rs
Adds a new decision path in resolve_version that uses the Backend hooks to prefer already-installed channel builds, resolve online when needed, pass through the spec offline, and fall back to normal resolution.
E2e tests and documentation
e2e/core/test_zig_slow, docs/lang/zig.md
E2e test asserts mise x zig@master produces a -dev. version and a versioned install directory. Documentation describes zig@master nightly install and upgrade behavior.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant ToolVersion
  participant ZigPlugin
  participant ziglang.org

  User->>ToolVersion: resolve_version("master")
  ToolVersion->>ZigPlugin: is_rolling_channel("master")
  ZigPlugin-->>ToolVersion: true

  alt already installed & no latest_versions lookup
    ToolVersion->>ZigPlugin: latest_installed_channel_version("master")
    ZigPlugin-->>ToolVersion: "0.15.0-dev.XXXX" (cached install)
    ToolVersion-->>User: resolved to installed dev version
  else online resolution needed
    ToolVersion->>ZigPlugin: resolve_channel_version(config, "master")
    ZigPlugin->>ziglang.org: GET /download/index.json
    ziglang.org-->>ZigPlugin: JSON { master: { version: "0.15.0-dev.YYYY" } }
    ZigPlugin-->>ToolVersion: "0.15.0-dev.YYYY"
    ToolVersion->>ZigPlugin: get_tarball_url(tv with -dev. version)
    ZigPlugin->>ZigPlugin: nightly_tarball_url()
    ZigPlugin-->>ToolVersion: https://ziglang.org/builds/zig-{arch}-{os}-{version}.tar.xz
    ToolVersion-->>User: installs under versioned directory
  else offline
    ToolVersion-->>User: returns rolling spec unchanged
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Poem

🐇 Hop! The nightly builds arrive with grace,
master resolves to -dev. in its place,
No frozen channels blocking the stream—
Each upgrade chases nightly's gleaming dream.
JSON dances, downloads flow free,
The rolling rabbit hops with glee! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: resolving the master channel to concrete nightly versions, which is the core objective of the PR.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/plugins/core/zig.rs`:
- Around line 324-330: The HTTP_FETCH.json() call and subsequent pointer/parsing
operations use the `?` operator, which propagates transient network errors as
failures instead of allowing fallback to normal resolution. Modify this block to
catch any errors from the HTTP fetch or JSON parsing and return `Ok(None)` in
those cases, while still returning `Ok(Some(version_string))` when the channel
is successfully resolved. This allows the system to gracefully degrade when the
remote index is temporarily unavailable.
- Around line 297-308: The latest_installed_channel_version method is manually
sorting versions using Versioning::new which violates repo policy for version
ordering. Replace the manual sort using sorted_by_cached_key(|s|
(Versioning::new(s), s.clone())) with a call to the Backend API method
list_installed_versions_matching, which already provides versions in the correct
order according to backend semantics. Filter the results returned by this API
for -dev. versions and take the last one, removing the manual Versioning::new
sorting entirely.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 02bf78fc-93db-4ad4-adee-e6602cc8eae8

📥 Commits

Reviewing files that changed from the base of the PR and between 2543e50 and aa7d475.

📒 Files selected for processing (5)
  • docs/lang/zig.md
  • e2e/core/test_zig_slow
  • src/backend/mod.rs
  • src/plugins/core/zig.rs
  • src/toolset/tool_version.rs

Comment thread src/plugins/core/zig.rs Outdated
Comment thread src/plugins/core/zig.rs Outdated
@greptile-apps

greptile-apps Bot commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a long-standing issue where zig@master was never re-resolved after first install, causing it to stay frozen at an old nightly indefinitely. The fix teaches the Backend trait about "rolling channels" via three new hooks and implements them for zig's master channel.

  • Adds rolling-channel resolution in tool_version.rs mirroring the latest fast-path: reuse an installed nightly (network-free), otherwise re-resolve via the index, offline-fallback to the literal channel name.
  • Implements the hooks in zig.rs, constructs /builds/ tarball URLs via an extracted nightly_tarball_url helper (URL format confirmed correct against the live index), and adds an e2e test verifying the fix end-to-end.

Confidence Score: 5/5

Safe to merge. Channel-resolution logic is correctly scoped, the URL format matches what ziglang.org actually serves, minisign verification is unchanged, and the e2e test validates the core fix.

The three-level fast-path (installed nightly → network resolve → literal fallthrough) correctly mirrors the existing latest pattern and handles offline/prefer-offline modes consistently. The nightly_tarball_url helper produces the correct zig-{arch}-{os}-{version} format confirmed against the live index. No logic, safety, or correctness defects were found.

No files require special attention.

Important Files Changed

Filename Overview
src/plugins/core/zig.rs Core zig backend changes: adds nightly_tarball_url helper, implements rolling-channel hooks for master, and adds -dev. fallback arms to get_tarball_url and resolve_lock_info.
src/toolset/tool_version.rs Adds a rolling-channel resolution block before the normal version resolution path, correctly mirroring the latest fast-path semantics.
src/backend/mod.rs Adds three well-documented Backend trait methods with default no-op impls that preserve backward compat for all other backends.
e2e/core/test_zig_slow New test validates zig@master resolves to a -dev. nightly and does not create a frozen installs/zig/master directory.
docs/lang/zig.md Adds a master (nightly channel) documentation section explaining the new resolution and upgrade behavior.

Reviews (3): Last reviewed commit: "fix(zig): resolve master channel to the ..." | Re-trigger Greptile

Comment thread src/toolset/tool_version.rs Outdated
Comment thread src/plugins/core/zig.rs
@JamBalaya56562 JamBalaya56562 force-pushed the fix-zig-master-channel branch from aa7d475 to 875cff8 Compare June 14, 2026 05:10

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/toolset/tool_version.rs (1)

414-443: 💤 Low value

Clarify the fall-through comment to cover the global-offline case.

The comment at lines 438–443 accurately describes the case where online resolution fails (resolve_channel_version returns Ok(None)), but it doesn't mention that we also reach this fall-through when settings.offline() is true and opts.offline is false (global MISE_OFFLINE without prune-style offline). In that case the code skips the resolve_channel_version call (line 430) and the opts.offline early return (line 435), falling through to normal resolution.

Consider updating the comment to clarify both scenarios, for example:

-            // Online but the channel did not resolve to a concrete version --
-            // either the index lacked the channel key, or the fetch failed
-            // transiently (resolve_channel_version maps both to Ok(None)). Fall
-            // through to normal resolution, which still matches the literal
-            // channel name in the backend's version list as before.
+            // Fall through to normal resolution when the channel cannot be
+            // concretized: either we're offline (global MISE_OFFLINE without
+            // opts.offline), or online resolution failed (the index lacked the
+            // channel key / fetch error; resolve_channel_version maps both to
+            // Ok(None)). Normal resolution can still match the literal channel
+            // name in the backend's version list as before. (`#10251`)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/toolset/tool_version.rs` around lines 414 - 443, The comment at lines
438–443 in the rolling release channel handling block needs clarification.
Currently it only describes the case where online resolution fails
(resolve_channel_version returns Ok(None)), but it doesn't account for the case
where global offline mode is enabled (settings.offline() is true) while
opts.offline is false, which also causes the code to skip the
resolve_channel_version call and fall through to normal resolution. Update the
comment to cover both scenarios: the online resolution failure case and the
global-offline-without-prune-style-offline case, so it clearly explains all
paths that lead to the fall-through behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/toolset/tool_version.rs`:
- Around line 414-443: The comment at lines 438–443 in the rolling release
channel handling block needs clarification. Currently it only describes the case
where online resolution fails (resolve_channel_version returns Ok(None)), but it
doesn't account for the case where global offline mode is enabled
(settings.offline() is true) while opts.offline is false, which also causes the
code to skip the resolve_channel_version call and fall through to normal
resolution. Update the comment to cover both scenarios: the online resolution
failure case and the global-offline-without-prune-style-offline case, so it
clearly explains all paths that lead to the fall-through behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a949887b-abc6-4997-89db-151d3c2c4c6d

📥 Commits

Reviewing files that changed from the base of the PR and between aa7d475 and 875cff8.

📒 Files selected for processing (5)
  • docs/lang/zig.md
  • e2e/core/test_zig_slow
  • src/backend/mod.rs
  • src/plugins/core/zig.rs
  • src/toolset/tool_version.rs
🚧 Files skipped from review as they are similar to previous changes (4)
  • e2e/core/test_zig_slow
  • docs/lang/zig.md
  • src/plugins/core/zig.rs
  • src/backend/mod.rs

@risu729

risu729 commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

I think we should share the logic with existing rolling release support in the http backend, maybe other backends support it but I don't remember.

`zig@master` was pinned to the literal "master": mise installed it under
installs/zig/master and never re-resolved it, so `mise upgrade`/`mise outdated`
compared "master" == "master" and never picked up new nightlies (a master install
could sit weeks out of date). Zig publishes "master" as a rolling channel in its
download index (ziglang.org/download/index.json) whose `version` field points at
the current nightly (e.g. 0.17.0-dev.836+...), with the build hosted under
ziglang.org/builds/.

Resolve such rolling channels to their concrete version at resolution time, like
"latest", so installs land in versioned dirs and upgrade/outdated track new builds:

- Add Backend::is_rolling_channel, Backend::latest_installed_channel_version and
  Backend::resolve_channel_version hooks (default no-op).
- In ToolVersion::resolve_version, re-resolve a channel like "latest": reuse an
  installed build of THAT channel (never an unrelated installed release, so
  zig@master is not short-circuited to a stable that happens to be installed),
  which keeps hook-env/exec network-free; otherwise resolve via the backend;
  offline falls back to the literal channel.
- Implement for zig "master": read /master/version from the index, reuse the latest
  installed -dev nightly, and build the /builds/ tarball URL for the resolved dev
  version (not a top-level index key) in get_tarball_url / resolve_lock_info.
  minisign verification is unchanged.

mach-latest is left as a follow-up (machengine index format unverified).

Addresses discussion jdx#10251.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@JamBalaya56562 JamBalaya56562 force-pushed the fix-zig-master-channel branch from 875cff8 to a64ff0d Compare June 14, 2026 07:45
@jdx jdx merged commit da66374 into jdx:main Jun 14, 2026
34 checks passed
@JamBalaya56562 JamBalaya56562 deleted the fix-zig-master-channel branch June 14, 2026 09:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants