1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
infra / config / scripts / branch.py [blame]
#!/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()