From f7eb055e8ad64c186696033a83ad79bb249483c1 Mon Sep 17 00:00:00 2001 From: Marek Kubica Date: Thu, 19 Feb 2026 14:58:39 +0100 Subject: [PATCH 1/6] Add an option to the installer to support passing the release Signed-off-by: Marek Kubica --- static/install | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/static/install b/static/install index 6a11ef9..e34e23a 100755 --- a/static/install +++ b/static/install @@ -41,6 +41,20 @@ success_bold() { printf "%b%s %b" "${Bold_Green}" "$*" "${Color_Off}" } +while [ "$#" -gt "0" ]; do + arg="$1" + shift + case "$arg" in + -r|--release) + if [ "$#" -eq "0" ]; then + error "--release must be passed an argument" + fi + release="$1" + shift + ;; + esac +done + tildify() { case "$1" in "$HOME"/*) @@ -78,7 +92,13 @@ esac tar_target_name="dune-$target" tar_target="$tar_target_name.tar.gz" -dune_tar_uri="https://nightly.dune.build/latest/$target" + +release=${release:-nightly} +if [ "$release" = "nightly" ]; then + dune_tar_uri="https://nightly.dune.build/latest/${target}" +else + dune_tar_uri="https://nightly.dune.build/stable/${release}/${target}" +fi install_dir="$HOME/.local" bin_dir="${install_dir}/bin" @@ -345,4 +365,4 @@ fi # end of main } -main +main "$@" From c8f4d5cdca1f92b885742d541028a318631c36af Mon Sep 17 00:00:00 2001 From: Marek Kubica Date: Thu, 19 Feb 2026 15:09:05 +0100 Subject: [PATCH 2/6] Add instructions on how to download a stable release Signed-off-by: Marek Kubica --- lib/component.mlx | 14 ++++++++++++-- lib/main.mlx | 12 ++++++++++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/lib/component.mlx b/lib/component.mlx index 4eaf47f..6a92d89 100644 --- a/lib/component.mlx +++ b/lib/component.mlx @@ -1,6 +1,16 @@ module Info = struct - let curl_with_sh url = - Format.sprintf "curl -fsSL %s | sh" url |> JSX.string + let curl_with_sh ~url ~sh_args = + let sh_args = match sh_args with + | None -> "" + | Some x -> " " ^ x + in + Printf.sprintf "curl -fsSL %s | sh%s" url sh_args |> JSX.string + + let curl_with_sh_nightly ~url = curl_with_sh ~url ~sh_args:None + + let curl_with_sh_stable ~url ~version = + let sh_args = Some (Printf.sprintf "-s - --release %s" version) in + curl_with_sh ~url ~sh_args end module Link = struct diff --git a/lib/main.mlx b/lib/main.mlx index 6209cc4..0ce5b51 100644 --- a/lib/main.mlx +++ b/lib/main.mlx @@ -41,12 +41,20 @@ let warning () = let getting_started ~install_url () =
+

"Install Dune"

- "Copy & Install" + "Copy & Install (nightly)" +

+ + +

+ + "Copy & Install (stable)"

- + ") /> +

"Getting Started"

"You can create and run your first hello-world program using Dune like this"

From a7f223f6d5b633a2ed5b9a427dc61f5c36fa9990 Mon Sep 17 00:00:00 2001 From: Marek Kubica Date: Fri, 20 Feb 2026 11:41:45 +0100 Subject: [PATCH 3/6] Display latest stable release version taken from the bundle Signed-off-by: Marek Kubica --- bin/main.ml | 31 ++++++++++++++++++++++++++++++- lib/main.mlx | 36 ++++++++++++++++++------------------ lib/web.ml | 4 ++-- 3 files changed, 50 insertions(+), 21 deletions(-) diff --git a/bin/main.ml b/bin/main.ml index b1ca2a0..82275b9 100644 --- a/bin/main.ml +++ b/bin/main.ml @@ -103,13 +103,42 @@ module Sync = struct let cmd = Cmd.v info term end +let find_latest_stable bundles = + bundles + |> List.filter_map (fun (b : Metadata.Bundle.t) -> + match b.tag with + | None -> None + | Some tag -> + (match Scanf.sscanf_opt tag "%d.%d.%d" (fun x y z -> x, y, z) with + | None -> None + | Some tup -> Some (tup, b))) + |> List.sort (fun ((maj, min, patch), _) ((maj', min', patch'), _) -> + (* reverse sort, biggest first *) + match Int.compare maj' maj with + | 0 -> + (match Int.compare min' min with + | 0 -> Int.compare patch' patch + | otherwise -> otherwise) + | otherwise -> otherwise) + |> function + | [] -> None + | (_, bundle) :: _ -> Some bundle +;; + module Http = struct let serve dev metadata_file port = let title = "Dune Nightly" in let base_url = Config.Server.url in let bundles = Metadata.import_from_json metadata_file in + let latest_release = + match find_latest_stable bundles with + | None -> "" + | Some bundle -> + (* guaranteed to exist at this point *) + Option.get bundle.tag + in let routes = - let main_page = Web.generate_main_page ~title ~base_url bundles in + let main_page = Web.generate_main_page ~title ~base_url ~latest_release bundles in Web.Route.empty |> Web.Route.add ~path:"/" main_page |> Web.Route.add ~path:"/index.html" main_page diff --git a/lib/main.mlx b/lib/main.mlx index 0ce5b51..fab14ea 100644 --- a/lib/main.mlx +++ b/lib/main.mlx @@ -38,7 +38,7 @@ let warning () =

-let getting_started ~install_url () = +let getting_started ~install_url ~latest_release:version () =
@@ -53,7 +53,7 @@ let getting_started ~install_url () = "Copy & Install (stable)" - ") /> +

"Getting Started"

"You can create and run your first hello-world program using Dune like this"

@@ -245,7 +245,7 @@ let installation_target ~base_url ~bundle target = "Certificate" -let manual_installation ~base_url ~releases () = +let manual_installation ~base_url ~builds () =

"Manual Installation"

@@ -254,12 +254,12 @@ let manual_installation ~base_url ~releases () =

"Featured Downloads"

- "This is the latest release of the Dune nightly. See the " - "release history" - " section for all past releases." + "This is the latest build of the Dune nightly. See the " + "build history" + " section for all past builds."

    - (let bundle: Metadata.Bundle.t = releases |> List.hd in + (let bundle: Metadata.Bundle.t = builds |> List.hd in bundle.targets |> List.map (installation_target ~base_url ~bundle) |> JSX.list) @@ -267,7 +267,7 @@ let manual_installation ~base_url ~releases () =

    "Installing the binary"

    - "After downloading a binary release of Dune, make it executable and place it somewhere reachable by your PATH:" + "After downloading a binary build of Dune, make it executable and place it somewhere reachable by your PATH:"

    @@ -315,19 +315,19 @@ let release_information ~base_url ~bundle ~target () = -let release_history ~base_url ~releases () = +let build_history ~base_url ~builds () = let open Metadata in -
    +
    -

    "Last Month Release History"

    +

    "Last Month Build History"

    "Here is a list of the " - (JSX.int (List.length releases)) + (JSX.int (List.length builds)) " latest builds of the Dune nightly."

    ( - releases + builds |> List.map (fun (bundle: Bundle.t) -> let date = Bundle.get_date_string_from ~prefix:"nightly-" bundle in let summary = Format.sprintf "dune %s" date in @@ -355,15 +355,15 @@ let release_history ~base_url ~releases () =
    -let page ~base_url ~releases () = - let releases = Core.List.take 30 releases in +let page ~base_url ~latest_release ~builds () = + let builds = Core.List.take 30 builds in let install_url = Filename.concat base_url "install" in
    - + - - + +
    diff --git a/lib/web.ml b/lib/web.ml index add3e01..23f0015 100644 --- a/lib/web.ml +++ b/lib/web.ml @@ -1,7 +1,7 @@ let export_website_to_string ~title content = Container.page ~title content |> JSX.render -let generate_main_page ~title ~base_url releases = - Main.page ~base_url ~releases () |> export_website_to_string ~title +let generate_main_page ~title ~base_url ~latest_release builds = + Main.page ~base_url ~latest_release ~builds () |> export_website_to_string ~title ;; let generate_error_page ~title reason = From 0970f3aa0558d9f7301e24e374b877b0eec01c50 Mon Sep 17 00:00:00 2001 From: Marek Kubica Date: Fri, 20 Feb 2026 14:06:38 +0100 Subject: [PATCH 4/6] Reindent and fail on unknown arguments Signed-off-by: Marek Kubica --- static/install | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/static/install b/static/install index e34e23a..e50b832 100755 --- a/static/install +++ b/static/install @@ -46,12 +46,15 @@ while [ "$#" -gt "0" ]; do shift case "$arg" in -r|--release) - if [ "$#" -eq "0" ]; then + if [ "$#" -eq "0" ]; then error "--release must be passed an argument" fi - release="$1" - shift - ;; + release="$1" + shift + ;; + *) + error "Unknown argument: ${arg}" + ;; esac done From c7a848436e5a6b98bb3632764318309c6b8306e5 Mon Sep 17 00:00:00 2001 From: Ali Caglayan Date: Mon, 23 Feb 2026 09:34:45 +0100 Subject: [PATCH 5/6] fix: copy buttons now copy correct text Before the copy buttons shared the same id, so would always fetch the same content. Furthermore, there was no visual feedback. I've instead replaced the copy functionality with a local variant which should allow us to avoid combing through elements. Signed-off-by: Ali Caglayan Signed-off-by: Marek Kubica --- lib/component.mlx | 42 +++++++----------------------------------- static/main.css | 16 ++++++++++++++++ 2 files changed, 23 insertions(+), 35 deletions(-) diff --git a/lib/component.mlx b/lib/component.mlx index 6a92d89..2dc14be 100644 --- a/lib/component.mlx +++ b/lib/component.mlx @@ -35,43 +35,15 @@ end module Curl = struct let make ~script () =
    - + script - - - +
    + +
    +
    + +
    end diff --git a/static/main.css b/static/main.css index ea95f89..5659e3b 100644 --- a/static/main.css +++ b/static/main.css @@ -554,6 +554,22 @@ video { --tw-contain-style: ; } +.container { + width: 100%; +} + +@media (min-width: 60em) { + .container { + max-width: 60em; + } +} + +@media (min-width: 80em) { + .container { + max-width: 80em; + } +} + .absolute { position: absolute; } From 2d3b3b3f2e762bda9defbd086e4bf8677e64029f Mon Sep 17 00:00:00 2001 From: Marek Kubica Date: Wed, 25 Feb 2026 14:57:06 +0100 Subject: [PATCH 6/6] Rename release history into build history It is confusing to call nightly builds releases in the presence of actual stable releases. Signed-off-by: Marek Kubica --- lib/container.mlx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/container.mlx b/lib/container.mlx index ee5315f..736d4ab 100644 --- a/lib/container.mlx +++ b/lib/container.mlx @@ -33,7 +33,7 @@ let navbar () = "Share Feedback" "FAQs" "Manual Installation" - "Last Month Release History" + "Last Month Build History"

@@ -58,7 +58,7 @@ let footer_info () = "Share Feedback" "FAQs" "Manual Installation" - "Last Month Release History" + "Last Month Build History"