| # Copyright 2019 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import functools |
| |
| from PB.go.chromium.org.luci.cv.api.config.v2 import config as config_pb2 |
| from recipe_engine import recipe_api |
| |
| |
| class CommitQueueApi(recipe_api.RecipeApi): |
| """Module for polling parsing commit-queue.cfg.""" |
| |
| @functools.lru_cache(maxsize=None) |
| def _load(self, project, config_name=None): |
| return self.m.luci_config.commit_queue(project=project, config_name=config_name) |
| |
| def all_tryjobs( |
| self, |
| project=None, |
| include_experimental=False, |
| include_unrestricted=True, |
| include_restricted=False, |
| include_all_modes=False, |
| include_path_filtered=False, |
| config_name=None, |
| included_repos=frozenset(), |
| ): |
| cfg = self._load(project, config_name=config_name) |
| |
| builders = set() |
| if cfg: |
| for group in cfg.config_groups: |
| triggering_repos = set() |
| for g in group.gerrit: |
| gitiles_host = g.url.replace("-review", "") |
| for p in g.projects: |
| triggering_repos.add(f"{gitiles_host}/{p.name}") |
| |
| # URLs in commit-queue.cfg and `included_repos` should all use |
| # "https://" prefixes, so they should be comparable. |
| if included_repos and not triggering_repos.intersection(included_repos): |
| continue |
| |
| for builder in group.verifiers.tryjob.builders: |
| if ( |
| not include_unrestricted |
| and builder.result_visibility |
| != config_pb2.COMMENT_LEVEL_RESTRICTED |
| ): |
| continue |
| if ( |
| not include_restricted |
| and builder.result_visibility |
| == config_pb2.COMMENT_LEVEL_RESTRICTED |
| ): |
| continue |
| |
| if not include_experimental and ( |
| builder.experiment_percentage or builder.includable_only |
| ): |
| continue |
| if ( |
| not include_all_modes |
| # mode_allowlist includes "FULL_RUN" by default. |
| and "FULL_RUN" not in (builder.mode_allowlist or ("FULL_RUN",)) |
| ): |
| continue |
| # If the first location filter is not an exclude rule, then |
| # the builder only runs on an allowlisted (likely very |
| # small) set of file paths and should probably not be |
| # included by default. |
| if ( |
| not include_path_filtered |
| and builder.location_filters |
| and not builder.location_filters[0].exclude |
| ): |
| continue |
| |
| builders.add(builder.name) |
| |
| builders = sorted(builders) |
| self.m.step.empty("all tryjobs").presentation.logs["tryjobs"] = builders |
| return builders |