summaryrefslogtreecommitdiff
path: root/chromium/v8/tools/release/auto_roll.py
blob: f7692cf6f9775681a9afdb6c13d82c60bb874044 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/usr/bin/env python
# Copyright 2014 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import argparse
import json
import os
import sys
import urllib

from common_includes import *
import chromium_roll


class CheckActiveRoll(Step):
  MESSAGE = "Check active roll."

  @staticmethod
  def ContainsChromiumRoll(changes):
    for change in changes:
      if change["subject"].startswith("Update V8 to"):
        return True
    return False

  def RunStep(self):
    params = {
      "closed": 3,
      "owner": self._options.author,
      "limit": 30,
      "format": "json",
    }
    params = urllib.urlencode(params)
    search_url = "https://codereview.chromium.org/search"
    result = self.ReadURL(search_url, params, wait_plan=[5, 20])
    if self.ContainsChromiumRoll(json.loads(result)["results"]):
      print "Stop due to existing Chromium roll."
      return True


class DetectLastRoll(Step):
  MESSAGE = "Detect commit ID of the last Chromium roll."

  def RunStep(self):
    # The revision that should be rolled. Check for the latest of the most
    # recent releases based on commit timestamp.
    revisions = self.GetRecentReleases(
        max_age=self._options.max_age * DAY_IN_SECONDS)
    assert revisions, "Didn't find any recent release."

    # Interpret the DEPS file to retrieve the v8 revision.
    # TODO(machenbach): This should be part or the roll-deps api of
    # depot_tools.
    Var = lambda var: '%s'
    exec(FileToText(os.path.join(self._options.chromium, "DEPS")))

    # The revision rolled last.
    self["last_roll"] = vars['v8_revision']
    last_version = self.GetVersionTag(self["last_roll"])
    assert last_version, "The last rolled v8 revision is not tagged."

    # There must be some progress between the last roll and the new candidate
    # revision (i.e. we don't go backwards). The revisions are ordered newest
    # to oldest. It is possible that the newest timestamp has no progress
    # compared to the last roll, i.e. if the newest release is a cherry-pick
    # on a release branch. Then we look further.
    for revision in revisions:
      version = self.GetVersionTag(revision)
      assert version, "Internal error. All recent releases should have a tag"

      if SortingKey(last_version) < SortingKey(version):
        self["roll"] = revision
        break
    else:
      print("There is no newer v8 revision than the one in Chromium (%s)."
            % self["last_roll"])
      return True


class RollChromium(Step):
  MESSAGE = "Roll V8 into Chromium."

  def RunStep(self):
    if self._options.roll:
      args = [
        "--author", self._options.author,
        "--reviewer", self._options.reviewer,
        "--chromium", self._options.chromium,
        "--last-roll", self["last_roll"],
        "--use-commit-queue",
        self["roll"],
      ]
      if self._options.sheriff:
        args.append("--sheriff")
      if self._options.dry_run:
        args.append("--dry-run")
      if self._options.work_dir:
        args.extend(["--work-dir", self._options.work_dir])
      self._side_effect_handler.Call(chromium_roll.ChromiumRoll().Run, args)


class AutoRoll(ScriptsBase):
  def _PrepareOptions(self, parser):
    parser.add_argument("-c", "--chromium", required=True,
                        help=("The path to your Chromium src/ "
                              "directory to automate the V8 roll."))
    parser.add_argument("--max-age", default=3, type=int,
                        help="Maximum age in days of the latest release.")
    parser.add_argument("--roll", help="Call Chromium roll script.",
                        default=False, action="store_true")

  def _ProcessOptions(self, options):  # pragma: no cover
    if not options.reviewer:
      print "A reviewer (-r) is required."
      return False
    if not options.author:
      print "An author (-a) is required."
      return False
    return True

  def _Config(self):
    return {
      "PERSISTFILE_BASENAME": "/tmp/v8-auto-roll-tempfile",
    }

  def _Steps(self):
    return [
      CheckActiveRoll,
      DetectLastRoll,
      RollChromium,
    ]


if __name__ == "__main__":  # pragma: no cover
  sys.exit(AutoRoll().Run())