blob: 0025ebc90daddeb76748c786b83a8d4f79627ae3 [file] [log] [blame]
# Copyright 2022 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.
"""Recipe for flagging large-scale changes (LSCs) that may impact downstream projects."""
import datetime
from recipe_engine import post_process
from PB.recipes.fuchsia.lsc_suggester import InputProperties
PYTHON_VERSION_COMPATIBILITY = "PY3"
DEPS = [
"fuchsia/gerrit",
"fuchsia/status_check",
"recipe_engine/json",
"recipe_engine/properties",
"recipe_engine/url",
]
PROPERTIES = InputProperties
FX_LSC_MESSAGE = """
Please run `fx lsc presubmit` on API+1 changes. See http://go/run-fx-lsc-presubmit.
Note that the LSC tryjobs are non-blocking. You will need to check the results manually.
"""
FX_LSC_TAG = "autogenerated:suggest-fx-lsc"
def RunSteps(api, props):
assert props.gerrit_host, "props.gerrit_host must be specified"
for change in get_eligible_changes_with_messages(api, props.gerrit_host):
# Only comment on the change if it has not been commented on before
# regardless of patchset. change["messages"] contains messages from all
# patchsets.
assert "messages" in change, "change %s must have a `messages` key" % change
has_fx_lsc_tag = any(
message.get("tag") == FX_LSC_TAG for message in change["messages"]
)
if not has_fx_lsc_tag:
step = api.gerrit.set_review(
"add fx lsc message to %d" % change["_number"],
api.url.unquote(change["id"]),
message=FX_LSC_MESSAGE,
tag=FX_LSC_TAG,
notify="OWNER",
host=props.gerrit_host,
)
def get_eligible_changes_with_messages(api, gerrit_host):
"""Finds changes to suggest running fx lsc.
Eligible changes have the following properties:
* unsubmitted
* recently modified/created
* need the API-Review label or have API+1 label
* in directory:sdk
Args:
gerrit_host (str): Gerrit Host to query.
Returns:
changes ([]json ChangeInfo): list of changes that are suggested to run
fx lsc. See
https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#change-info.
"""
# We restrict the results to recently modified/created changes. This is to
# avoid messaging abandoned changes so that we do not spam users.
#
# The following change fxr/644416 had 80 messages and the result size was
# ~52KB -> 100KB. We expect a max of O(10) eligible changes, where result
# size will be 1MB.
raw_query = "is:open -is:wip (label:Api-Review=need OR label:Api-Review+1) -age:1h directory:sdk"
# Query for unsubmitted changes that are api+1. Get the messages so that we
# can determine if the change has been fx lsc commented before. The query
# will get all the messages from all patchsets from a change.
changes = api.gerrit.change_query(
name="get eligible changes",
query_string=raw_query,
query_params=["MESSAGES"],
host=gerrit_host,
max_attempts=3,
timeout=datetime.timedelta(seconds=120),
).json.output
# API returns None if there is no search results instead of [].
return changes or []
def GenTests(api):
# For this test, check that there are no fx lsc comments added.
yield api.status_check.test("empty") + api.properties(
gerrit_host="fuchsia-review.googlesource.com"
) + api.step_data("get eligible changes", api.json.output([]))
# For this test, check that only change 1000 and 1001 got a fx lsc comment
# added.
yield api.status_check.test("default") + api.properties(
gerrit_host="fuchsia-review.googlesource.com"
) + api.step_data(
"get eligible changes",
api.json.output(
[
{
"id": "myProject~main~1000",
"project": "myProject",
"status": "NEW",
"_number": 1000,
"messages": [],
},
{
"id": "myProject~main~1001",
"project": "myProject",
"status": "NEW",
"_number": 1001,
"messages": [
{"message": ""},
{"message": "nothing"},
],
},
{
"id": "myProject~main~1002",
"project": "myProject",
"status": "NEW",
"_number": 1002,
"messages": [
{"message": ""},
{"message": FX_LSC_MESSAGE, "tag": FX_LSC_TAG},
{"message": "nothing"},
],
},
{
"id": "myProject~main~1003",
"project": "myProject",
"status": "NEW",
"_number": 1003,
"messages": [
{
"message": "Different from current FX_LSC_MESSAGE",
"tag": FX_LSC_TAG,
},
],
},
]
),
) + api.post_process(
post_process.MustRun, "add fx lsc message to 1000", "add fx lsc message to 1001"
)