blob: 673b064d142a88145a33828ee5a65f58eb560cd9 [file] [log] [blame]
# 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.
load('@stdlib//internal/graph.star', 'graph')
load('@stdlib//internal/validate.star', 'validate')
load('@stdlib//internal/luci/common.star', 'keys', 'triggerer')
def gitiles_poller(
name=None,
bucket=None,
repo=None,
refs=None,
refs_regexps=None,
schedule=None,
triggers=None,
):
"""Defines a gitiles poller which can trigger builders on git commits.
It periodically examines the state of watched refs in the git repository. On
each iteration it triggers builders if either:
* A watched ref's tip has changed since the last iteration (e.g. a new
commit landed on a ref). Each new detected commit results in a separate
triggering request, so if for example 10 new commits landed on a ref since
the last poll, 10 new triggering requests will be submitted to the
builders triggered by this poller. How they are converted to actual builds
depends on `triggering_policy` of a builder. For example, some builders
may want to have one build per commit, others don't care and just want to
test the latest commit. See core.builder(...) and scheduler.policy(...)
for more details.
*** note
**Caveat**: When a large number of commits are pushed on the ref between
iterations of the poller, only the most recent 50 commits will result in
triggering requests. Everything older is silently ignored. This is a
safeguard against mistaken or deliberate but unusual git push actions,
which typically don't have intent of triggering a build for each such
commit.
***
* A ref belonging to the watched set has just been created. This produces
a single triggering request.
The watched ref set is defined via `refs` and `refs_regexps` fields. One is
just a simple enumeration of refs, and another allows to use regular
expressions to define what refs belong to the watched set. Both fields can
be used at the same time. If neither is set, the gitiles_poller defaults to
watching `refs/heads/master`.
Args:
name: name of the poller, to refer to it from other rules. Required.
bucket: name of the bucket the poller belongs to. Required.
repo: URL of a git repository to poll, starting with `https://`. Required.
refs: a list of fully qualified refs to watch, e.g. `refs/heads/master` or
`refs/tags/v1.2.3`.
refs_regexps: a list of regular expressions that define the watched set of
refs, 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.
schedule: string with a schedule that describes when to run one iteration
of the poller. See [Defining cron schedules](#schedules_doc) for the
expected format of this field. Note that it is rare to use custom
schedules for pollers. By default, the poller will run each 30 sec.
triggers: names of builders to trigger whenever the poller detects a new git
commit on any ref in the watched ref set.
"""
name = validate.string('name', name)
bucket = validate.string('bucket', bucket)
refs = validate.list('refs', refs)
for r in refs:
validate.string('refs', r)
refs_regexps = validate.list('refs_regexps', refs_regexps)
for r in refs_regexps:
validate.string('refs_regexps', r)
if not refs and not refs_regexps:
refs = ['refs/heads/master']
# Node that carries the full definition of the poller.
poller_key = keys.gitiles_poller(bucket, name)
graph.add_node(poller_key, props = {
'name': name,
'bucket': bucket,
'repo': validate.string('repo', repo, regexp=r'https://.+'),
'refs': refs,
'refs_regexps': refs_regexps,
'schedule': validate.string('schedule', schedule, required=False),
})
graph.add_edge(keys.bucket(bucket), poller_key)
# Setup nodes that indicate this poller can be referenced in 'triggered_by'
# relations (either via its bucket-scoped name or via its global name).
triggerer_key = triggerer.add(poller_key)
# Link to builders triggered by this builder.
for t in validate.list('triggers', triggers):
graph.add_edge(
parent = triggerer_key,
child = keys.builder_ref(validate.string('triggers', t)),
title = 'triggers',
)