diff --git a/gitlab/pipeline.ml b/gitlab/pipeline.ml index 1548f076..b25c58a5 100644 --- a/gitlab/pipeline.ml +++ b/gitlab/pipeline.ml @@ -192,7 +192,7 @@ let gitlab_status_of_state head result = let local_test ~query_uri ~solver repo () = let platforms = Conf.fetch_platforms ~query_uri ~include_macos:false ~include_freebsd:false - () + ~include_windows:false () in let src = Git.Local.head_commit repo in let src_content = Repo_content.extract src in @@ -207,7 +207,8 @@ let local_test ~query_uri ~solver repo () = let v ?ocluster ~app ~query_uri ~solver ~migrations () = let platforms = - Conf.fetch_platforms ~query_uri ~include_macos:true ~include_freebsd:true () + Conf.fetch_platforms ~query_uri ~include_macos:true ~include_freebsd:true + ~include_windows:true () in let ocluster = Option.map (Cluster_build.config ~timeout:(Duration.of_hour 1)) ocluster diff --git a/lib/build_info.ml b/lib/build_info.ml index a64f3b85..44973cc0 100644 --- a/lib/build_info.ml +++ b/lib/build_info.ml @@ -12,9 +12,15 @@ let of_label label = { label; variant = None } If it is experimental we allow those builds to fail without failing the overall build for a commit. *) let experimental_variant s = - Astring.String.( - is_prefix ~affix:Variant.lower_bound_label s.label - || is_prefix ~affix:Variant.opam_label s.label) + if + Astring.String.( + is_prefix ~affix:Variant.lower_bound_label s.label + || is_prefix ~affix:Variant.opam_label s.label) + then true + else + match s.variant with + | None -> false + | Some v -> Astring.String.equal "windows-server-2022" (Variant.distro v) (** Like [experimental_variant], but takes strings for when a [build_info] record is unavailable. @@ -24,4 +30,5 @@ let experimental_variant s = let experimental_variant_str s = Astring.String.( is_prefix ~affix:Variant.lower_bound_label s - || is_prefix ~affix:Variant.opam_label s) + || is_prefix ~affix:Variant.opam_label s + || is_prefix ~affix:"windows-server-2022" s) diff --git a/lib/opam_build.ml b/lib/opam_build.ml index 807c98b0..ad45b19a 100644 --- a/lib/opam_build.ml +++ b/lib/opam_build.ml @@ -86,12 +86,12 @@ let install_project_deps ~opam_version ~opam_files ~selection = let prefix = match Variant.os variant with | `macOS -> "~/local" - | `linux -> "/usr" + | `windows | `linux -> "/usr" | `freeBSD -> "/usr/local" in let ln = match Variant.os variant with - | `macOS -> "ln" + | `windows | `macOS -> "ln" | `linux | `freeBSD -> "sudo ln" in let groups = group_opam_files opam_files in @@ -115,6 +115,11 @@ let install_project_deps ~opam_version ~opam_files ~selection = Obuilder_spec.Cache.v download_cache ~target:"/home/opam/.opam/download-cache"; ] + | `windows -> + [ + Obuilder_spec.Cache.v download_cache + ~target:"c:\\Users\\opam\\AppData\\local\\opam\\download-cache"; + ] | `macOS -> [ Obuilder_spec.Cache.v download_cache @@ -133,12 +138,13 @@ let install_project_deps ~opam_version ~opam_files ~selection = let home_dir = match Variant.os selection.Selection.variant with - | `macOS -> None + | `windows | `macOS -> None | `linux -> Some "/src" | `freeBSD -> Some "/src" in let work_dir = match Variant.os selection.Selection.variant with + | `windows -> Some (Fpath.v "/Users/opam/Documents") | `macOS -> Some (Fpath.v "./src/") | `linux -> None | `freeBSD -> None @@ -202,6 +208,7 @@ let spec ~base ~opam_version ~opam_files ~selection = let to_name x = OpamPackage.of_string x |> OpamPackage.name_to_string in let home_dir = match Variant.os selection.Selection.variant with + | `windows -> "/Users/opam/Documents" | `macOS -> "./src" | `linux -> "/src" | `freeBSD -> "/src" @@ -213,6 +220,11 @@ let spec ~base ~opam_version ~opam_files ~selection = in let run_build = match Variant.os selection.Selection.variant with + | `windows -> + run + "cd /cygdrive/c/Users/opam/Documents && opam exec -- dune build%s \ + @install @check @runtest && rm -rf _build" + only_packages | `macOS -> run "cd ./src && opam exec -- dune build%s @install @check @runtest && \ diff --git a/lib/platform.ml b/lib/platform.ml index ea9ee227..211cb93f 100644 --- a/lib/platform.ml +++ b/lib/platform.ml @@ -12,6 +12,7 @@ module Pool_name = struct | `Linux_riscv64 | `Macos_x86_64 | `Macos_ARM64 + | `Windows_x86_64 | `FreeBSD_x86_64 ] let to_string = function @@ -22,6 +23,7 @@ module Pool_name = struct | `Linux_riscv64 -> "linux-riscv64" | `Macos_x86_64 -> "macos-x86_64" | `Macos_ARM64 -> "macos-arm64" + | `Windows_x86_64 -> "test" | `FreeBSD_x86_64 -> "freebsd-x86_64" let of_string = function @@ -32,6 +34,7 @@ module Pool_name = struct | "linux-riscv64" -> Ok `Linux_riscv64 | "macos-x86_64" -> Ok `Macos_x86_64 | "macos-arm64" -> Ok `Macos_ARM64 + | "test" -> Ok `Windows_x86_64 | "freebsd-x86_64 " -> Ok `FreeBSD_x86_64 | s -> Error (`Msg (s ^ ": invalid pool name")) end diff --git a/lib/platform.mli b/lib/platform.mli index 9cdf3e8d..f808c71f 100644 --- a/lib/platform.mli +++ b/lib/platform.mli @@ -9,6 +9,7 @@ module Pool_name : sig | `Linux_riscv64 | `Macos_x86_64 | `Macos_ARM64 + | `Windows_x86_64 | `FreeBSD_x86_64 ] val to_string : t -> string diff --git a/lib/query.ml b/lib/query.ml index 236cb5c7..2fa41429 100644 --- a/lib/query.ml +++ b/lib/query.ml @@ -36,12 +36,12 @@ let prepare_image ~variant = let prefix = match Variant.os variant with | `macOS -> "~/local" - | `linux -> "/usr" + | `windows | `linux -> "/usr" | `freeBSD -> "/usr/local" in let ln = match Variant.os variant with - | `macOS -> "ln" + | `windows | `macOS -> "ln" | `linux | `freeBSD -> "sudo ln" in (* XXX: don't overwrite default config? *) diff --git a/lib/query_local.ml b/lib/query_local.ml index 5baf3b86..b33577ba 100644 --- a/lib/query_local.ml +++ b/lib/query_local.ml @@ -41,12 +41,12 @@ let prepare_image ~job ~docker_context ~tag variant image = let prefix = match Variant.os variant with | `macOS -> "~/local" - | `linux -> "/usr" + | `windows | `linux -> "/usr" | `freeBSD -> "/usr/local" in let ln = match Variant.os variant with - | `macOS -> "ln" + | `windows | `macOS -> "ln" | `linux | `freeBSD -> "sudo ln" in (* XXX: don't overwrite default config? *) diff --git a/lib/variant.ml b/lib/variant.ml index b631a14d..a0ab6a71 100644 --- a/lib/variant.ml +++ b/lib/variant.ml @@ -40,10 +40,12 @@ type t = { [@@deriving yojson, ord, eq] let macos_distributions = [ "macos-homebrew" ] +let windows_distributions = [ "windows-server-2022" ] let freebsd_distributions = [ "freebsd" ] let os { distro; _ } = if List.exists (String.equal distro) macos_distributions then `macOS + else if List.exists (String.equal distro) windows_distributions then `windows else if List.exists (String.equal distro) freebsd_distributions then `freeBSD else `linux diff --git a/lib/variant.mli b/lib/variant.mli index 071f747e..aad9a98e 100644 --- a/lib/variant.mli +++ b/lib/variant.mli @@ -31,4 +31,4 @@ val docker_tag : t -> string val pp : t Fmt.t val to_string : t -> string val of_string : string -> t -val os : t -> [> `linux | `macOS | `freeBSD ] +val os : t -> [> `linux | `windows | `macOS | `freeBSD ] diff --git a/service/conf.ml b/service/conf.ml index 2ea1cce0..78d37f1d 100644 --- a/service/conf.ml +++ b/service/conf.ml @@ -89,6 +89,22 @@ type platform = { lower_bound : bool; } +(* Support OCaml 4.14 on Windows. *) +let windows_distros = + List.map + (fun ocaml_version -> + { + label = "windows-server-2022"; + builder = Builders.local; + pool = `Windows_x86_64; + distro = "windows-server-2022"; + ocaml_version; + arch = `X86_64; + opam_version = `V2_2; + lower_bound = false; + }) + default_compilers + (* Support OCaml default compilers on FreeBSD platform. *) let freebsd_distros = List.map @@ -141,7 +157,8 @@ let pool_of_arch = function | `Ppc64le -> `Linux_ppc64 | `Riscv64 -> `Linux_riscv64 -let platforms ~profile ~include_macos ~include_freebsd opam_version = +let platforms ~profile ~include_macos ~include_freebsd ~include_windows + opam_version = let v ?(arch = `X86_64) ?(lower_bound = false) label distro ocaml_version = { arch; @@ -188,6 +205,7 @@ let platforms ~profile ~include_macos ~include_freebsd opam_version = distros |> List.append (if include_macos then macos_distros else []) |> List.append (if include_freebsd then freebsd_distros else []) + |> List.append (if include_windows then windows_distros else []) in (* The first one in this list is used for lint actions *) let ovs = List.rev OV.Releases.recent @ OV.Releases.unreleased_betas in @@ -247,7 +265,8 @@ let merge_lower_bound_platforms platforms = in upper_bound @ lower_bound -let fetch_platforms ~query_uri ~include_macos ~include_freebsd () = +let fetch_platforms ~query_uri ~include_macos ~include_freebsd ~include_windows + () = let open Ocaml_ci in let conn = Option.map @@ -270,7 +289,9 @@ let fetch_platforms ~query_uri ~include_macos ~include_freebsd () = lower_bound; } = match (conn, distro) with - | Some conn, "macos-homebrew" | Some conn, "freebsd" -> + | Some conn, "windows-server-2022" + | Some conn, "macos-homebrew" + | Some conn, "freebsd" -> (* FreeBSD and MacOS uses ZFS snapshots rather than docker images. *) let docker_image_name = Fmt.str "%s-ocaml-%d.%d" distro (OV.major ocaml_version) @@ -308,6 +329,7 @@ let fetch_platforms ~query_uri ~include_macos ~include_freebsd () = in let v2_2 = platforms ~profile:platforms_profile `V2_2 ~include_macos ~include_freebsd + ~include_windows |> merge_lower_bound_platforms in Current.list_seq (List.map v v2_2) |> Current.map List.flatten diff --git a/service/pipeline.ml b/service/pipeline.ml index bd657aa8..c04bbc0b 100644 --- a/service/pipeline.ml +++ b/service/pipeline.ml @@ -112,7 +112,7 @@ let set_active_refs ~repo refs default_ref = let local_test ~query_uri ~solver repo () = let platforms = Conf.fetch_platforms ~query_uri ~include_macos:false ~include_freebsd:false - () + ~include_windows:false () in let src = Git.Local.head_commit repo in let src_content = Repo_content.extract src in @@ -130,7 +130,8 @@ let v ?ocluster ~app ~solver ~query_uri ~migrations () = Option.map (Cluster_build.config ~timeout:(Duration.of_hour 1)) ocluster in let platforms = - Conf.fetch_platforms ~query_uri ~include_macos:true ~include_freebsd:true () + Conf.fetch_platforms ~query_uri ~include_macos:true ~include_freebsd:true + ~include_windows:true () in let migrations = match migrations with diff --git a/test/service/test_conf.ml b/test/service/test_conf.ml index 758186ce..0f1f1aed 100644 --- a/test/service/test_conf.ml +++ b/test/service/test_conf.ml @@ -22,7 +22,7 @@ let to_tag d = DD.((resolve_alias d :> t) |> tag_of_distro) let test_platforms () = let platforms = Service.Conf.platforms ~profile:`All ~include_macos:true - ~include_freebsd:true `V2_1 + ~include_freebsd:true ~include_windows:true `V2_1 |> List.map extract in let exists = @@ -59,7 +59,7 @@ let test_platforms () = let test_macos_platforms () = let platforms = Service.Conf.platforms ~profile:`All ~include_macos:true - ~include_freebsd:true `V2_1 + ~include_freebsd:true ~include_windows:true `V2_1 |> List.map extract in let exists = @@ -96,7 +96,7 @@ let test_macos_platforms () = let test_distro_arches () = let platforms = Service.Conf.platforms ~profile:`All ~include_macos:true - ~include_freebsd:true `V2_1 + ~include_freebsd:true ~include_windows:true `V2_1 |> List.map extract in (* Test that these distros don't occur with these arches under any OCaml version *) diff --git a/web-ui/view/step.ml b/web-ui/view/step.ml index 2f82f213..4bad2613 100644 --- a/web-ui/view/step.ml +++ b/web-ui/view/step.ml @@ -706,20 +706,10 @@ module Make (M : Git_forge_intf.Forge) = struct in List.filter_map aux data |> String.concat "\n" in - let collapse_carriage_returns log_line = - let rec last = function - | [] -> raise (Failure "Trying to take log_line from empty list (BUG)") - | [ s ] -> s - | _ :: l -> last l - in - match log_line with - | "" -> "" - | log_line -> Astring.String.cuts ~sep:"\r" log_line |> last - in let process_logs data = Astring.String.(with_range ~len:(length data - 1)) data |> Astring.String.cuts ~sep:"\n" - |> List.map (fun l -> collapse_carriage_returns l |> Ansi.process ansi) + |> List.map (fun l -> Astring.String.trim l |> Ansi.process ansi) |> tabulate in let open Lwt.Infix in