(* This goal script is responsible for: * - testing each new commit to the libguestfs source repo * - checking for new upstream releases of libguestfs * - testing new upstream releases * - packaging them as a source tarball * - testing the source tarball on a variety of systems * - if all the above works, uploading the external website * Note this doesn't build the Fedora releases. See 'libguestfs_fedora.ml'. *) open Goaljobs open Printf open Config open Libguestfs (* Enable debugging. *) let () = Unix.putenv "LIBGUESTFS_DEBUG" "1"; Unix.putenv "LIBGUESTFS_TRACE" "1" (* Log program output. *) let from = "rjones@redhat.com" let to_ = "rjones@redhat.com" (* let logfile = log_program_output () let () = eprintf "logging to %s\n%!" logfile *) let package = "libguestfs" (* Goal: the website has been updated to 'version'. *) let rec goal website_updated version = target (url_exists version.url && (if version.is_stable then url_exists version.python_url else true) ); require (tarball_created version); require (tarball_tested version); if version.is_stable then require (tarball_signed version); (* Python sdists only generated for stable releases. *) if version.is_stable then ( require (python_tarball_created version); require (python_tarball_tested version) ); (* We only update the website for the development releases. *) if not version.is_stable then require (website_built version); require (website_checked_in version); if version.is_stable then require (python_website_checked_in version); require (website_rsync_done version) (* Goal: website has been rsync'd. *) and website_rsync_done version = target (url_contains_string "http://libguestfs.org" version.version && url_exists version.url); sh " cd %s ./.rsync " websites_repo (* Goal: Tarball added to repository and checked in. *) and website_checked_in version = let key = sprintf "libguestfs_website_checked_in_%s" version.version in target (memory_exists key); onrun (fun () -> memory_set key "1"); require (tarball_created version); require (tarball_tested version); if version.is_stable then require (tarball_signed version); sh " cd %s cp %s/tarballs/%s %s if %b; then cp %s/tarballs/%s.sig %s.sig; fi git add %s cd %s git add *.txt *.html cd %s git commit -m \"Version %s\" " libguestfs_download_repo buildtmp version.tarball version.urlpath version.is_stable buildtmp version.tarball version.urlpath version.urlpath libguestfs_website_repo websites_repo version.version (* Goal: website (local copy) has been built. *) and website_built version = let index_file = sprintf "%s/index.html" libguestfs_website_repo in target (file_contains_string index_file version.version); require (tarball_created version); require (tarball_tested version); (* We should only update the website on development releases. *) assert (not version.is_stable); sh " tar zxf %s/tarballs/%s cd %s echo %s > localconfigure chmod +x localconfigure echo %s > localenv ./localconfigure make V=1 make maintainer-upload-website WEBSITESDIR=%s " buildtmp version.tarball version.package_version (quote (libguestfs_localconfigure `Tarball)) (quote (libguestfs_localenv (supermin version))) (quote websites_repo) (* Goal: for stable versions, the tarball must be signed. *) and tarball_signed version = let tar_file = sprintf "%s/tarballs/%s" buildtmp version.tarball in let sig_file = tar_file ^ ".sig" in target (file_exists sig_file); require (tarball_created version); sh "sign-tarball %s" tar_file (* Goal: the tarball has passed the required set of tests before * a release is allowed. *) and tarball_tested version = let key = sprintf "libguestfs_tarball_tested_%s" version.version in target (memory_exists key); onrun (fun () -> memory_set key "1"); require (tarball_created version); sh " tar zxf %s/tarballs/%s cd %s echo %s > localconfigure chmod +x localconfigure echo %s > localenv ./localconfigure make V=1 if ! make check-release; then for f in `find -name test-suite.log | xargs grep -l ^FAIL:`; do echo \"*** $f ***\" cat $f done exit 1 fi " buildtmp version.tarball version.package_version (quote (libguestfs_localconfigure `Tarball)) (quote (libguestfs_localenv (supermin version))) (* Goal: the tarball has been created from git. *) and tarball_created version = let filename = sprintf "%s/tarballs/%s" buildtmp version.tarball in target (file_exists filename); require (repo_up_to_date version.branch); let repodir = sprintf "%s/repos/%s-%s" buildtmp package version.branch in (* Branches <= 1.32 are tagged with "1.32.11", * branches >= 1.33 are tagged with "v1.33.11". *) let version_tag = if version.minor >= 33 then "v" ^ version.version else version.version in sh " cp -a %s libguestfs cd libguestfs git reset --hard %s echo %s > localconfigure chmod +x localconfigure echo %s > localenv ./localconfigure # Ensure the po-docs are updated. Grrr this is ugly ... make ||: rm po-docs/podfiles make -C po-docs update-po make V=1 make dist # Ensure redhat hardening flags didn't leak into the tarball. # https://bugzilla.redhat.com/show_bug.cgi?id=1214506 if zcat %s | grep -q redhat-hardened; then exit 1; fi mv %s %s/tarballs/%s " repodir version_tag (quote (libguestfs_localconfigure `Git)) (quote (libguestfs_localenv (supermin version))) version.tarball version.tarball buildtmp version.tarball (* Goal: test a commit. *) and commit_tested branch commit = onfail ( fun _ -> let subject = sprintf "goal: %s: FAILED" goalname in mailto ~from ~subject (*~attach:[logfile]*) to_ ); let key = sprintf "libguestfs_commit_tested_%s" commit in target (memory_exists key); onrun (fun () -> memory_set key "1"); require (repo_up_to_date branch); let repodir = sprintf "%s/repos/%s-%s" buildtmp package branch in sh " cp -a %s libguestfs cd libguestfs git reset --hard %s echo %s > localconfigure chmod +x localconfigure echo %s > localenv ./localconfigure make V=1 if ! make check-release; then for f in `find -name test-suite.log | xargs grep -l ^FAIL:`; do echo \"*** $f ***\" cat $f done exit 1 fi " repodir commit (quote (libguestfs_localconfigure `Git)) (quote (libguestfs_localenv None)) and repo_up_to_date branch = git_force branch (* Goals for Python sdists. *) and python_website_checked_in version = let key = sprintf "libguestfs_python_website_checked_in_%s" version.version in target (memory_exists key); onrun (fun () -> memory_set key "1"); require (python_tarball_created version); require (python_tarball_tested version); sh " cd %s cp %s/tarballs/%s %s git add %s git commit -m \"Python sdist version %s\" " libguestfs_download_repo buildtmp version.python_tarball version.python_urlpath version.python_urlpath version.version and python_tarball_tested version = let key = sprintf "libguestfs_python_tarball_tested_%s" version.version in target (memory_exists key); onrun (fun () -> memory_set key "1"); require (python_tarball_created version); sh " virtualenv venv source ./venv/bin/activate pip install %s/tarballs/%s " buildtmp version.python_tarball and python_tarball_created version = let filename = sprintf "%s/tarballs/%s" buildtmp version.python_tarball in target (file_exists filename); require (tarball_created version); sh " tar zxf %s/tarballs/%s cd %s echo %s > localconfigure chmod +x localconfigure echo %s > localenv ./localconfigure make V=1 make -C python sdist cp python/dist/%s %s " buildtmp version.tarball version.package_version (quote (libguestfs_localconfigure `Tarball)) (quote (libguestfs_localenv (supermin version))) version.python_tarball filename let () = (* Add a periodic job to check for new git commits and test them. *) every libguestfs_query_mins minutes ~name:"new libguestfs commit" ( fun () -> require (repo_up_to_date "master"); let commit = git_latest_commit "master" in require (commit_tested "master" commit); ); (* Periodic job to build new tarballs. *) every libguestfs_query_mins minutes ~name:"new libguestfs version" ( fun () -> require (repo_up_to_date "master"); let version = git_latest_version "master" in require (website_updated version) ) (* Allow these jobs to run from the command line. *) let () = publish "commit" ( function | [commit] -> require (commit_tested "master" commit) | [branch; commit] -> require (commit_tested branch commit) | _ -> failwith "use './libguestfs_upstream commit [] '" ); publish "release" ( function | [version] -> require (website_updated (vernames version)) | _ -> failwith "use './libguestfs_upstream release '" )