libguestfs: Print failures.
[goaljobs-goals.git] / libguestfs_upstream.ml
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'.
9  *)
10
11 open Goaljobs
12 open Printf
13 open Config
14 open Libguestfs
15
16 (* Enable debugging. *)
17 let () =
18   Unix.putenv "LIBGUESTFS_DEBUG" "1";
19   Unix.putenv "LIBGUESTFS_TRACE" "1"
20
21 (* Log program output. *)
22 let from = "rjones@redhat.com"
23 let to_ = "rjones@redhat.com"
24 (*
25 let logfile = log_program_output ()
26 let () = eprintf "logging to %s\n%!" logfile
27 *)
28
29 let package = "libguestfs"
30
31 (* Goal: the website has been updated to 'version'. *)
32 let rec goal website_updated version =
33   target (url_exists version.url &&
34             (if version.is_stable then
35                url_exists version.python_url
36              else true)
37          );
38
39   require (tarball_created version);
40   require (tarball_tested version);
41
42   (* Python sdists only generated for stable releases. *)
43   if version.is_stable then (
44     require (python_tarball_created version);
45     require (python_tarball_tested version)
46   );
47
48   (* We only update the website for the development releases. *)
49   if not version.is_stable then
50     require (website_built version);
51
52   require (website_checked_in version);
53   if version.is_stable then
54     require (python_website_checked_in version);
55   require (website_rsync_done version)
56
57 (* Goal: website has been rsync'd. *)
58 and website_rsync_done version =
59   target (url_contains_string "http://libguestfs.org" version.version &&
60           url_exists version.url);
61
62   sh "
63     cd %s
64     ./.rsync
65   " websites_repo
66
67 (* Goal: Tarball added to repository and checked in. *)
68 and website_checked_in version =
69   let key = sprintf "libguestfs_website_checked_in_%s" version.version in
70   target (memory_exists key);
71   onrun (fun () -> memory_set key "1");
72
73   require (tarball_created version);
74   require (tarball_tested version);
75
76   sh "
77     cd %s
78     cp %s/tarballs/%s %s
79     git add %s
80     cd %s
81     git add *.txt *.html
82     cd %s
83     git commit -m \"Version %s\"
84   " libguestfs_download_repo
85     buildtmp version.tarball version.urlpath
86     version.urlpath
87     libguestfs_website_repo
88     websites_repo
89     version.version
90
91 (* Goal: website (local copy) has been built. *)
92 and website_built version =
93   let index_file = sprintf "%s/index.html" libguestfs_website_repo in
94   target (file_contains_string index_file version.version);
95
96   require (tarball_created version);
97   require (tarball_tested version);
98
99   (* We should only update the website on development releases. *)
100   assert (not version.is_stable);
101
102   sh "
103     tar zxf %s/tarballs/%s
104     cd %s
105
106     echo %s > localconfigure
107     chmod +x localconfigure
108     echo %s > localenv
109
110     ./localconfigure
111     make V=1
112     make maintainer-upload-website WEBSITESDIR=%s
113   " buildtmp version.tarball
114     version.package_version
115     (quote (libguestfs_localconfigure `Tarball))
116     (quote (libguestfs_localenv (supermin version)))
117     (quote websites_repo)
118
119 (* Goal: the tarball has passed the required set of tests before
120  * a release is allowed.
121  *)
122 and tarball_tested version =
123   let key = sprintf "libguestfs_tarball_tested_%s" version.version in
124   target (memory_exists key);
125   onrun (fun () -> memory_set key "1");
126
127   require (tarball_created version);
128
129   sh "
130     tar zxf %s/tarballs/%s
131     cd %s
132
133     echo %s > localconfigure
134     chmod +x localconfigure
135     echo %s > localenv
136
137     ./localconfigure
138     make V=1
139     if ! make check-release; then
140       for f in `find -name test-suite.log | xargs grep -l ^FAIL:`; do
141         echo \"*** $f ***\"
142         cat $f
143       done
144       exit 1
145     fi
146   " buildtmp version.tarball
147     version.package_version
148     (quote (libguestfs_localconfigure `Tarball))
149     (quote (libguestfs_localenv (supermin version)))
150
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);
155
156   require (repo_up_to_date version.branch);
157
158   let repodir = sprintf "%s/repos/%s-%s" buildtmp package version.branch in
159
160   (* Branches <= 1.32 are tagged with "1.32.11",
161    * branches >= 1.33 are tagged with "v1.33.11".
162    *)
163   let version_tag =
164     if version.minor >= 33 then "v" ^ version.version
165     else version.version in
166
167   sh "
168     cp -a %s libguestfs
169     cd libguestfs
170     git reset --hard %s
171
172     echo %s > localconfigure
173     chmod +x localconfigure
174     echo %s > localenv
175
176     ./localconfigure
177
178     # Ensure the po-docs are updated.  Grrr this is ugly ...
179     make ||:
180     rm po-docs/podfiles
181     make -C po-docs update-po
182
183     make V=1
184     make dist
185
186     # Ensure redhat hardening flags didn't leak into the tarball.
187     # https://bugzilla.redhat.com/show_bug.cgi?id=1214506
188     if zcat %s | grep -q redhat-hardened; then exit 1; fi
189
190     mv %s %s/tarballs/%s
191   " repodir
192     version_tag
193     (quote (libguestfs_localconfigure `Git))
194     (quote (libguestfs_localenv (supermin version)))
195     version.tarball
196     version.tarball buildtmp version.tarball
197
198 (* Goal: test a commit. *)
199 and commit_tested branch commit =
200   onfail (
201     fun _ ->
202       let subject = sprintf "goal: %s: FAILED" goalname in
203       mailto ~from ~subject (*~attach:[logfile]*) to_
204   );
205
206   let key = sprintf "libguestfs_commit_tested_%s" commit in
207   target (memory_exists key);
208   onrun (fun () -> memory_set key "1");
209
210   require (repo_up_to_date branch);
211
212   let repodir = sprintf "%s/repos/%s-%s" buildtmp package branch in
213
214   sh "
215     cp -a %s libguestfs
216     cd libguestfs
217     git reset --hard %s
218
219     echo %s > localconfigure
220     chmod +x localconfigure
221     echo %s > localenv
222
223     ./localconfigure
224     make V=1
225     if ! make check-release; then
226       for f in `find -name test-suite.log | xargs grep -l ^FAIL:`; do
227         echo \"*** $f ***\"
228         cat $f
229       done
230       exit 1
231     fi
232   " repodir
233     commit
234     (quote (libguestfs_localconfigure `Git))
235     (quote (libguestfs_localenv None))
236
237 and repo_up_to_date branch =
238   git_force branch
239
240 (* Goals for Python sdists. *)
241 and python_website_checked_in version =
242   let key = sprintf "libguestfs_python_website_checked_in_%s" version.version in
243   target (memory_exists key);
244   onrun (fun () -> memory_set key "1");
245
246   require (python_tarball_created version);
247   require (python_tarball_tested version);
248
249   sh "
250     cd %s
251     cp %s/tarballs/%s %s
252     git add %s
253     git commit -m \"Python sdist version %s\"
254   " libguestfs_download_repo
255     buildtmp version.python_tarball version.python_urlpath
256     version.python_urlpath
257     version.version
258
259 and python_tarball_tested version =
260   let key = sprintf "libguestfs_python_tarball_tested_%s" version.version in
261   target (memory_exists key);
262   onrun (fun () -> memory_set key "1");
263
264   require (python_tarball_created version);
265
266   sh "
267     virtualenv venv
268     source ./venv/bin/activate
269     pip install %s/tarballs/%s
270   " buildtmp version.python_tarball
271
272 and python_tarball_created version =
273   let filename = sprintf "%s/tarballs/%s" buildtmp version.python_tarball in
274   target (file_exists filename);
275
276   require (tarball_created version);
277
278   sh "
279     tar zxf %s/tarballs/%s
280     cd %s
281
282     echo %s > localconfigure
283     chmod +x localconfigure
284     echo %s > localenv
285
286     ./localconfigure
287     make V=1
288     make -C python sdist
289     cp python/dist/%s %s
290   " buildtmp version.tarball
291     version.package_version
292     (quote (libguestfs_localconfigure `Tarball))
293     (quote (libguestfs_localenv (supermin version)))
294     version.python_tarball filename
295
296 let () =
297   (* Add a periodic job to check for new git commits and test them. *)
298   every libguestfs_query_mins minutes ~name:"new libguestfs commit" (
299     fun () ->
300       require (repo_up_to_date "master");
301       let commit = git_latest_commit "master" in
302       require (commit_tested "master" commit);
303   );
304
305   (* Periodic job to build new tarballs. *)
306   every libguestfs_query_mins minutes ~name:"new libguestfs version" (
307     fun () ->
308       require (repo_up_to_date "master");
309       let version = git_latest_version "master" in
310       require (website_updated version)
311   )
312
313 (* Allow these jobs to run from the command line. *)
314 let () =
315   publish "commit" (
316     function
317     | [commit] -> require (commit_tested "master" commit)
318     | [branch; commit] -> require (commit_tested branch commit)
319     | _ ->
320       failwith "use './libguestfs_upstream commit [<branch>] <commit>'"
321   );
322   publish "release" (
323     function
324     | [version] -> require (website_updated (vernames version))
325     | _ ->
326       failwith "use './libguestfs_upstream release <version>'"
327   )