| #!/usr/bin/env vpython3 |
| # Copyright 2020 The Chromium Authors |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| """Script for updating the project settings for a chromium branch. |
| |
| To initialize a new chromium branch, run the following from the root of |
| the repo (where MM is the milestone number and BBBB is the branch |
| number): |
| ``` |
| infra/config/scripts/branch.py initialize --milestone MM --branch BBBB |
| infra/config/main.star |
| infra/config/dev.star |
| ``` |
| |
| Usage: |
| branch.py initialize --milestone XX --branch YYYY |
| """ |
| |
| import argparse |
| import json |
| import os |
| |
| from typing import Any, Optional |
| |
| INFRA_CONFIG_DIR = os.path.abspath(os.path.join(__file__, '..', '..')) |
| |
| def parse_args(args=None, *, parser_type=None): |
| parser_type = parser_type or argparse.ArgumentParser |
| parser = parser_type( |
| description='Update the project settings for a chromium branch') |
| parser.set_defaults(func=None) |
| parser.add_argument('--settings-json', |
| help='Path to the settings.json file', |
| default=os.path.join(INFRA_CONFIG_DIR, 'settings.json')) |
| |
| subparsers = parser.add_subparsers() |
| |
| init_parser = subparsers.add_parser( |
| 'initialize', help='Initialize the settings for a branch') |
| init_parser.set_defaults(func=initialize_cmd) |
| init_parser.add_argument( |
| '--milestone', |
| required=True, |
| help=('The milestone identifier ' |
| '(e.g. the milestone number for standard release channel)')) |
| init_parser.add_argument( |
| '--branch', |
| required=True, |
| help='The branch name, must correspond to a ref in refs/branch-heads') |
| # Executing "lucicfg validate" fails if the project name is not the name of a |
| # project known to luci-config. This flag allows for an initial branch config |
| # to be created that can be checked with "lucicfg validate". |
| init_parser.add_argument( |
| '--test-config', |
| action='store_true', |
| help=argparse.SUPPRESS, |
| ) |
| |
| enable_platform_parser = subparsers.add_parser( |
| 'enable-platform', help='Enable builders for an additional platform') |
| enable_platform_parser.set_defaults(func=enable_platform_cmd) |
| enable_platform_parser.add_argument( |
| 'platform', help='The platform to enable builders for') |
| enable_platform_parser.add_argument( |
| '--description', |
| required=True, |
| help='A description of why the platform is enabled') |
| enable_platform_parser.add_argument( |
| '--gardener-rotation', |
| help=('A gardener rotation that builders' |
| ' associated with the platform should be added to')) |
| |
| args = parser.parse_args(args) |
| if args.func is None: |
| parser.error('no sub-command specified') |
| return args |
| |
| |
| def initial_settings( |
| *, |
| milestone: str, |
| branch: str, |
| chromium_project: str, |
| chrome_project: str, |
| ) -> dict[str, Any]: |
| settings = dict( |
| project=chromium_project, |
| project_title=f'Chromium M{milestone}', |
| ref=f'refs/branch-heads/{branch}', |
| chrome_project=chrome_project, |
| is_main=False, |
| platforms={ |
| p: { |
| "description": "beta/stable", |
| "gardener_rotation": "chrome_browser_release" |
| } |
| for p in ( |
| "android", |
| "cros", |
| "fuchsia", |
| "ios", |
| "linux", |
| "mac", |
| "windows", |
| ) |
| }, |
| ) |
| |
| return json.dumps(settings, indent=4) + '\n' |
| |
| def initialize_cmd(args): |
| if args.test_config: |
| chromium_project = 'chromium' |
| chrome_project = 'chrome' |
| else: |
| chromium_project = f'chromium-m{args.milestone}' |
| chrome_project = f'chrome-m{args.milestone}' |
| settings = initial_settings( |
| milestone=args.milestone, |
| branch=args.branch, |
| chromium_project=chromium_project, |
| chrome_project=chrome_project, |
| ) |
| |
| with open(args.settings_json, 'w') as f: |
| f.write(settings) |
| |
| |
| def enable_platform( |
| settings_json: str, |
| platform: str, |
| description: str, |
| gardener_rotation: Optional[str], |
| ) -> str: |
| settings = json.loads(settings_json) |
| settings['is_main'] = False |
| platforms = settings.pop('platforms', {}) |
| platform_settings = {'description': description} |
| if gardener_rotation is not None: |
| platform_settings['gardener_rotation'] = gardener_rotation |
| platforms[platform] = platform_settings |
| settings['platforms'] = dict(sorted(platforms.items())) |
| return json.dumps(settings, indent=4) + '\n' |
| |
| |
| def enable_platform_cmd(args): |
| with open(args.settings_json) as f: |
| settings = f.read() |
| |
| settings = enable_platform( |
| settings, |
| args.platform, |
| args.description, |
| args.gardener_rotation, |
| ) |
| |
| with open(args.settings_json, 'w') as f: |
| f.write(settings) |
| |
| |
| def main(): |
| args = parse_args() |
| args.func(args) |
| |
| if __name__ == '__main__': |
| main() |