| # Copyright 2019 The LUCI Authors. |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| """Defines luci.console_view(...) rule.""" |
| |
| load("@stdlib//internal/io.star", "io") |
| load("@stdlib//internal/lucicfg.star", "lucicfg") |
| load("@stdlib//internal/validate.star", "validate") |
| load("@stdlib//internal/luci/common.star", "keys", "kinds", "view") |
| load("@stdlib//internal/luci/proto.star", "milo_pb") |
| load("@stdlib//internal/luci/rules/console_view_entry.star", "console_view_entry") |
| |
| # TODO(vadimsh): Document how builders should be configured to be eligible for |
| # inclusion into a console. |
| |
| def _console_view( |
| ctx, # @unused |
| *, |
| name = None, |
| title = None, |
| repo = None, |
| refs = None, |
| exclude_ref = None, |
| include_experimental_builds = None, |
| header = None, |
| favicon = None, |
| default_commit_limit = None, |
| default_expand = None, |
| entries = None): |
| r"""A Milo UI view that displays a table-like console. |
| |
| In this view columns are builders and rows are git commits on which builders |
| are triggered. |
| |
| A console is associated with a single git repository it uses as a source of |
| commits to display as rows. The watched ref set is defined via `refs` and |
| optional `exclude_ref` fields. If `refs` are empty, the console defaults to |
| watching `refs/heads/main`. |
| |
| `exclude_ref` is useful when watching for commits that landed specifically |
| on a branch. For example, the config below allows to track commits from all |
| release branches, but ignore the commits from the main branch, from which |
| these release branches are branched off: |
| |
| luci.console_view( |
| ... |
| refs = ['refs/branch-heads/\d+\.\d+'], |
| exclude_ref = 'refs/heads/main', |
| ... |
| ) |
| |
| For best results, ensure commits on each watched ref have **committer** |
| timestamps monotonically non-decreasing. Gerrit will take care of this if |
| you require each commit to go through Gerrit by prohibiting "git push" on |
| these refs. |
| |
| #### Adding builders |
| |
| Builders that belong to the console can be specified either right here: |
| |
| luci.console_view( |
| name = 'CI builders', |
| ... |
| entries = [ |
| luci.console_view_entry( |
| builder = 'Windows Builder', |
| short_name = 'win', |
| category = 'ci', |
| ), |
| # Can also pass a dict, this is equivalent to passing |
| # luci.console_view_entry(**dict). |
| { |
| 'builder': 'Linux Builder', |
| 'short_name': 'lnx', |
| 'category': 'ci', |
| }, |
| ... |
| ], |
| ) |
| |
| Or separately one by one via luci.console_view_entry(...) declarations: |
| |
| luci.console_view(name = 'CI builders') |
| luci.console_view_entry( |
| builder = 'Windows Builder', |
| console_view = 'CI builders', |
| short_name = 'win', |
| category = 'ci', |
| ) |
| |
| Note that consoles support builders defined in other projects. See |
| [Referring to builders in other projects](#external-builders) for more |
| details. |
| |
| #### Console headers |
| |
| Consoles can have headers which are collections of links, oncall rotation |
| information, and console summaries that are displayed at the top of a |
| console, below the tree status information. Links and oncall information is |
| always laid out to the left, while console groups are laid out to the right. |
| Each oncall and links group take up a row. |
| |
| Header definitions are based on `Header` message in Milo's [project.proto]. |
| There are two way to supply this message via `header` field: |
| |
| * Pass an appropriately structured dict. Useful for defining small headers |
| inline: |
| |
| luci.console_view( |
| ... |
| header = { |
| 'links': [ |
| {'name': '...', 'links': [...]}, |
| ... |
| ], |
| }, |
| ... |
| ) |
| |
| * Pass a string. It is treated as a path to a file with serialized |
| `Header` message. Depending on its extension, it is loaded ether as |
| JSONPB-encoded message (`*.json` and `*.jsonpb` paths), or as |
| TextPB-encoded message (everything else): |
| |
| luci.console_view( |
| ... |
| header = '//consoles/main_header.textpb', |
| ... |
| ) |
| |
| [project.proto]: https://chromium.googlesource.com/infra/luci/luci-go/+/refs/heads/main/milo/api/config/project.proto |
| |
| Args: |
| ctx: the implicit rule context, see lucicfg.rule(...). |
| name: a name of this console, will show up in URLs. Note that names of |
| luci.console_view(...) and luci.list_view(...) are in the same namespace |
| i.e. defining a console view with the same name as some list view (and |
| vice versa) causes an error. Required. |
| title: a title of this console, will show up in UI. Defaults to `name`. |
| repo: URL of a git repository whose commits are displayed as rows in the |
| console. Must start with `https://`. Required. |
| refs: a list of regular expressions that define the set of refs to pull |
| commits from when displaying the console, e.g. `refs/heads/[^/]+` or |
| `refs/branch-heads/\d+\.\d+`. The regular expression should have a |
| literal prefix with at least two slashes present, e.g. |
| `refs/release-\d+/foobar` is *not allowed*, because the literal prefix |
| `refs/release-` contains only one slash. The regexp should not start |
| with `^` or end with `$` as they will be added automatically. If empty, |
| defaults to `['refs/heads/main']`. |
| exclude_ref: a single ref, commits from which are ignored even when they |
| are reachable from refs specified via `refs` and `refs_regexps`. Note |
| that force pushes to this ref are not supported. Milo uses caching |
| assuming set of commits reachable from this ref may only grow, never |
| lose some commits. |
| header: either a string with a path to the file with the header definition |
| (see io.read_file(...) for the acceptable path format), or a dict with |
| the header definition. |
| include_experimental_builds: if True, this console will not filter out |
| builds marked as Experimental. By default consoles only show production |
| builds. |
| favicon: optional https URL to the favicon for this console, must be |
| hosted on `storage.googleapis.com`. Defaults to `favicon` in |
| luci.milo(...). |
| default_commit_limit: if set, will change the default number of commits to |
| display on a single page. |
| default_expand: if set, will default the console page to expanded view. |
| entries: a list of luci.console_view_entry(...) entities specifying |
| builders to show on the console. |
| """ |
| refs = validate.list("refs", refs) or ["refs/heads/main"] |
| for r in refs: |
| validate.string("refs", r) |
| |
| if header != None: |
| if type(header) == "dict": |
| header = milo_pb.Header(**header) |
| elif type(header) == "string": |
| header = io.read_proto(milo_pb.Header, header) |
| else: |
| fail('bad "header": got %s, want string or dict' % type(header)) |
| |
| return view.add_view( |
| key = keys.console_view(name), |
| entry_kind = kinds.CONSOLE_VIEW_ENTRY, |
| entry_ctor = console_view_entry, |
| entries = entries, |
| props = { |
| "name": name, |
| "title": validate.string("title", title, default = name, required = False), |
| "repo": validate.repo_url("repo", repo), |
| "refs": refs, |
| "exclude_ref": validate.string("exclude_ref", exclude_ref, required = False), |
| "header": header, |
| "include_experimental_builds": validate.bool("include_experimental_builds", include_experimental_builds, required = False), |
| "favicon": validate.string("favicon", favicon, regexp = r"https://storage\.googleapis\.com/.+", required = False), |
| "default_commit_limit": validate.int("default_commit_limit", default_commit_limit, min = 0, max = 1000, default = 0, required = False), |
| "default_expand": validate.bool("default_expand", default_expand, required = False), |
| }, |
| ) |
| |
| console_view = lucicfg.rule(impl = _console_view) |