go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/lucicfg/starlark/stdlib/internal/luci/rules/console_view.star (about)

     1  # Copyright 2019 The LUCI Authors.
     2  #
     3  # Licensed under the Apache License, Version 2.0 (the "License");
     4  # you may not use this file except in compliance with the License.
     5  # You may obtain a copy of the License at
     6  #
     7  #      http://www.apache.org/licenses/LICENSE-2.0
     8  #
     9  # Unless required by applicable law or agreed to in writing, software
    10  # distributed under the License is distributed on an "AS IS" BASIS,
    11  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  # See the License for the specific language governing permissions and
    13  # limitations under the License.
    14  
    15  """Defines luci.console_view(...) rule."""
    16  
    17  load("@stdlib//internal/io.star", "io")
    18  load("@stdlib//internal/lucicfg.star", "lucicfg")
    19  load("@stdlib//internal/validate.star", "validate")
    20  load("@stdlib//internal/luci/common.star", "keys", "kinds", "view")
    21  load("@stdlib//internal/luci/proto.star", "milo_pb")
    22  load("@stdlib//internal/luci/rules/console_view_entry.star", "console_view_entry")
    23  
    24  # TODO(vadimsh): Document how builders should be configured to be eligible for
    25  # inclusion into a console.
    26  
    27  def _console_view(
    28          ctx,  # @unused
    29          *,
    30          name = None,
    31          title = None,
    32          repo = None,
    33          refs = None,
    34          exclude_ref = None,
    35          include_experimental_builds = None,
    36          header = None,
    37          favicon = None,
    38          default_commit_limit = None,
    39          default_expand = None,
    40          entries = None):
    41      r"""A Milo UI view that displays a table-like console.
    42  
    43      In this view columns are builders and rows are git commits on which builders
    44      are triggered.
    45  
    46      A console is associated with a single git repository it uses as a source of
    47      commits to display as rows. The watched ref set is defined via `refs` and
    48      optional `exclude_ref` fields. If `refs` are empty, the console defaults to
    49      watching `refs/heads/main`.
    50  
    51      `exclude_ref` is useful when watching for commits that landed specifically
    52      on a branch. For example, the config below allows to track commits from all
    53      release branches, but ignore the commits from the main branch, from which
    54      these release branches are branched off:
    55  
    56          luci.console_view(
    57              ...
    58              refs = ['refs/branch-heads/\d+\.\d+'],
    59              exclude_ref = 'refs/heads/main',
    60              ...
    61          )
    62  
    63      For best results, ensure commits on each watched ref have **committer**
    64      timestamps monotonically non-decreasing. Gerrit will take care of this if
    65      you require each commit to go through Gerrit by prohibiting "git push" on
    66      these refs.
    67  
    68      #### Adding builders
    69  
    70      Builders that belong to the console can be specified either right here:
    71  
    72          luci.console_view(
    73              name = 'CI builders',
    74              ...
    75              entries = [
    76                  luci.console_view_entry(
    77                      builder = 'Windows Builder',
    78                      short_name = 'win',
    79                      category = 'ci',
    80                  ),
    81                  # Can also pass a dict, this is equivalent to passing
    82                  # luci.console_view_entry(**dict).
    83                  {
    84                      'builder': 'Linux Builder',
    85                      'short_name': 'lnx',
    86                      'category': 'ci',
    87                  },
    88                  ...
    89              ],
    90          )
    91  
    92      Or separately one by one via luci.console_view_entry(...) declarations:
    93  
    94          luci.console_view(name = 'CI builders')
    95          luci.console_view_entry(
    96              builder = 'Windows Builder',
    97              console_view = 'CI builders',
    98              short_name = 'win',
    99              category = 'ci',
   100          )
   101  
   102      Note that consoles support builders defined in other projects. See
   103      [Referring to builders in other projects](#external-builders) for more
   104      details.
   105  
   106      #### Console headers
   107  
   108      Consoles can have headers which are collections of links, oncall rotation
   109      information, and console summaries that are displayed at the top of a
   110      console, below the tree status information. Links and oncall information is
   111      always laid out to the left, while console groups are laid out to the right.
   112      Each oncall and links group take up a row.
   113  
   114      Header definitions are based on `Header` message in Milo's [project.proto].
   115      There are two way to supply this message via `header` field:
   116  
   117        * Pass an appropriately structured dict. Useful for defining small headers
   118          inline:
   119  
   120              luci.console_view(
   121                  ...
   122                  header = {
   123                      'links': [
   124                          {'name': '...', 'links': [...]},
   125                          ...
   126                      ],
   127                  },
   128                  ...
   129              )
   130  
   131        * Pass a string. It is treated as a path to a file with serialized
   132          `Header` message. Depending on its extension, it is loaded ether as
   133          JSONPB-encoded message (`*.json` and `*.jsonpb` paths), or as
   134          TextPB-encoded message (everything else):
   135  
   136              luci.console_view(
   137                  ...
   138                  header = '//consoles/main_header.textpb',
   139                  ...
   140              )
   141  
   142      [project.proto]: https://chromium.googlesource.com/infra/luci/luci-go/+/refs/heads/main/milo/api/config/project.proto
   143  
   144      Args:
   145        ctx: the implicit rule context, see lucicfg.rule(...).
   146        name: a name of this console, will show up in URLs. Note that names of
   147          luci.console_view(...) and luci.list_view(...) are in the same namespace
   148          i.e. defining a console view with the same name as some list view (and
   149          vice versa) causes an error. Required.
   150        title: a title of this console, will show up in UI. Defaults to `name`.
   151        repo: URL of a git repository whose commits are displayed as rows in the
   152          console. Must start with `https://`. Required.
   153        refs: a list of regular expressions that define the set of refs to pull
   154          commits from when displaying the console, e.g. `refs/heads/[^/]+` or
   155          `refs/branch-heads/\d+\.\d+`. The regular expression should have a
   156          literal prefix with at least two slashes present, e.g.
   157          `refs/release-\d+/foobar` is *not allowed*, because the literal prefix
   158          `refs/release-` contains only one slash. The regexp should not start
   159          with `^` or end with `$` as they will be added automatically. If empty,
   160          defaults to `['refs/heads/main']`.
   161        exclude_ref: a single ref, commits from which are ignored even when they
   162          are reachable from refs specified via `refs` and `refs_regexps`. Note
   163          that force pushes to this ref are not supported. Milo uses caching
   164          assuming set of commits reachable from this ref may only grow, never
   165          lose some commits.
   166        header: either a string with a path to the file with the header definition
   167          (see io.read_file(...) for the acceptable path format), or a dict with
   168          the header definition.
   169        include_experimental_builds: if True, this console will not filter out
   170          builds marked as Experimental. By default consoles only show production
   171          builds.
   172        favicon: optional https URL to the favicon for this console, must be
   173          hosted on `storage.googleapis.com`. Defaults to `favicon` in
   174          luci.milo(...).
   175        default_commit_limit: if set, will change the default number of commits to
   176          display on a single page.
   177        default_expand: if set, will default the console page to expanded view.
   178        entries: a list of luci.console_view_entry(...) entities specifying
   179          builders to show on the console.
   180      """
   181      refs = validate.list("refs", refs) or ["refs/heads/main"]
   182      for r in refs:
   183          validate.string("refs", r)
   184  
   185      if header != None:
   186          if type(header) == "dict":
   187              header = milo_pb.Header(**header)
   188          elif type(header) == "string":
   189              header = io.read_proto(milo_pb.Header, header)
   190          else:
   191              fail('bad "header": got %s, want string or dict' % type(header))
   192  
   193      return view.add_view(
   194          key = keys.console_view(name),
   195          entry_kind = kinds.CONSOLE_VIEW_ENTRY,
   196          entry_ctor = console_view_entry,
   197          entries = entries,
   198          props = {
   199              "name": name,
   200              "title": validate.string("title", title, default = name, required = False),
   201              "repo": validate.repo_url("repo", repo),
   202              "refs": refs,
   203              "exclude_ref": validate.string("exclude_ref", exclude_ref, required = False),
   204              "header": header,
   205              "include_experimental_builds": validate.bool("include_experimental_builds", include_experimental_builds, required = False),
   206              "favicon": validate.string("favicon", favicon, regexp = r"https://storage\.googleapis\.com/.+", required = False),
   207              "default_commit_limit": validate.int("default_commit_limit", default_commit_limit, min = 0, max = 1000, default = 0, required = False),
   208              "default_expand": validate.bool("default_expand", default_expand, required = False),
   209          },
   210      )
   211  
   212  console_view = lucicfg.rule(impl = _console_view)