No more blocked pipelines
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
Activity
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 BrownYeah, 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 newMergeGitOptions
feels like it's solving a problem which doesn't exist. And creating a newrebase_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 thegitlab_rebase
strategy.I'm not opposed to a
rebase_no_ff
orforce_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.
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: - Comment on lines +250 to +262
Looks like this will handle #385. Could you add the relevant metadata to ensure merging this will close that issue?
@fooishbar Looks like the linters need to be appeased:
/builds/fooishbar/marge-bot/marge/git.py:153:22: E201 whitespace after '[' /builds/fooishbar/marge-bot/marge/git.py:153:32: E202 whitespace before ']'
tests/git_repo_mock.py:167: [W0613(unused-argument), GitModel.rebase] Unused argument 'fuse_args'
Yeah, that's trivially fixable with !449 (merged).
- Resolved by Ben Brown
@fooishbar I suspect you don't actively monitor activity on gitlab.com. I hope this ping will help.
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 thewait_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
.
- cancelling commit is R-b!
-
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.
- I would keep the
--no-ff
change here as standalone commit, so it can get extra attention, so we don't break someones workflow.
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