Further updates to OCaml rebuild.
authorRichard W.M. Jones <rjones@redhat.com>
Thu, 19 Sep 2013 16:28:11 +0000 (17:28 +0100)
committerRichard W.M. Jones <rjones@redhat.com>
Thu, 19 Sep 2013 16:28:11 +0000 (17:28 +0100)
Makefile
fedora.ml
fedora_ocaml_rebuild.ml
git.ml [new file with mode: 0644]

index 903d26b..a9b99eb 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -15,7 +15,7 @@ all: \
        fedora_ocaml_rebuild \
        libguestfs_upstream
 
-fedora_ocaml_rebuild: config.ml utils.ml fedora.ml fedora_ocaml_rebuild.ml
+fedora_ocaml_rebuild: config.ml utils.ml git.ml fedora.ml fedora_ocaml_rebuild.ml
        $(goaljobs) --package pcre,extlib $^ -o $@
 
 libguestfs_upstream: config.ml libguestfs_upstream.ml
index edc9cfd..7d1d70b 100644 (file)
--- a/fedora.ml
+++ b/fedora.ml
@@ -73,6 +73,14 @@ let contains_substring substr str =
  * resists automation: RHBZ#760924.
  *)
 
+(* XXX koji_build_state verrel: If you do a build and it fails, then
+ * do another build without bumping the release field, 'koji buildinfo'
+ * seems to always return the failed build, at least until the second
+ * build completes.  This means the code below fails.  Unclear how it
+ * can be fixed, but best to always bump the release to avoid the
+ * problem.
+ *)
+
 (* Get build state. *)
 let rec koji_build_state verrel =
   fst (koji_build_state_task verrel)
@@ -90,34 +98,36 @@ and koji_build_state_task =
     else (
       let out = shout "timeout 120 koji buildinfo %s 2>&1 ||:" verrel in
       if no_such_build out then
-        failwith (sprintf "koji_build_state_task: %s: no such build" verrel);
-      let state =
-        try
-          let subs = Pcre.exec ~rex:state out in
-          match Pcre.get_substring subs 1 with
-          | "BUILDING" -> `Building
-          | "COMPLETE" -> `Complete
-          | "DELETED" -> `Deleted
-          | "FAILED" -> `Failed
-          | "CANCELED" -> `Canceled
-          | sub ->
-            failwith (sprintf "koji_build_state_task: %s: unknown build state '%s'"
-                        verrel sub)
-        with
-          Not_found ->
-            failwith (sprintf "koji_build_state_task: %s: no build state found"
-                        verrel) in
-      let task =
-        try
-          let subs = Pcre.exec ~rex:task_id out in
-          Some (int_of_string (Pcre.get_substring subs 1))
-        with
-          Not_found -> None in
-
-      if state == `Complete then
-        memory_set key "1";
-
-      state, task
+        `No_such_build, None
+      else (
+        let state =
+          try
+            let subs = Pcre.exec ~rex:state out in
+            match Pcre.get_substring subs 1 with
+            | "BUILDING" -> `Building
+            | "COMPLETE" -> `Complete
+            | "DELETED" -> `Deleted
+            | "FAILED" -> `Failed
+            | "CANCELED" -> `Canceled
+            | sub ->
+              failwith (sprintf "koji_build_state_task: %s: unknown build state '%s'"
+                          verrel sub)
+          with
+            Not_found ->
+              failwith (sprintf "koji_build_state_task: %s: no build state found"
+                          verrel) in
+        let task =
+          try
+            let subs = Pcre.exec ~rex:task_id out in
+            Some (int_of_string (Pcre.get_substring subs 1))
+          with
+            Not_found -> None in
+
+        if state == `Complete then
+          memory_set key "1";
+
+        state, task
+      )
     )
 
 (* Perform a Koji build and wait until it finishes.  If it fails,
@@ -134,10 +144,16 @@ let koji_build =
     let out =
       shout "
         cd %s
-        fedpkg build%s 2>&1 ||:
+        fedpkg build%s 2>&1
     " repodir (if not wait then " --nowait" else "")
     in
-    if wait then (
+    if not wait then (
+      (* Just check the task was created. *)
+      if not (Pcre.pmatch ~rex:created_task out) then (
+        eprintf "%s\n%!" out;
+        failwith "fedpkg build: build failed to start"
+      )
+    ) else (
       let task_id =
         try
           let subs = Pcre.exec ~rex:created_task out in
index 2eccde1..2b270fd 100644 (file)
@@ -5,6 +5,7 @@ open Printf
 
 open Goaljobs
 open Config
+open Git
 open Fedora
 
 let branch = "master"
@@ -19,6 +20,7 @@ let rebuild_name = "OCaml 4.01.0"
 let blocked = [
   "ocaml-libvirt"; (* RHBZ#1009701 *)
   "ocaml-lwt"; "ocaml-react"; (* loganjerry is handling *)
+  "ocaml-xmlrpc-light"; (* temporary, can remove after 2013-09-19 *)
 ]
 
 (* List of OCaml-related source package names. *)
@@ -59,8 +61,10 @@ and rebuilt 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 30;
+      sleep 60;
       loop ()
     | `Complete ->
       ()
@@ -90,7 +94,7 @@ and rebuild_started pkg =
   target (file_contains_string specfile rebuild_name &&
             (match koji_build_state (fedora_verrel pkg branch) with
             | `Building | `Complete -> true
-            | `Deleted | `Failed | `Canceled -> false));
+            | `Deleted | `Failed | `Canceled | `No_such_build -> false));
 
   (* All dependent packages must have been fully rebuilt and in the
    * repo first.
@@ -100,8 +104,28 @@ and rebuild_started pkg =
   (* A local test build must succeed. *)
   require (local_build_succeeded pkg);
 
-  (* Rebuild the package in Koji, but don't wait. *)
-  koji_build ~wait:false pkg branch
+  (* Rebuild the package in Koji.  Don't wait ... *)
+  koji_build ~wait:false 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. *)
@@ -115,7 +139,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);
@@ -126,13 +150,29 @@ and specfile_updated pkg =
   let repodir = fedora_repo pkg branch in
   let specfile = fedora_specfile pkg branch in
 
-  (* XXX Automate common changes. *)
+  sh "
+    cd %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'.
+   *)
+  (* XXX Automate common specfile fixes. *)
   let title = rebuild_name ^ " rebuild." in
+  sh "rpmdev-bumpspec -c %s %s" (quote title) specfile;
+
   sh "
     cd %s
-    git pull --rebase
-    rm -rf x86_64 noarch *.src.rpm
-    rpmdev-bumpspec -c %s %s
     echo 'Please make further changes as required to the spec file %s.spec'
     echo '(Press return key)'
     read
@@ -144,6 +184,5 @@ and specfile_updated pkg =
     read
     fedpkg push
   " repodir
-    (quote title) specfile
     pkg
     specfile 
diff --git a/git.ml b/git.ml
new file mode 100644 (file)
index 0000000..ef95978
--- /dev/null
+++ b/git.ml
@@ -0,0 +1,12 @@
+(* Utilities for handling git repositories. *)
+
+open Goaljobs
+
+let git_has_local_changes dir =
+  let lines = shlines "cd %s && git status --porcelain" (quote dir) in
+  let lines = List.filter (
+    fun line ->
+      let code = String.sub line 0 2 in
+      code <> "??"
+  ) lines in
+  List.length lines > 0