Skip to content
Snippets Groups Projects

No more blocked pipelines

Open Daniel Stone requested to merge fooishbar/marge-bot:no-more-blocked-pipelines into main
4 unresolved threads

There are three main changes in here, but all to minimise Marge's downtime.

The first is to explicitly use --no-ff when we do a rebase. This may be a Mesa/freedesktop-specific wart, but there's a certain sense to it. We set our pipelines to run automatically when triggered by Marge, and manual when triggered by users. Generally, this works well: Marge rebases and pushes, which creates a new pipeline, and she waits for it to complete. However, if a user pushes a branch which fast-forwards from the target branch, and they've already got the Part-of trailer in it, the rebase will be a no-op. This change unconditionally adds --no-ff, on the grounds that if you've asked to rebase, then you should rebase.

The second just treats the 'new' canceling status the same as canceled, so we bail out as soon as someone presses the button, instead of waiting for it all to resolve on the server side.

The third is an early timeout for when we don't end up with a pipeline. If the CI workflow is misconfigured, we may never create a pipeline, or it may end up being manual. This inserts all the known not-yet-started statuses into a wait-for-pipeline wrapper and gives it five minutes to begin running before it gives up and moves on. This avoids spinning for an hour waiting for a pipeline which will never complete.

Merge request reports

Loading
Loading

Activity

Filter activity
  • Approvals
  • Assignees & reviewers
  • Comments (from bots)
  • Comments (from users)
  • Commits & branches
  • Edits
  • Labels
  • Lock status
  • Mentions
  • Merge request status
  • Tracking
150 150
151 151 Throws a `GitError` if the rebase fails. Will also try to --abort it.
152 152 """
153 fuse_args = [ '--no-ff' ]
  • I feel like this one ought to be behind a CLI flag, some users (me included) would prefer to avoid unnecessarily rerunning any pipelines.

    Edited by Ben Brown
  • Yeah, so I started doing this and I don't have a great answer. Passing bare git args to the generic strategy feels very wrong. Passing MergeJobOptions to the strategy doesn't work because it creates circular imports. Creating a new MergeGitOptions feels like it's solving a problem which doesn't exist. And creating a new rebase_ff_only strategy feels like it's ripe for a combinatorial explosion. What do you think is best here?

  • merge() already accepts *merge_args, so there's already a precedent for passing raw git args, though I agree that passing them to the generic strategy feels wrong, especially given --no-ff is likely to be incompatible with the gitlab_rebase strategy.

    I'm not opposed to a rebase_no_ff or force_rebase strategy (or whichever name feels most appropriate), though admittedly we already have a couple of flags that influence how branches are updated: --use-merge-strategy, --rebase-remotely; deprecating these in favour of a more generic option is potentially a good idea.

  • Please register or sign in to reply
  • Ben Brown
    Ben Brown @benjamb started a thread on commit fad17778
  • 247 248 raise CannotMerge(f"Someone canceled the CI. {pipeline_msg}")
    248 249
    249 if ci_status not in ("created", "pending", "running"):
    250 if waiting_for_queue > -1 and ci_status in (
    251 "created", "waiting_for_resource", "preparing", "waiting_for_callback", "manual", None
    252 ):
    253 waiting_for_queue += 1
    254 # give it five minutes to become runnable in extreme cases
    255 if waiting_for_queue > 30:
    256 raise CannotMerge(
    257 f"Pipeline took longer than 5 minutes to become runnable: {ci_status}. {pipeline_msg}"
    258 )
    259 log.warning("Waiting for pipeline to be runnable")
    260 elif ci_status in ('pending', 'running'):
    261 waiting_for_queue = -1
    262 else:
  • 246 247 if ci_status in ("canceling", "canceled"):
    247 248 raise CannotMerge(f"Someone canceled the CI. {pipeline_msg}")
    248 249
    249 if ci_status not in ("created", "pending", "running"):
    250 if waiting_for_queue > -1 and ci_status in (
    251 "created", "waiting_for_resource", "preparing", "waiting_for_callback", "manual", None
    252 ):
    253 waiting_for_queue += 1
    254 # give it five minutes to become runnable in extreme cases
    255 if waiting_for_queue > 30:
    • Can we make this more defensive by using a timestamp for waiting_for_queue? This would mark the start of the wait_for_ci_to_pass and allow us to set a constant for the timeout duration. For example:

      waiting_for_queue_timestamp = datetime.now(timezone.utc)
      
      ...
      
      if (datetime.now(timezone.utc) - waiting_for_queue_timestamp).total_seconds() >= QUEUE_WAIT_TIMEOUT_MIN * 60:

      This approach would ensure that we accurately track the elapsed time and handle cases where the spinning block might need to time out more precisely and avoid surprise if we change waiting_time_in_secs.

    • Please register or sign in to reply
  • @fooishbar

    1. cancelling commit is R-b!
    2. Wait 5 minutes for pipeline to become runnable LGTM, thou Gallo comment worth considering

    If you could separate the first two commits, I believe it's safe to merge them ASAP.

    1. I would keep the --no-ff change here as standalone commit, so it can get extra attention, so we don't break someones workflow.
  • Ben Brown mentioned in merge request !485 (merged)

    mentioned in merge request !485 (merged)

  • @fooishbar Would enabling the --guarantee-final-pipeline option not satisfy your need for a marge-bot triggered pipeline when the rebase is effectively a no-op?

    Edited by Ben Brown
  • Please register or sign in to reply
    Loading