1 (* This goal script is responsible for:
2 * - testing each new commit to the libguestfs source repo
3 * - checking for new upstream releases of libguestfs
4 * - testing new upstream releases
5 * - packaging them as a source tarball
6 * - testing the source tarball on a variety of systems
7 * - if all the above works, uploading the external website
8 * Note this doesn't build the Fedora releases. See 'libguestfs_fedora.ml'.
15 (* Enable debugging. *)
17 Unix.putenv "LIBGUESTFS_DEBUG" "1";
18 Unix.putenv "LIBGUESTFS_TRACE" "1"
20 (* Log program output. *)
21 let from = "rjones@redhat.com"
22 let to_ = "rjones@redhat.com"
23 let logfile = log_program_output ()
24 let () = eprintf "logging to %s\n%!" logfile
26 let package = "libguestfs"
28 (* Helper object which stores everything about a version. *)
30 version : string; (* The version as a normal string. *)
31 major : int; (* Broken-out version fields. *)
34 is_stable : bool; (* is a stable version of libguestfs? *)
35 branch : string; (* 'master' or 'stable-1.xx' *)
36 package_version : string; (* package-version *)
37 tarball : string; (* package-version.tar.gz *)
38 urlpath : string; (* download/1.X-(stable|development)/tarball *)
39 url : string; (* full download URL of tarball *)
42 (* Helper: Fetch latest gnulib into $buildtmp/repos/gnulib
43 * XXX Move to Gnulib module.
48 if [ ! -d gnulib ]; then git clone git://git.sv.gnu.org/gnulib.git; fi
50 git checkout --force master
54 (* Goal: the website has been updated to 'version'. *)
55 let rec goal website_updated version =
56 target (url_exists version.url);
58 require (tarball_created version);
59 require (tarball_tested version);
61 (* We only update the website for the development releases. *)
62 if not version.is_stable then
63 require (website_built version);
65 require (website_cvs_checked_in version);
66 require (website_rsync_done version)
68 (* Goal: website has been rsync'd. *)
69 and website_rsync_done version =
70 let key = sprintf "libguestfs_website_rsync_done_%s" version.version in
71 target (memory_exists key);
72 onrun (fun () -> memory_set key "1");
76 echo NOT RUNNING: . .rsync
77 " libguestfs_website_cvs
79 (* Goal: Tarball added to CVS and CVS checked in. *)
80 and website_cvs_checked_in version =
81 let key = sprintf "libguestfs_website_cvs_checked_in_%s" version.version in
82 target (memory_exists key);
83 onrun (fun () -> memory_set key "1");
85 require (tarball_created version);
86 require (tarball_tested version);
91 echo NOT RUNNING: cvs add -kb %s
92 echo NOT RUNNING: cvs ci -m \"Version %s\"
93 " libguestfs_website_cvs
94 buildtmp version.tarball version.urlpath
98 (* Goal: website (local copy) has been built. *)
99 and website_built version =
100 let index_file = sprintf "%s/index.html" libguestfs_website_cvs in
101 target (file_contains_string index_file version.version);
103 require (tarball_created version);
104 require (tarball_tested version);
106 (* We should only update the website on development releases. *)
107 assert (not version.is_stable);
110 tar zxf %s/tarballs/%s
113 echo %s > localconfigure
114 chmod +x localconfigure
120 " buildtmp version.tarball
121 version.package_version
122 (quote (libguestfs_localconfigure `Tarball))
123 (quote libguestfs_localenv)
125 (* Goal: the tarball has passed the required set of tests before
126 * a release is allowed.
128 and tarball_tested version =
129 let key = sprintf "libguestfs_tarball_tested_%s" version.version in
130 target (memory_exists key);
131 onrun (fun () -> memory_set key "1");
133 require (tarball_created version);
136 tar zxf %s/tarballs/%s
139 echo %s > localconfigure
140 chmod +x localconfigure
146 " buildtmp version.tarball
147 version.package_version
148 (quote (libguestfs_localconfigure `Tarball))
149 (quote libguestfs_localenv)
151 (* Goal: the tarball has been created from git. *)
152 and tarball_created version =
153 let filename = sprintf "%s/tarballs/%s" buildtmp version.tarball in
154 target (file_exists filename);
156 let repodir = sprintf "%s/repos/%s-%s" buildtmp package version.branch in
157 require (directory_exists repodir);
164 echo %s > localconfigure
165 chmod +x localconfigure
174 (quote (libguestfs_localconfigure `Git))
175 (quote libguestfs_localenv)
176 version.tarball buildtmp version.tarball
178 (* Goal: test a commit. *)
179 and commit_tested branch commit =
182 let subject = sprintf "goal: %s: FAILED" goalname in
183 mailto ~from ~subject ~attach:[logfile] to_
186 let key = sprintf "libguestfs_commit_tested_%s" commit in
187 target (memory_exists key);
188 onrun (fun () -> memory_set key "1");
190 let repodir = sprintf "%s/repos/%s-%s" buildtmp package branch in
191 require (directory_exists repodir);
198 echo %s > localconfigure
199 chmod +x localconfigure
207 (quote (libguestfs_localconfigure `Git))
208 (quote libguestfs_localenv)
210 (* Helper function to make a full 'info' object from a version
213 let vernames version =
214 Scanf.sscanf version "%d.%d.%d" (
215 fun major minor release ->
216 let is_stable = minor mod 2 = 0 in
219 sprintf "stable-%d.%d" major minor
222 let package_version = sprintf "%s-%d.%d.%d" package major minor release in
223 let tarball = sprintf "%s.tar.gz" package_version in
226 sprintf "download/%d.%d-stable/%s" major minor tarball
228 sprintf "download/%d.%d-development/%s" major minor tarball in
229 let url = "http://libguestfs.org/" ^ urlpath in
231 major = major; minor = minor; release = release;
232 is_stable = is_stable;
234 package_version = package_version;
240 (* Helper function to read the latest version in a repo and return
243 let git_latest_version branch =
246 git describe --tags --abbrev=0
247 " buildtmp package (quote branch) in
250 (* Get the latest commit. *)
251 let git_latest_commit branch =
255 " buildtmp package (quote branch)
257 (* Clone or update a repo to the latest version on a branch, by force.
258 * It is cached in name = $buildtmp/repos/<package>-<branch>
260 let git_force url branch =
263 if [ ! -d %s-%s ]; then git clone %s %s-%s; fi
265 git checkout --force %s
267 # Copy or update gnulib
271 package (quote branch) (quote url) package (quote branch)
272 package (quote branch)
276 (* Add a periodic job to check for new git commits and test them. *)
277 every libguestfs_query_mins minutes ~name:"new libguestfs commit" (
279 git_force "https://github.com/libguestfs/libguestfs.git" "master";
281 let commit = git_latest_commit "master" in
282 require (commit_tested "master" commit);
285 (* Periodic job to build new tarballs. *)
286 every libguestfs_query_mins minutes ~name:"new libguestfs version" (
288 git_force "https://github.com/libguestfs/libguestfs.git" "master";
290 let version = git_latest_version "master" in
291 require (website_updated version)
294 (* Allow these jobs to run from the command line. *)
298 | [commit] -> require (commit_tested "master" commit)
299 | [branch; commit] -> require (commit_tested branch commit)
301 failwith "use './libguestfs_upstream commit [<branch>] <commit>'"
305 | [version] -> require (website_updated (vernames version))
307 failwith "use './libguestfs_upstream release <version>'"