| # 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)'), |
| ) |