blob: 3bee962c33417f035e1b411ff47e51601a6ce1f0 [file] [log] [blame] [edit]
# Copyright 2022 The Pigweed 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
#
# https://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.
"""Recipe module to post comments on Gerrit CLs.
This module provides a `maybe_post` method that can be used to post a comment
on a Gerrit CL associated with the current build. The behavior of the comment
posting (e.g., whether to comment on success, failure, or always) can be
configured through an `Options` proto message. It also allows specifying
a list of allowed Gerrit hosts to prevent accidental commenting on unintended
repositories.
"""
from __future__ import annotations
from recipe_engine import recipe_api
from PB.recipe_modules.pigweed.gerrit_comment.options import (
CommentBehavior,
Options,
)
from RECIPE_MODULES.recipe_engine.defer import api as defer_api
class GerritCommentApi(recipe_api.RecipeApi):
def maybe_post(self, options: Options, result: defer_api.DeferredResult):
"""Maybe post a comment on a Gerrit CL.
Post a comment on the CL associated with this build (or not, depending
on the options).
Args:
options: Options.
result: DeferredResult object.
"""
if options.comment_behavior == CommentBehavior.COMMENT_UNSPECIFIED:
return
with self.m.step.nest('maybe post') as pres:
if (
options.comment_behavior == CommentBehavior.COMMENT_ON_FAILURE
and result.is_ok()
):
pres.step_summary_text = (
'No-op: Comments requested only on failures, '
'but the step passed.'
)
return
changes = self.m.buildbucket.build.input.gerrit_changes
if len(changes) == 0:
pres.step_summary_text = (
'No-op: no Gerrit change to comment on '
'(expected for CI builds).'
)
return
change = changes[-1]
if (
self.m.gerrit.normalize_host(change.host)
not in options.allowed_gerrit_hosts
):
pres.step_summary_text = (
'No-op: '
"the change is on a host that's not explicitly allowlisted."
)
return
# If we made it here, we should post a comment on the CL.
pres.step_summary_text = 'Posting CL comment'
if result.is_ok():
status = 'OK'
else:
try:
result.result()
assert False, "shouldn't get here" # pragma: no cover
except Exception as exc:
status = str(exc)
self.m.gerrit.set_review(
'post CL comment',
change.change,
host=change.host,
message='{} completed with status {}: http://go/bbid/{}'.format(
self.m.buildbucket.builder_name,
status,
self.m.buildbucket.build.id,
),
notify='OWNER',
)