OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # | 2 # |
3 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 3 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
4 # for details. All rights reserved. Use of this source code is governed by a | 4 # for details. All rights reserved. Use of this source code is governed by a |
5 # BSD-style license that can be found in the LICENSE file. | 5 # BSD-style license that can be found in the LICENSE file. |
6 | 6 |
7 # Dart Editor promote tools. | 7 # Dart Editor promote tools. |
8 | 8 |
9 import imp | 9 import imp |
10 import optparse | 10 import optparse |
11 import os | 11 import os |
12 import subprocess | 12 import subprocess |
13 import sys | 13 import sys |
14 import time | 14 import time |
15 import urllib | 15 import urllib |
16 import bots.bot_utils as bot_utils | 16 import bots.bot_utils as bot_utils |
17 | 17 |
18 from os.path import join | 18 from os.path import join |
19 | 19 |
20 DART_PATH = os.path.abspath(os.path.join(__file__, '..', '..')) | 20 DART_PATH = os.path.abspath(os.path.join(__file__, '..', '..')) |
| 21 DRY_RUN = False |
21 | 22 |
22 def BuildOptions(): | 23 def BuildOptions(): |
23 usage = """usage: %prog promote [options] | 24 usage = """usage: %prog promote [options] |
24 where: | 25 where: |
25 promote - Will promote builds from raw/signed locations to release | 26 promote - Will promote builds from raw/signed locations to release |
26 locations. | 27 locations. |
27 | 28 |
28 Example: Promote revision r29962 on dev channel: | 29 Example: Promote revision r29962 on dev channel: |
29 python editor/build/promote.py promote --channel=dev --revision=29962 | 30 python editor/build/promote.py promote --channel=dev --revision=29962 |
30 """ | 31 """ |
31 | 32 |
32 result = optparse.OptionParser(usage=usage) | 33 result = optparse.OptionParser(usage=usage) |
33 | 34 |
34 group = optparse.OptionGroup( | 35 group = optparse.OptionGroup( |
35 result, 'Promote', 'options used to promote code') | 36 result, 'Promote', 'options used to promote code') |
36 group.add_option( | 37 group.add_option( |
37 '--revision', help='The svn revision to promote', action='store') | 38 '--revision', help='The svn revision to promote', action='store') |
38 group.add_option( | 39 group.add_option( |
39 '--channel', type='string', help='Channel to promote.', default=None) | 40 '--channel', type='string', help='Channel to promote.', default=None) |
| 41 group.add_option("--dry", help='Dry run', default=False, action="store_true") |
40 result.add_option_group(group) | 42 result.add_option_group(group) |
41 | 43 |
42 return result | 44 return result |
43 | 45 |
44 | 46 |
45 def main(): | 47 def main(): |
46 parser = BuildOptions() | 48 parser = BuildOptions() |
47 (options, args) = parser.parse_args() | 49 (options, args) = parser.parse_args() |
48 | 50 |
49 def die(msg): | 51 def die(msg): |
(...skipping 16 matching lines...) Expand all Loading... |
66 die('You must supply a valid integer argument to --revision to promote') | 68 die('You must supply a valid integer argument to --revision to promote') |
67 | 69 |
68 # Make sure options.channel is a valid | 70 # Make sure options.channel is a valid |
69 if not options.channel: | 71 if not options.channel: |
70 die('Specify --channel=be/dev/stable') | 72 die('Specify --channel=be/dev/stable') |
71 if options.channel not in bot_utils.Channel.ALL_CHANNELS: | 73 if options.channel not in bot_utils.Channel.ALL_CHANNELS: |
72 die('You must supply a valid channel to --channel to promote') | 74 die('You must supply a valid channel to --channel to promote') |
73 else: | 75 else: |
74 die('Invalid command specified: {0}. See help below'.format(args[0])) | 76 die('Invalid command specified: {0}. See help below'.format(args[0])) |
75 | 77 |
| 78 if options.dry: |
| 79 global DRY_RUN |
| 80 DRY_RUN = True |
76 if command == 'promote': | 81 if command == 'promote': |
77 _PromoteDartArchiveBuild(options.channel, options.revision) | 82 _PromoteDartArchiveBuild(options.channel, options.revision) |
78 | 83 |
79 | 84 |
80 def UpdateDocs(): | 85 def UpdateDocs(): |
81 try: | 86 try: |
82 print 'Updating docs' | 87 print 'Updating docs' |
83 url = "http://api.dartlang.org/docs/releases/latest/?force_reload=true" | 88 url = "http://api.dartlang.org/docs/releases/latest/?force_reload=true" |
84 f = urllib.urlopen(url) | 89 f = urllib.urlopen(url) |
85 f.read() | 90 f.read() |
(...skipping 20 matching lines...) Expand all Loading... |
106 "InternalError: Sanity check failed on GS URI: %s" % gs_path) | 111 "InternalError: Sanity check failed on GS URI: %s" % gs_path) |
107 | 112 |
108 # Google cloud storage has read-after-write, read-after-update, | 113 # Google cloud storage has read-after-write, read-after-update, |
109 # and read-after-delete consistency, but not list after delete consistency. | 114 # and read-after-delete consistency, but not list after delete consistency. |
110 # Because gsutil uses list to figure out if it should do the unix styly | 115 # Because gsutil uses list to figure out if it should do the unix styly |
111 # copy to or copy into, this means that if the directory is reported as | 116 # copy to or copy into, this means that if the directory is reported as |
112 # still being there (after it has been deleted) gsutil will copy | 117 # still being there (after it has been deleted) gsutil will copy |
113 # into the directory instead of to the directory. | 118 # into the directory instead of to the directory. |
114 def wait_for_delete_to_be_consistent_with_list(gs_path): | 119 def wait_for_delete_to_be_consistent_with_list(gs_path): |
115 while True: | 120 while True: |
| 121 if DRY_RUN: |
| 122 break |
116 (_, _, exit_code) = Gsutil(['ls', gs_path], throw_on_error=False) | 123 (_, _, exit_code) = Gsutil(['ls', gs_path], throw_on_error=False) |
117 # gsutil will exit 1 if the "directory" does not exist | 124 # gsutil will exit 1 if the "directory" does not exist |
118 if exit_code != 0: | 125 if exit_code != 0: |
119 break | 126 break |
120 time.sleep(1) | 127 time.sleep(1) |
121 | 128 |
122 def remove_gs_directory(gs_path): | 129 def remove_gs_directory(gs_path): |
123 safety_check_on_gs_path(gs_path, to_revision, channel) | 130 safety_check_on_gs_path(gs_path, to_revision, channel) |
124 Gsutil(['-m', 'rm', '-R', '-f', gs_path]) | 131 Gsutil(['-m', 'rm', '-R', '-f', gs_path]) |
125 wait_for_delete_to_be_consistent_with_list(gs_path) | 132 wait_for_delete_to_be_consistent_with_list(gs_path) |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 from_loc = raw_namer.version_filepath(revision) | 165 from_loc = raw_namer.version_filepath(revision) |
159 to_loc = release_namer.version_filepath(to_revision) | 166 to_loc = release_namer.version_filepath(to_revision) |
160 Gsutil(['cp', '-a', 'public-read', from_loc, to_loc]) | 167 Gsutil(['cp', '-a', 'public-read', from_loc, to_loc]) |
161 | 168 |
162 | 169 |
163 promote(revision) | 170 promote(revision) |
164 promote('latest') | 171 promote('latest') |
165 | 172 |
166 def Gsutil(cmd, throw_on_error=True): | 173 def Gsutil(cmd, throw_on_error=True): |
167 gsutilTool = join(DART_PATH, 'third_party', 'gsutil', 'gsutil') | 174 gsutilTool = join(DART_PATH, 'third_party', 'gsutil', 'gsutil') |
168 return bot_utils.run([sys.executable, gsutilTool] + cmd, | 175 command = [sys.executable, gsutilTool] + cmd |
169 throw_on_error=throw_on_error) | 176 if DRY_RUN: |
| 177 print "DRY runnning: %s" % command |
| 178 return |
| 179 return bot_utils.run(command, throw_on_error=throw_on_error) |
170 | 180 |
171 | 181 |
172 if __name__ == '__main__': | 182 if __name__ == '__main__': |
173 sys.exit(main()) | 183 sys.exit(main()) |
OLD | NEW |