OLD | NEW |
1 # Copyright 2014 The Chromium Authors. All rights reserved. | 1 # Copyright 2014 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 """An auto-roller for GN binaries into Chromium. | 5 """An auto-roller for GN binaries into Chromium. |
6 | 6 |
7 This script is used to update the GN binaries that a Chromium | 7 This script is used to update the GN binaries that a Chromium |
8 checkout uses. In order to update the binaries, one must follow | 8 checkout uses. In order to update the binaries, one must follow |
9 four steps in order: | 9 four steps in order: |
10 | 10 |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 new_deps = deps_content.replace("'buildtools_revision':", | 175 new_deps = deps_content.replace("'buildtools_revision':", |
176 "'buildtools_revision': ") | 176 "'buildtools_revision': ") |
177 | 177 |
178 with open('DEPS', 'w') as fp: | 178 with open('DEPS', 'w') as fp: |
179 fp.write(new_deps) | 179 fp.write(new_deps) |
180 | 180 |
181 def WaitForBuildToFinish(self): | 181 def WaitForBuildToFinish(self): |
182 print('Checking build') | 182 print('Checking build') |
183 results = self.CheckBuild() | 183 results = self.CheckBuild() |
184 while (len(results) < 3 or | 184 while (len(results) < 3 or |
185 any(r['state'] == 'pending' for r in results.values())): | 185 any(r['state'] in ('pending', 'started') |
| 186 for r in results.values())): |
186 print() | 187 print() |
187 print('Sleeping for 30 seconds') | 188 print('Sleeping for 30 seconds') |
188 time.sleep(30) | 189 time.sleep(30) |
189 print('Checking build') | 190 print('Checking build') |
190 results = self.CheckBuild() | 191 results = self.CheckBuild() |
191 return 0 if all(r['state'] == 'success' for r in results.values()) else 1 | 192 |
| 193 ret = 0 if all(r['state'] == 'success' for r in results.values()) else 1 |
| 194 if ret: |
| 195 print('Build failed.') |
| 196 else: |
| 197 print('Builds ready.') |
| 198 |
| 199 # Close the build CL and move off of the build branch back to whatever |
| 200 # we were on before. |
| 201 self.Call('git-cl set-close') |
| 202 self.MovetoLastHead() |
| 203 |
| 204 return ret |
192 | 205 |
193 def CheckBuild(self): | 206 def CheckBuild(self): |
194 _, out, _ = self.Call('git-cl issue') | 207 _, out, _ = self.Call('git-cl issue') |
195 | 208 |
196 issue = int(out.split()[2]) | 209 issue = int(out.split()[2]) |
197 | 210 |
198 _, out, _ = self.Call('git config user.email') | 211 _, out, _ = self.Call('git config user.email') |
199 email = '' | 212 email = '' |
200 rpc_server = upload.GetRpcServer(CODE_REVIEW_SERVER, email) | 213 rpc_server = upload.GetRpcServer(CODE_REVIEW_SERVER, email) |
201 try: | 214 try: |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 print(' sha1: %s' % r['sha1']) | 270 print(' sha1: %s' % r['sha1']) |
258 print(' state: %s' % r['state']) | 271 print(' state: %s' % r['state']) |
259 print(' build: %s' % r['build']) | 272 print(' build: %s' % r['build']) |
260 print(' url: %s' % r['url']) | 273 print(' url: %s' % r['url']) |
261 print() | 274 print() |
262 | 275 |
263 return results | 276 return results |
264 | 277 |
265 def RollBuildtools(self): | 278 def RollBuildtools(self): |
266 results = self.CheckBuild() | 279 results = self.CheckBuild() |
267 if not all(r['state'] == 'success' for r in results.values()): | 280 if (len(results) < 3 or |
| 281 not all(r['state'] == 'success' for r in results.values())): |
268 print("Roll isn't done or didn't succeed, exiting:") | 282 print("Roll isn't done or didn't succeed, exiting:") |
269 return 1 | 283 return 1 |
270 | 284 |
271 desc = self.GetBuildtoolsDesc() | 285 desc = self.GetBuildtoolsDesc() |
272 | 286 |
273 self.Call('git new-branch roll_buildtools_gn_%s' % self.new_gn_version, | 287 self.Call('git new-branch roll_buildtools_gn_%s' % self.new_gn_version, |
274 cwd=self.buildtools_dir) | 288 cwd=self.buildtools_dir) |
275 | 289 |
276 for platform in results: | 290 for platform in results: |
277 fname = 'gn.exe.sha1' if platform == 'win' else 'gn.sha1' | 291 fname = 'gn.exe.sha1' if platform == 'win' else 'gn.sha1' |
(...skipping 21 matching lines...) Expand all Loading... |
299 print(err) | 313 print(err) |
300 return ret | 314 return ret |
301 | 315 |
302 # Fetch the revision we just committed so that RollDEPS will find it. | 316 # Fetch the revision we just committed so that RollDEPS will find it. |
303 self.Call('git fetch', cwd=self.buildtools_dir) | 317 self.Call('git fetch', cwd=self.buildtools_dir) |
304 | 318 |
305 # Reset buildtools to the new commit so that we're not still on the | 319 # Reset buildtools to the new commit so that we're not still on the |
306 # merged branch. | 320 # merged branch. |
307 self.Call('git checkout origin/master', cwd=self.buildtools_dir) | 321 self.Call('git checkout origin/master', cwd=self.buildtools_dir) |
308 | 322 |
| 323 _, out, _ = self.Call('git rev-parse origin/master', |
| 324 cwd=self.buildtools_dir) |
| 325 new_buildtools_commitish = out.strip() |
| 326 print('Ready to roll buildtools to %s in DEPS' % new_buildtools_commitish) |
| 327 |
309 return 0 | 328 return 0 |
310 | 329 |
311 def RollDEPS(self): | 330 def RollDEPS(self): |
312 ret, _, _ = self.Call('git new-branch roll_gn_%s' % self.new_gn_version) | 331 ret, _, _ = self.Call('git new-branch roll_gn_%s' % self.new_gn_version) |
313 if ret: | 332 if ret: |
314 print('Failed to create a new branch for roll_gn_%s' % | 333 print('Failed to create a new branch for roll_gn_%s' % |
315 self.new_gn_version) | 334 self.new_gn_version) |
316 return 1 | 335 return 1 |
317 | 336 |
318 _, out, _ = self.Call('git rev-parse origin/master', | 337 _, out, _ = self.Call('git rev-parse origin/master', |
(...skipping 10 matching lines...) Expand all Loading... |
329 new_deps_lines.append(" 'buildtools_revision': '%s',\n" % | 348 new_deps_lines.append(" 'buildtools_revision': '%s',\n" % |
330 new_buildtools_commitish) | 349 new_buildtools_commitish) |
331 else: | 350 else: |
332 new_deps_lines.append(l) | 351 new_deps_lines.append(l) |
333 | 352 |
334 if not old_buildtools_commitish: | 353 if not old_buildtools_commitish: |
335 print('Could not update DEPS properly, exiting') | 354 print('Could not update DEPS properly, exiting') |
336 return 1 | 355 return 1 |
337 | 356 |
338 with open('DEPS', 'w') as fp: | 357 with open('DEPS', 'w') as fp: |
339 fp.write(''.join(new_deps_lines) + '\n') | 358 fp.write(''.join(new_deps_lines)) |
340 | 359 |
341 desc = self.GetDEPSRollDesc(old_buildtools_commitish, | 360 desc = self.GetDEPSRollDesc(old_buildtools_commitish, |
342 new_buildtools_commitish) | 361 new_buildtools_commitish) |
343 desc_file = tempfile.NamedTemporaryFile(delete=False) | 362 desc_file = tempfile.NamedTemporaryFile(delete=False) |
344 try: | 363 try: |
345 desc_file.write(desc) | 364 desc_file.write(desc) |
346 desc_file.close() | 365 desc_file.close() |
347 self.Call('git commit -a -F %s' % desc_file.name) | 366 self.Call('git commit -a -F %s' % desc_file.name) |
348 self.Call('git-cl upload -f --send-mail --use-commit-queue') | 367 self.Call('git-cl upload -f --send-mail --use-commit-queue') |
349 finally: | 368 finally: |
350 os.remove(desc_file.name) | 369 os.remove(desc_file.name) |
351 | 370 |
352 # Intentionally leave the src checkout on the new branch with the roll | 371 # Move off of the roll branch onto whatever we were on before. |
353 # since we're not auto-committing it. | 372 # Do not explicitly close the roll CL issue, however; the CQ |
| 373 # will close it when the roll lands, assuming it does so. |
| 374 self.MoveToLastHead() |
354 | 375 |
355 return 0 | 376 return 0 |
356 | 377 |
| 378 def MovetoLastHead(self): |
| 379 _, out, _ = self.Call('git reflog -1') |
| 380 m = re.match('moving from ([^\s]+)', out) |
| 381 last_head = m.group(1) |
| 382 self.Call('git checkout %s' % last_head) |
| 383 |
357 def GetBuildtoolsDesc(self): | 384 def GetBuildtoolsDesc(self): |
358 gn_changes = self.GetGNChanges() | 385 gn_changes = self.GetGNChanges() |
359 return ( | 386 return ( |
360 'Roll gn %s..%s (r%s:r%s)\n' | 387 'Roll gn %s..%s (r%s:r%s)\n' |
361 '\n' | 388 '\n' |
362 '%s' | 389 '%s' |
363 '\n' | 390 '\n' |
364 'TBR=%s\n' % ( | 391 'TBR=%s\n' % ( |
365 self.old_gn_commitish[:COMMITISH_DIGITS], | 392 self.old_gn_commitish[:COMMITISH_DIGITS], |
366 self.new_gn_commitish[:COMMITISH_DIGITS], | 393 self.new_gn_commitish[:COMMITISH_DIGITS], |
367 self.old_gn_version, | 394 self.old_gn_version, |
368 self.new_gn_version, | 395 self.new_gn_version, |
369 gn_changes, | 396 gn_changes, |
370 self.reviewer, | 397 self.reviewer, |
371 )) | 398 )) |
372 | 399 |
373 def GetDEPSRollDesc(self, old_buildtools_commitish, new_buildtools_commitish): | 400 def GetDEPSRollDesc(self, old_buildtools_commitish, new_buildtools_commitish): |
374 gn_changes = self.GetGNChanges() | 401 gn_changes = self.GetGNChanges() |
375 | 402 |
376 return ( | 403 return ( |
377 'Roll buildtools %s..%s\n' | 404 'Roll buildtools %s..%s\n' |
378 '\n' | 405 '\n' |
379 ' In order to roll GN %s..%s (r%s:r%s) and pick up\n' | 406 ' In order to roll GN %s..%s (r%s:r%s) and pick up\n' |
380 ' the following changes:\n' | 407 ' the following changes:\n' |
381 '\n' | 408 '\n' |
382 '%s' | 409 '%s' |
383 '\n' | 410 '\n' |
384 'TBR=%s\n' | 411 'TBR=%s\n' |
385 'CQ_EXTRA_TRYBOTS=tryserver.chromium.mac:mac_chromium_gn_rel,' | 412 'CQ_EXTRA_TRYBOTS=tryserver.chromium.mac:mac_chromium_gn_dbg;' |
386 'mac_chromium_gn_dbg;' | |
387 'tryserver.chromium.win:win8_chromium_gn_dbg,' | 413 'tryserver.chromium.win:win8_chromium_gn_dbg,' |
388 'win_chromium_gn_x64_rel\n' % ( | 414 'win_chromium_gn_x64_rel\n' % ( |
389 old_buildtools_commitish[:COMMITISH_DIGITS], | 415 old_buildtools_commitish[:COMMITISH_DIGITS], |
390 new_buildtools_commitish[:COMMITISH_DIGITS], | 416 new_buildtools_commitish[:COMMITISH_DIGITS], |
391 self.old_gn_commitish[:COMMITISH_DIGITS], | 417 self.old_gn_commitish[:COMMITISH_DIGITS], |
392 self.new_gn_commitish[:COMMITISH_DIGITS], | 418 self.new_gn_commitish[:COMMITISH_DIGITS], |
393 self.old_gn_version, | 419 self.old_gn_version, |
394 self.new_gn_version, | 420 self.new_gn_version, |
395 gn_changes, | 421 gn_changes, |
396 self.reviewer, | 422 self.reviewer, |
397 )) | 423 )) |
398 | 424 |
399 def GetGNChanges(self): | 425 def GetGNChanges(self): |
400 _, out, _ = self.Call( | 426 _, out, _ = self.Call( |
401 "git log --pretty=' %h %s' " + | 427 "git log --pretty=' %h %s' " + |
402 "%s..%s tools/gn" % (self.old_gn_commitish, self.new_gn_commitish)) | 428 "%s..%s tools/gn" % (self.old_gn_commitish, self.new_gn_commitish)) |
403 return out | 429 return out |
404 | 430 |
405 def Call(self, cmd, cwd=None): | 431 def Call(self, cmd, cwd=None): |
406 proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True, | 432 proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True, |
407 cwd=(cwd or self.chromium_src_dir)) | 433 cwd=(cwd or self.chromium_src_dir)) |
408 out, err = proc.communicate() | 434 out, err = proc.communicate() |
409 return proc.returncode, out, err | 435 return proc.returncode, out, err |
410 | 436 |
411 | 437 |
412 if __name__ == '__main__': | 438 if __name__ == '__main__': |
413 roller = GNRoller() | 439 roller = GNRoller() |
414 sys.exit(roller.Roll()) | 440 sys.exit(roller.Roll()) |
OLD | NEW |