cirruslabs / cirrus-ci-docs

Documentation for Cirrus CI 📚
https://cirrus-ci.org
MIT License
352 stars 109 forks source link

Configure concurrent builds in case of a PR / configure build events #1236

Open julien-carsique-sonarsource opened 1 year ago

julien-carsique-sonarsource commented 1 year ago

Description

When a PR is created or updated, two concurrent builds are triggered: one for the branch and one for the PR. We would like to choose whether to run the two builds or only one, typically only the PR.

The same observation may apply to all the build events related to the same changeset, like tags.

Usually, for a given changeset, only one build is needed. While Git server handles only one event (commit update), vendors like GitHub are sending many build events related to the same changeset: push, tag, PR, release, etc. (see events-that-trigger-workflows). Since Cirrus reacts to multiple events matching the same changeset, and each event holds different information that can be needed by the build, it would be very useful to be able to choose the event to be used for the unique build.

Context

The issue is that despite the only_if condition, the skip of building the branch is not a blank operation. This requires repeated glue code to avoid concurrent builds and conflicting results. That is confusing to the developers. The status is reported to GitHub. The UI is full of duplicated builds. It eventually happened that depending on the build order, the PR build was autocanceled.

GitHub solved this, by requiring configuring the triggering events. Other CI solutions have an option for choosing the branch build strategy. It is very rare that someone wants two simultaneous builds for a PR, isn't it?

To solve this partially, we have introduced a default top-level only_if condition that lists the branch patterns allowed for building, if not a PR:

$CIRRUS_USER_COLLABORATOR == 'true' && $CIRRUS_TAG == "" && (
    $CIRRUS_PR != "" ||
    $CIRRUS_BRANCH == $CIRRUS_DEFAULT_BRANCH ||
    $CIRRUS_BRANCH =~ "branch-.*" ||
    $CIRRUS_BUILD_SOURCE == 'api'
)

Expressed build conditions:

Note that this is not exactly the same behavior as "all branches being built, but with only one build in case of a PR". The implemented above behavior may deserve dedicated explicit options to configure the build strategy, like "prefer build of pull-request over branch" or, as explained on top, configuring the build events to react on.

Anything Else

Also, Cirrus is not able to trigger builds on events such as merge/close of PRs. This would be needed for cleanup or close tasks.