Fedora OCaml rebuild for OCaml 4.02.0 beta in Rawhide.
[goaljobs-goals.git] / fedora_ocaml_rebuild.ml
index b4445dd..c2e1558 100644 (file)
@@ -1,9 +1,11 @@
 (* Perform a complete Fedora OCaml rebuild, in build order. *)
 
+open Unix
 open Printf
 
 open Goaljobs
 open Config
+open Git
 open Fedora
 
 let branch = "master"
@@ -12,11 +14,10 @@ let koji_target = "rawhide"
 (* The name of the rebuild, and also the magic substring that must
  * appear in the %changelog when the package has been rebuilt.
  *)
-let rebuild_name = "OCaml 4.01.0"
+let rebuild_name = "OCaml 4.02.0 beta"
 
 (* Packages that have problems or we just don't want to build. *)
 let blocked = [
-  "ocaml-libvirt"; (* RHBZ#1009701 *)
   "ocaml-lwt"; "ocaml-react"; (* loganjerry is handling *)
 ]
 
@@ -35,10 +36,52 @@ let pkg_deps = dependencies branch source_packages
 
 (* Goal: rebuild all packages. *)
 let rec goal all () =
-  List.iter (fun pkg -> require (rebuilt pkg)) source_packages
+  List.iter (fun pkg -> require (rebuild_started pkg)) source_packages
 
 (* Goal: That 'package' has been rebuilt and exists in Koji. *)
 and rebuilt pkg =
+  let specfile = fedora_specfile pkg branch in
+
+  (* Note: verrel may change as we go along, so don't assign it to
+   * variable.
+   *)
+
+  (* Note the target must be both of these because the old verrel
+   * could exist as a koji build without it having been part of the
+   * rebuild.
+   *)
+  target (file_contains_string specfile rebuild_name &&
+          koji_build_state (fedora_verrel pkg branch) == `Complete);
+
+  (* Start the rebuild. *)
+  require (rebuild_started pkg);
+
+  (* Wait for the build state to reach a conclusion. *)
+  let rec loop () =
+    match koji_build_state (fedora_verrel pkg branch) with
+    | `No_such_build ->
+      failwith (sprintf "rebuild of package %s: no build found" pkg)
+    | `Building ->
+      sleep 60;
+      loop ()
+    | `Complete ->
+      ()
+    | `Deleted ->
+      failwith (sprintf "rebuild of package %s: deleted" pkg)
+    | `Failed ->
+      failwith (sprintf "rebuild of package %s: failed" pkg)
+    | `Canceled ->
+      failwith (sprintf "rebuild of package %s: canceled" pkg)
+  in
+  loop ();
+
+  (* Wait for the build to appear in Koji repo. *)
+  koji_wait_repo koji_target (fedora_verrel pkg branch)
+
+(* Goal: The rebuild of the package has started, but we haven't waited
+ * for it to finish.
+ *)
+and rebuild_started pkg =
   let deps = List.assoc pkg pkg_deps in
   let specfile = fedora_specfile pkg branch in
 
@@ -47,19 +90,40 @@ and rebuilt pkg =
    * rebuild.
    *)
   target (file_contains_string specfile rebuild_name &&
-            koji_build_exists (fedora_verrel pkg branch));
+            (match koji_build_state (fedora_verrel pkg branch) with
+            | `Building | `Complete -> true
+            | `Deleted | `Failed | `Canceled | `No_such_build -> false));
 
-  (* All dependent packages must have been done first. *)
+  (* All dependent packages must have been fully rebuilt and in the
+   * repo first.
+   *)
   List.iter (fun dep -> require (rebuilt dep)) deps;
 
   (* A local test build must succeed. *)
   require (local_build_succeeded pkg);
 
-  (* Rebuild the package in Koji. *)
-  koji_build pkg branch;
+  (* Rebuild the package in Koji.  Don't wait ... *)
+  koji_build ~wait:false pkg branch;
 
-  (* Wait for the build to appear in Koji repo.  Note verrel may change. *)
-  koji_wait_repo koji_target (fedora_verrel pkg branch)
+  (* ... but the build doesn't appear in Koji (eg. in 'koji
+   * buildinfo') until the SRPM has been built.  This can take quite
+   * some time.  Loop here until the build appears.
+   *)
+  let rec loop () =
+    match koji_build_state (fedora_verrel pkg branch) with
+    | `No_such_build ->
+      sleep 60;
+      loop ();
+    | `Building | `Complete ->
+      ()
+    | `Deleted ->
+      failwith (sprintf "rebuild of package %s: deleted" pkg)
+    | `Failed ->
+      failwith (sprintf "rebuild of package %s: failed" pkg)
+    | `Canceled ->
+      failwith (sprintf "rebuild of package %s: canceled" pkg)
+  in
+  loop ()
 
 and local_build_succeeded pkg =
   (* The specfile must have been updated. *)
@@ -73,7 +137,7 @@ and local_build_succeeded pkg =
   (* Do a local test build to ensure the Koji build will work. *)
   sh "
     cd %s
-    sudo yum-builddep %s
+    sudo yum-builddep -y %s
     fedpkg local
   " (fedora_repo pkg branch)
     (fedora_specfile pkg branch);
@@ -84,13 +148,34 @@ and specfile_updated pkg =
   let repodir = fedora_repo pkg branch in
   let specfile = fedora_specfile pkg branch in
 
-  (* XXX Automate common changes. *)
-  let title = rebuild_name ^ " rebuild." in
   sh "
     cd %s
-    git pull --rebase
-    rm -rf x86_64 noarch *.src.rpm
-    rpmdev-bumpspec -c %s %s
+    rm -rf x86_64 noarch *.src.rpm .build* clog
+    git fetch
+  " repodir;
+
+  if not (git_has_local_changes repodir) then
+    sh "
+      cd %s
+      git pull --rebase
+    " repodir;
+
+  sh "sudo yum-builddep -y %s" specfile;
+
+  (* For rationale behind always bumping the spec file, see comment
+   * in 'fedora.ml'.
+   *)
+  let title =
+    if not (file_contains_string specfile rebuild_name) then
+      rebuild_name ^ " rebuild."
+    else
+      "Bump release and rebuild." in
+  sh "rpmdev-bumpspec -c %s %s" (quote title) specfile;
+
+  (* XXX Automate common specfile fixes. *)
+
+  sh "
+    cd %s
     echo 'Please make further changes as required to the spec file %s.spec'
     echo '(Press return key)'
     read
@@ -102,6 +187,5 @@ and specfile_updated pkg =
     read
     fedpkg push
   " repodir
-    (quote title) specfile
     pkg
     specfile