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
infra / config / project.star [blame]
# 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.
"""Project-wide settings and common structs (e.g. platform names)."""
platform = struct(
ANDROID = "android",
CROS = "cros",
CROS_LTS = "cros-lts",
FUCHSIA = "fuchsia",
IOS = "ios",
LINUX = "linux",
MAC = "mac",
WINDOWS = "windows",
)
PLATFORMS = tuple([getattr(platform, a) for a in dir(platform)])
def _platform_settings(
*,
description, # buildifier: disable=unused-variable
gardener_rotation = None):
"""Declare settings for a platform on the project.
This provides the project-wide settings for a platform, which should be
modified based on what channels the milestone is being shipped to for each
platform.
Args:
* description - A string describing why the platform is enabled in the
project. This is not used by the starlark, but enables providing some
form of documentaion in the json file.
* gardener_rotation - The name of a gardener rotation in which to include
builders that are selected for the corresponding platform.
"""
return struct(
gardener_rotation = gardener_rotation,
)
def _project_settings(
*,
project,
project_title,
ref,
chrome_project,
is_main,
platforms = {}):
"""Declare settings for the project.
This provides the central location for what must be modified when
setting up the project for a new branch or when a branch changes category
(e.g. moves from a standard release channel to the long-term support
channel).
Args:
* project - The name of the LUCI project. No logic should depend on this
value, it should only be used where the name of a project is required.
* project_title - A string identifying the project in title contexts (e.g.
titles of consoles). No conditional logic should depend on this value,
it should only be used where the title of a project is required.
* ref - The git ref containing the code for this branch.
* chrome_project - The name of the corresponding chrome project. No logic
should depend on this value, it should only be used where the name of a
project is required.
* ref - The git ref containing the code for this branch. No logic should
depend on this value, it should only be used where a ref is required.
* is_main - Whether or not this is the project for the main ref.
* platforms - A mapping from a platform ID value to the settings for the
platform. The valid platform ID values are the members of the platform
struct. The settings for the platforms are dicts giving arguments for
the _platform_settings function.
Returns:
A struct with attributes set to the input parameters. Additionally, the
is_main attribute is set to True if branch_types is empty or False if
branch_types is not empty.
"""
if is_main:
if platforms:
fail("main project should not have any platforms set")
else:
if not platforms:
fail("Non-main projects must have at least one platform set")
invalid_platforms = [p for p in platforms if not p in PLATFORMS]
if invalid_platforms:
fail("The following platforms are invalid: {}".format(invalid_platforms))
platforms = {k: _platform_settings(**v) for k, v in platforms.items()}
return struct(
project = project,
project_title = project_title,
ref = ref,
chrome_project = chrome_project,
is_main = is_main,
platforms = platforms,
)
settings = _project_settings(**json.decode(io.read_file("./settings.json")))
def _generate_project_pyl(ctx):
ctx.output["project.pyl"] = "\n".join([
"# This is a non-LUCI generated file",
"# This is consumed by presubmit checks that need to validate the config",
repr(dict(
# On main, we want to ensure that we don't have source side specs
# defined for non-existent builders
# On branches, we don't want to re-generate the source side specs as
# that would increase branch day toil and complicate cherry-picks
validate_source_side_specs_have_builder = settings.is_main,
)),
"",
])
lucicfg.generator(_generate_project_pyl)
def _milestone_details(*, project, ref):
"""Define the details for an active milestone.
Args:
* project - The name of the LUCI project that is configured for the
milestone.
* ref - The ref in the git repository that contains the code for the
milestone.
"""
return struct(
project = project,
ref = ref,
)
# The milestone names and branch numbers of branches that we have builders
# running for (including milestone-specific projects)
# Branch numbers and milestones can be viewed in the chromium column at
# https://chromiumdash.appspot.com/releases
# The 3rd portion of the version number is the branch number for the associated
# milestone
ACTIVE_MILESTONES = {
m["name"]: _milestone_details(project = m["project"], ref = m["ref"])
for m in json.decode(io.read_file("./milestones.json")).values()
} if settings.is_main else {}