Skip to content

Commit 48219d6

Browse files
sortieCommit Queue
authored and
Commit Queue
committed
[infra] Promote beta to stable when stable is ahead of beta.
Don't promote older releases to latest if promoted out of order. Fixes: b/227744513 Change-Id: I954c8620897e59ed3caa459e0bd22e446e38d02d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/283622 Commit-Queue: Jonas Termansen <[email protected]> Reviewed-by: Alexander Thomas <[email protected]>
1 parent 5421297 commit 48219d6

File tree

2 files changed

+98
-4
lines changed

2 files changed

+98
-4
lines changed

tools/promote.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
# Dart SDK promote tools.
88

9+
import json
910
import optparse
1011
import os
1112
import sys
@@ -14,6 +15,7 @@
1415
import bots.bot_utils as bot_utils
1516

1617
from os.path import join
18+
from utils import Version
1719

1820
DART_PATH = os.path.abspath(os.path.join(__file__, '..', '..'))
1921
DRY_RUN = False
@@ -93,6 +95,18 @@ def die(msg):
9395
_PromoteDartArchiveBuild(options.channel, source, options.revision)
9496

9597

98+
def GetLatestRelease(channel):
99+
release_namer = bot_utils.GCSNamer(channel, bot_utils.ReleaseType.RELEASE)
100+
version_object = release_namer.version_filepath('latest')
101+
global DRY_RUN
102+
was_dry = DRY_RUN
103+
DRY_RUN = False
104+
(stdout, _, _) = Gsutil(['cat', version_object])
105+
DRY_RUN = was_dry
106+
version = json.loads(stdout)['version']
107+
return Version(version=version)
108+
109+
96110
def UpdateDocs():
97111
try:
98112
print('Updating docs')
@@ -114,7 +128,6 @@ def _PromoteDartArchiveBuild(channel, source_channel, revision):
114128
release_namer = bot_utils.GCSNamer(channel, bot_utils.ReleaseType.RELEASE)
115129

116130
def promote(to_revision):
117-
118131
def safety_check_on_gs_path(gs_path, revision, channel):
119132
if not (revision != None and len(channel) > 0 and
120133
('%s' % revision) in gs_path and channel in gs_path):
@@ -182,7 +195,13 @@ def remove_gs_directory(gs_path):
182195
Gsutil(no_cache + ['cp', from_loc, to_loc])
183196

184197
promote(revision)
185-
promote('latest')
198+
# Promote to latest unless it's an older version.
199+
if GetLatestRelease(channel) <= Version(version=revision):
200+
promote('latest')
201+
# Promote beta to stable if stable becomes ahead of beta.
202+
if channel == 'stable' and \
203+
GetLatestRelease('beta') <= Version(version=revision):
204+
_PromoteDartArchiveBuild('beta', 'stable', revision)
186205

187206

188207
def Gsutil(cmd, throw_on_error=True):

tools/utils.py

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
import contextlib
1111
import datetime
12+
from functools import total_ordering
1213
import glob
1314
import imp
1415
import json
@@ -28,6 +29,8 @@
2829
except:
2930
pass
3031

32+
SEMANTIC_VERSION_PATTERN = r'^(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)(?:-(?P<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?P<buildmetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$'
33+
3134

3235
# To eliminate clashing with older archived builds on bleeding edge we add
3336
# a base number bigger the largest svn revision (this also gives us an easy
@@ -120,16 +123,88 @@ def GetMinidumpUtils(repo_path=DART_DIR):
120123
os.path.join(repo_path, 'tools', 'minidump.py'))
121124

122125

126+
@total_ordering
123127
class Version(object):
124128

125-
def __init__(self, channel, major, minor, patch, prerelease,
126-
prerelease_patch):
129+
def __init__(self,
130+
channel=None,
131+
major=None,
132+
minor=None,
133+
patch=None,
134+
prerelease=None,
135+
prerelease_patch=None,
136+
version=None):
127137
self.channel = channel
128138
self.major = major
129139
self.minor = minor
130140
self.patch = patch
131141
self.prerelease = prerelease
132142
self.prerelease_patch = prerelease_patch
143+
if version:
144+
self.set_version(version)
145+
146+
def set_version(self, version):
147+
match = re.match(SEMANTIC_VERSION_PATTERN, version)
148+
assert match, '%s must be a valid version' % version
149+
self.channel = 'stable'
150+
self.major = match['major']
151+
self.minor = match['minor']
152+
self.patch = match['patch']
153+
self.prerelease = '0'
154+
self.prerelease_patch = '0'
155+
if match['prerelease']:
156+
subversions = match['prerelease'].split('.')
157+
self.prerelease = subversions[0]
158+
self.prerelease_patch = subversions[1]
159+
self.channel = subversions[2]
160+
161+
def __str__(self):
162+
result = '%s.%s.%s' % (self.major, self.minor, self.patch)
163+
if self.channel != 'stable':
164+
result += '-%s.%s.%s' % (self.prerelease, self.prerelease_patch,
165+
self.channel)
166+
return result
167+
168+
def __eq__(self, other):
169+
return self.channel == other.channel and \
170+
self.major == other.major and \
171+
self.minor == other.minor and \
172+
self.patch == other.patch and \
173+
self.prerelease == other.prerelease and \
174+
self.prerelease_patch == other.prerelease_patch
175+
176+
def __lt__(self, other):
177+
if int(self.major) < int(other.major):
178+
return True
179+
if int(self.major) > int(other.major):
180+
return False
181+
if int(self.minor) < int(other.minor):
182+
return True
183+
if int(self.minor) > int(other.minor):
184+
return False
185+
if int(self.patch) < int(other.patch):
186+
return True
187+
if int(self.patch) > int(other.patch):
188+
return False
189+
# The stable channel is ahead of the other channels on the same triplet.
190+
if self.channel != 'stable' and other.channel == 'stable':
191+
return True
192+
if self.channel == 'stable' and other.channel != 'stable':
193+
return False
194+
# The be channel is ahead of the other channels on the same triplet.
195+
if self.channel != 'be' and other.channel == 'be':
196+
return True
197+
if self.channel == 'be' and other.channel != 'be':
198+
return False
199+
if int(self.prerelease_patch) < int(other.prerelease_patch):
200+
return True
201+
if int(self.prerelease_patch) > int(other.prerelease_patch):
202+
return False
203+
if int(self.prerelease) < int(other.prerelease):
204+
return True
205+
if int(self.prerelease) > int(other.prerelease):
206+
return False
207+
return False
133208

134209

135210
# Try to guess the host operating system.

0 commit comments

Comments
 (0)