runbot/runbot_merge/utils.py
Xavier Morel 23e1b93465 [FIX] runbot_merge: a few issues with updated staging check
1cea247e6c tried to improve staging
checks to avoid staging PRs in the wrong state, however it had two
issues:

PR state
--------

The process would reset the PR's state to open, but unless the head
was being resync'd it wouldn't re-apply the statuses on the state,
leading to a PR with all-valid statuses, but a missing CI.

Message
-------

The message check didn't compose the PR message the same way PR
creation / update did (it did not trim the title and description
individually, only after concatenation), resulting in a
not-actually-existing divergence getting signaled in the case where
the PR title ends or the description starts with whitespace.

Expand relevant test, add a utility function to compose a PR message
and use it everywhere for coherence.

Also update the logging and reporting to show a diff of all the
updated items (hidden behind a `details` element).
2023-02-14 13:45:28 +01:00

38 lines
1.1 KiB
Python

# -*- coding: utf-8 -*-
import itertools
import time
def shorten(text_ish, length):
""" If necessary, cuts-off the text or bytes input and appends ellipsis to
signal the cutoff, such that the result is below the provided length
(according to whatever "len" means on the text-ish so bytes or codepoints
or code units).
"""
if len(text_ish or ()) <= length:
return text_ish
cont = '...'
if isinstance(text_ish, bytes):
cont = cont.encode('ascii') # whatever
# add enough room for the ellipsis
return text_ish[:length-3] + cont
BACKOFF_DELAYS = (0.1, 0.2, 0.4, 0.8, 1.6)
def backoff(func=None, *, delays=BACKOFF_DELAYS, exc=Exception):
if func is None:
return lambda func: backoff(func, delays=delays, exc=exc)
for delay in itertools.chain(delays, [None]):
try:
return func()
except exc:
if delay is None:
raise
time.sleep(delay)
def make_message(pr_dict):
title = pr_dict['title'].strip()
body = (pr_dict.get('body') or '').strip()
return f'{title}\n\n{body}' if body else title