libguestfs: Handle new-style v1.XX.YY tags.
[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
35   require (tarball_created version);
36   require (tarball_tested version);
37
38   (* We only update the website for the development releases. *)
39   if not version.is_stable then
40     require (website_built version);
41
42   require (website_checked_in version);
43   require (website_rsync_done version)
44
45 (* Goal: website has been rsync'd. *)
46 and website_rsync_done version =
47   target (url_contains_string "http://libguestfs.org" version.version &&
48           url_exists version.url);
49
50   sh "
51     cd %s
52     ./.rsync
53   " libguestfs_website_repo
54
55 (* Goal: Tarball added to repository and checked in. *)
56 and website_checked_in version =
57   let key = sprintf "libguestfs_website_checked_in_%s" version.version in
58   target (memory_exists key);
59   onrun (fun () -> memory_set key "1");
60
61   require (tarball_created version);
62   require (tarball_tested version);
63
64   sh "
65     cd %s
66     cp %s/tarballs/%s %s
67     git add %s
68     git add *.txt *.html
69     git commit -m \"Version %s\"
70   " libguestfs_website_repo
71     buildtmp version.tarball version.urlpath
72     version.urlpath
73     version.version
74
75 (* Goal: website (local copy) has been built. *)
76 and website_built version =
77   let index_file = sprintf "%s/index.html" libguestfs_website_repo in
78   target (file_contains_string index_file version.version);
79
80   require (tarball_created version);
81   require (tarball_tested version);
82
83   (* We should only update the website on development releases. *)
84   assert (not version.is_stable);
85
86   sh "
87     tar zxf %s/tarballs/%s
88     cd %s
89
90     echo %s > localconfigure
91     chmod +x localconfigure
92     echo %s > localenv
93
94     ./localconfigure
95     make V=1
96     make maintainer-upload-website WEBSITEDIR=%s
97   " buildtmp version.tarball
98     version.package_version
99     (quote (libguestfs_localconfigure `Tarball))
100     (quote (libguestfs_localenv (supermin version)))
101     (quote libguestfs_website_repo)
102
103 (* Goal: the tarball has passed the required set of tests before
104  * a release is allowed.
105  *)
106 and tarball_tested version =
107   let key = sprintf "libguestfs_tarball_tested_%s" version.version in
108   target (memory_exists key);
109   onrun (fun () -> memory_set key "1");
110
111   require (tarball_created version);
112
113   sh "
114     tar zxf %s/tarballs/%s
115     cd %s
116
117     echo %s > localconfigure
118     chmod +x localconfigure
119     echo %s > localenv
120
121     ./localconfigure
122     make V=1
123     make check-release
124   " buildtmp version.tarball
125     version.package_version
126     (quote (libguestfs_localconfigure `Tarball))
127     (quote (libguestfs_localenv (supermin version)))
128
129 (* Goal: the tarball has been created from git. *)
130 and tarball_created version =
131   let filename = sprintf "%s/tarballs/%s" buildtmp version.tarball in
132   target (file_exists filename);
133
134   require (repo_up_to_date version.branch);
135
136   let repodir = sprintf "%s/repos/%s-%s" buildtmp package version.branch in
137
138   (* Branches <= 1.32 are tagged with "1.32.11",
139    * branches >= 1.33 are tagged with "v1.33.11".
140    *)
141   let version_tag =
142     if version.minor >= 33 then "v" ^ version.version
143     else version.version in
144
145   sh "
146     cp -a %s libguestfs
147     cd libguestfs
148     git reset --hard %s
149
150     echo %s > localconfigure
151     chmod +x localconfigure
152     echo %s > localenv
153
154     ./localconfigure
155
156     # Ensure the po-docs are updated.  Grrr this is ugly ...
157     make ||:
158     rm po-docs/podfiles
159     make -C po-docs update-po
160
161     make V=1
162     make dist
163
164     # Ensure redhat hardening flags didn't leak into the tarball.
165     # https://bugzilla.redhat.com/show_bug.cgi?id=1214506
166     if zcat %s | grep -q redhat-hardened; then exit 1; fi
167
168     mv %s %s/tarballs/%s
169   " repodir
170     version_tag
171     (quote (libguestfs_localconfigure `Git))
172     (quote (libguestfs_localenv (supermin version)))
173     version.tarball
174     version.tarball buildtmp version.tarball
175
176 (* Goal: test a commit. *)
177 and commit_tested branch commit =
178   onfail (
179     fun _ ->
180       let subject = sprintf "goal: %s: FAILED" goalname in
181       mailto ~from ~subject (*~attach:[logfile]*) to_
182   );
183
184   let key = sprintf "libguestfs_commit_tested_%s" commit in
185   target (memory_exists key);
186   onrun (fun () -> memory_set key "1");
187
188   require (repo_up_to_date branch);
189
190   let repodir = sprintf "%s/repos/%s-%s" buildtmp package branch in
191
192   sh "
193     cp -a %s libguestfs
194     cd libguestfs
195     git reset --hard %s
196
197     echo %s > localconfigure
198     chmod +x localconfigure
199     echo %s > localenv
200
201     ./localconfigure
202     make V=1
203     make check-release
204   " repodir
205     commit
206     (quote (libguestfs_localconfigure `Git))
207     (quote (libguestfs_localenv None))
208
209 and repo_up_to_date branch =
210   git_force branch
211
212 let () =
213   (* Add a periodic job to check for new git commits and test them. *)
214   every libguestfs_query_mins minutes ~name:"new libguestfs commit" (
215     fun () ->
216       require (repo_up_to_date "master");
217       let commit = git_latest_commit "master" in
218       require (commit_tested "master" commit);
219   );
220
221   (* Periodic job to build new tarballs. *)
222   every libguestfs_query_mins minutes ~name:"new libguestfs version" (
223     fun () ->
224       require (repo_up_to_date "master");
225       let version = git_latest_version "master" in
226       require (website_updated version)
227   )
228
229 (* Allow these jobs to run from the command line. *)
230 let () =
231   publish "commit" (
232     function
233     | [commit] -> require (commit_tested "master" commit)
234     | [branch; commit] -> require (commit_tested branch commit)
235     | _ ->
236       failwith "use './libguestfs_upstream commit [<branch>] <commit>'"
237   );
238   publish "release" (
239     function
240     | [version] -> require (website_updated (vernames version))
241     | _ ->
242       failwith "use './libguestfs_upstream release <version>'"
243   )