blob: f4f7b468165ff568830847bf5f0868287fafba9c [file] [log] [blame]
# Copyright 2022 The Chromium 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 re
from recipe_engine.post_process import (
MustRun,)
from PB.recipe_modules.dart.build.build import Build
from PB.recipes.dart.release.sdk import BuildOptions
DEPS = [
'dart/build',
'depot_tools/bot_update',
'depot_tools/gclient',
'depot_tools/gsutil',
'depot_tools/osx_sdk',
'recipe_engine/archive',
'recipe_engine/context',
'recipe_engine/cipd',
'recipe_engine/buildbucket',
'recipe_engine/bcid_reporter',
'recipe_engine/file',
'recipe_engine/path',
'recipe_engine/platform',
'recipe_engine/properties',
'recipe_engine/runtime',
'recipe_engine/step',
]
PYTHON_VERSION_COMPATIBILITY = "PY3"
PROPERTIES = BuildOptions
def _rename(string, renames):
return renames[string] if string in renames else string
def _platform_to_os(platform):
return _rename(platform, {
'mac': 'macos',
'win': 'windows',
})
def _platform_to_cipd_os(platform):
return _rename(platform, {
'win': 'windows',
})
def _arch_to_cipd_arch(arch):
return _rename(arch, {
'ia32': '386',
'x64': 'amd64',
'arm': 'arm6l',
'arm64': 'arm64',
})
def _is_cross(api, arch):
# TODO(b/234599649): Better logic for detecting cross-compilation
if api.platform.name == "mac":
return False
return arch != "ia32" and arch != "x64"
def _build_root(api):
if api.platform.name == "mac":
return "xcodebuild"
return "out"
def _build_conf(api, arch):
mode = "Release"
cross = 'X' if _is_cross(api, arch) else ''
return "%s%s%s" % (mode, cross, arch.upper())
class Version(object):
def __init__(self, channel, major, minor, patch, prerelease,
prerelease_patch):
self.channel = channel
self.major = major
self.minor = minor
self.patch = patch
self.prerelease = prerelease
self.prerelease_patch = prerelease_patch
def parse_version(content):
def match_against(pattern, file_content):
match = re.search(pattern, file_content, flags=re.MULTILINE)
return match.group(1) if match else None
channel = match_against('^CHANNEL ([A-Za-z0-9]+)$', content)
major = match_against('^MAJOR (\d+)$', content)
minor = match_against('^MINOR (\d+)$', content)
patch = match_against('^PATCH (\d+)$', content)
prerelease = match_against('^PRERELEASE (\d+)$', content)
prerelease_patch = match_against('^PRERELEASE_PATCH (\d+)$', content)
return Version(channel, major, minor, patch, prerelease, prerelease_patch)
def format_version(version, git_revision=None, no_git_hash=False):
suffix = ''
if version.channel == 'be':
suffix = '-edge' if no_git_hash else '-edge.{}'.format(git_revision)
elif version.channel in ('beta', 'dev'):
suffix = '-{}.{}.{}'.format(version.prerelease, version.prerelease_patch,
version.channel)
else:
assert version.channel == 'stable'
return '{}.{}.{}{}'.format(version.major, version.minor, version.patch,
suffix)
def _report_stage(api, properties, stage):
if not properties.disable_bcid:
api.bcid_reporter.report_stage(stage)
def RunSteps(api, properties):
assert properties.archs, 'the recipe requires archs to be specified'
_report_stage(api, properties, "start")
with api.osx_sdk('mac'):
# Fetch the Dart SDK source code while Snoopy keeps track of dependencies.
_report_stage(api, properties, "fetch")
api.gclient.set_config('dart')
api.bot_update.ensure_checkout(timeout=25 * 60) # 25 minutes
api.gclient.runhooks()
sdk_dir = api.path['checkout']
with api.context(cwd=sdk_dir):
_report_stage(api, properties, "compile")
# Build the Dart SDK.
builder_name = api.buildbucket.builder_name
is_try_job = builder_name.endswith('-try')
args = ['--sanitizer=none', '--mode=release', '--check-clean']
args.append('--arch=' + ','.join(properties.archs))
if properties.args:
args.extend(properties.args)
args.append('create_sdk')
api.build.build(args=args)
# TODO(b/234599649): Build and upload API docs on Linux.
# Upload the build Dart SDKs to cloud storage.
_report_stage(api, properties, "upload")
commit = api.buildbucket.gitiles_commit.id
version_path = sdk_dir.join('tools').join('VERSION')
version_contents = api.file.read_text('read tools/VERSION', version_path)
version = parse_version(version_contents)
version_string = format_version(version, git_revision=commit)
for arch in properties.archs:
os = _platform_to_os(api.platform.name)
out_path = sdk_dir.join(_build_root(api)).join(_build_conf(api, arch))
dart_sdk_path = out_path.join('dart-sdk')
zip_name = "dartsdk-%s-%s-release.zip" % (os, arch)
zip_path = out_path.join(zip_name)
(api.archive.package(out_path).with_dir(dart_sdk_path).archive(
'zip %s' % zip_name, zip_path))
sha256 = api.file.file_hash(zip_path)
sha256_name = zip_name + ".sha256sum"
sha256_path = out_path.join(sha256_name)
api.file.write_text('write %s' % sha256_name, sha256_path,
"%s *%s\n" % (sha256, zip_name))
if not api.runtime.is_experimental and not is_try_job:
# Upload the SDK to cloud storage.
bucket = "dart-archive"
topdir = "channels/%s/raw" % version.channel
subdirs = ["latest", "hash/%s" % commit]
if version.channel != 'be':
subdirs.append(version_string)
for subdir in subdirs:
object_path = "%s/%s/sdk/%s" % (topdir, subdir, zip_name)
api.gsutil.upload(
zip_path,
bucket,
object_path,
name='upload %s (%s)' % (zip_name, subdir))
# Report the cloud storage object to snoopy and get the provenance.
if not properties.disable_bcid:
api.bcid_reporter.report_gcs(sha256,
"gs://%s/%s" % (bucket, object_path))
api.gsutil.upload(
sha256_path,
bucket,
object_path + ".sha256sum",
name='upload %s (%s)' % (sha256_name, subdir))
dart_exe = 'dart.exe' if os == 'windows' else 'dart'
unstripped_path = out_path.join(dart_exe)
upstripped_object_path = "%s/%s/unstripped/%s/%s/%s" % (
topdir, subdir, os, arch, dart_exe)
api.gsutil.upload(
unstripped_path,
bucket,
upstripped_object_path,
name='upload unstripped %s (%s)' % (dart_exe, subdir))
# Upload the SDK to cipd.
if version.channel != "be":
cipd_os = _platform_to_cipd_os(api.platform.name)
cipd_arch = _arch_to_cipd_arch(arch)
cipd_platform = cipd_os + '-' + cipd_arch
package_name = 'flutter/dart-sdk/%s' % cipd_platform
pkg = api.cipd.PackageDefinition(
package_name, dart_sdk_path, 'copy', preserve_writable=True)
pkg.add_dir(dart_sdk_path)
api.cipd.create_from_pkg(
pkg,
tags={
'git_revision': commit,
'version': version_string
},
refs=[version.channel])
# TODO(b/236109907): Update VERSION (on Linux).
_report_stage(api, properties, "upload-complete")
def GenTests(api):
yield api.test(
'dart-sdk-linux-bcid-main',
api.platform.name('linux'),
api.buildbucket.ci_build(
project='dart-internal',
builder='dart-sdk-linux-bcid-main',
git_repo='https://dart.googlesource.com/sdk',
git_ref="refs/heads/main",
revision='abfdc3d50f6cf66165767da8df4f681a68467178'),
api.properties(BuildOptions(archs=['ia32', 'x64', 'arm', 'arm64'])),
api.properties(**{'$dart/build': Build(disable_goma=True)}),
api.step_data(
'read tools/VERSION',
api.file.read_text('''
CHANNEL be
MAJOR 2
MINOR 18
PATCH 0
PRERELEASE 0
PRERELEASE_PATCH 0
''')),
api.post_process(MustRun,
'gsutil upload dartsdk-linux-x64-release.zip (latest)'),
api.post_process(MustRun, 'report_stage (5)'),
)
yield api.test(
'dart-sdk-linux-riscv64-bcid-dev',
api.platform.name('linux'),
api.buildbucket.ci_build(
project='dart-internal',
builder='dart-sdk-linux-bcid-dev',
git_repo='https://dart.googlesource.com/sdk',
git_ref="refs/heads/dev",
revision='da07db8582242af643370cc866b5eed357367e83'),
api.step_data(
'read tools/VERSION',
api.file.read_text('''
CHANNEL dev
MAJOR 2
MINOR 17
PATCH 0
PRERELEASE 158
PRERELEASE_PATCH 0
''')),
api.properties(BuildOptions(archs=['riscv64'], args=["--no-clang"])),
api.properties(**{'$dart/build': Build(disable_goma=True)}),
api.post_process(
MustRun,
'gsutil upload dartsdk-linux-riscv64-release.zip (2.17.0-158.0.dev)'),
api.post_process(MustRun, 'report_stage (5)'),
)
yield api.test(
'dart-sdk-mac-bcid-beta',
api.platform.name('mac'),
api.platform.mac_release('10.15.7'),
api.buildbucket.ci_build(
project='dart-internal',
builder='dart-sdk-mac-bcid-beta',
git_repo='https://dart.googlesource.com/sdk',
git_ref="refs/heads/beta",
revision='a6465a49920e649938df378684d75df2aca56ccf'),
api.step_data(
'read tools/VERSION',
api.file.read_text('''
CHANNEL beta
MAJOR 2
MINOR 18
PATCH 0
PRERELEASE 44
PRERELEASE_PATCH 1
''')),
api.properties(**{'$dart/build': Build(disable_goma=True)}),
api.properties(BuildOptions(archs=['x64'])),
api.post_process(
MustRun,
'gsutil upload dartsdk-macos-x64-release.zip (2.18.0-44.1.beta)'),
api.post_process(MustRun, 'report_stage (5)'),
)
yield api.test(
'dart-sdk-mac-arm64-bcid-stable',
api.platform.name('mac'),
api.platform.mac_release('11.6.2'),
api.buildbucket.ci_build(
project='dart-internal',
builder='dart-sdk-mac-arm64-bcid-stable',
git_repo='https://dart.googlesource.com/sdk',
git_ref="refs/heads/stable",
revision='18df0aae67183931b1b6d5d12cc04d89f7137919'),
api.properties(**{'$dart/build': Build(disable_goma=True)}),
api.properties(BuildOptions(archs=['arm64'])),
api.step_data(
'read tools/VERSION',
api.file.read_text('''
CHANNEL stable
MAJOR 2
MINOR 17
PATCH 3
PRERELEASE 0
PRERELEASE_PATCH 0
''')),
api.post_process(
MustRun, 'gsutil upload dartsdk-macos-arm64-release.zip (2.17.3)'),
api.post_process(MustRun, 'report_stage (5)'),
)
yield api.test(
'dart-sdk-win-bcid-stable',
api.platform.name('win'),
api.buildbucket.ci_build(
project='dart-internal',
builder='dart-sdk-win-bcid-main',
git_repo='https://dart.googlesource.com/sdk',
git_ref="refs/heads/stable",
revision='18df0aae67183931b1b6d5d12cc04d89f7137919'),
api.properties(**{'$dart/build': Build(disable_goma=True)}),
api.properties(BuildOptions(archs=['ia32', 'x64', 'arm64'])),
api.step_data(
'read tools/VERSION',
api.file.read_text('''
CHANNEL stable
MAJOR 2
MINOR 17
PATCH 3
PRERELEASE 0
PRERELEASE_PATCH 0
''')),
api.post_process(
MustRun, 'gsutil upload dartsdk-windows-x64-release.zip (2.17.3)'),
api.post_process(MustRun, 'report_stage (5)'),
)