Commit Graph

11 Commits

Author SHA1 Message Date
Martin Trigaux (mat)
ccfff33d56 [IMP] runbot_merge: latest patches first 2025-02-25 15:34:34 +01:00
Xavier Morel
e6057afde7 [FIX] runbot_merge: handle missing patch commits
Commits can take some time to propagate through the network (I guess),
or human error can lead to the wrong commit being set.

Either way, because the entire thing was done using a single fetch in
`check=True` the cron job would fail entirely if any of the patch
commits was yet unavailable.

Update the updater to:

- fallback on individual fetches
- remove the patch from the set of applicable patch if we (still)
  can't find its commit

I'd have hoped `fetch` could retrieve whatever it found, but
apparently the server just crashes out when it doesn't find the commit
we ask for, and `fetch` doesn't update anything.

No linked issue because I apparently forgot to jot it down (and only
remembered about this issue with the #1063 patching issue) but this
was reported by mat last week (2025-02-21) when they were wondering
why one of their patches was taking a while:

- At 0832 patch was created by automated script.
- At 0947, an attempt to apply was made, the commit was not found.
- At 1126, a second attempt was made but an other patch had been
  created whose commit was not found, failing both.
- At 1255, there was a concurrency error ("cannot lock ref" on the
  target branch).
- Finally at 1427 the patch was applied.

All in all it took 6 hours to apply the patch, which is 3-4 staging
cycles.
2025-02-25 14:38:15 +01:00
Xavier Morel
5d08b79550 [IMP] runbot_merge: replace show --pretty=%H by rev-list -1
It's shorter, it's simpler (kinda), and it's 70% faster (although
that's unlikely to be any sort of bottleneck given applying patches
involves multiple network roundtrips).
2025-02-25 11:53:39 +01:00
Xavier Morel
157fec3492 [FIX] runbot_merge: reject patches yielding empty commits
Verify that the tree is different before and after applying the patch,
otherwise if there's a mistake made (e.g. a script does not check that
they have content and request a patch applying an existing commit
which is how odoo/enterprise#612a9cf3cadba64e4b18d535ca0ac7e3f4429a08
occurred) we end up with a completely empty commit and a duplicated
commit message.

Fixes #1063

Note: using `rev-parse` to retrieve the commit's tree would be 50%
faster, but we're talking 3.2 versus 2.4ms and it requires string
formatting instead of nice clean arguments so it's a bit meh.
2025-02-25 11:51:22 +01:00
Xavier Morel
1097c5f19e [ADD] runbot_merge: support for file creation in patch
Had been left out of the original impl, but turns out it might be
useful e.g. when a new lang gets added to the i18n export.

Fixes #1042
2025-01-29 13:29:53 +01:00
Xavier Morel
f900eb68b6 [FIX] runbot_merge: my pager lied to me
Hopefully this is the last fix to the patcher. From the start of the
implementation I relied on the idea that `git show` was adding a line
composed of a single space (and a newline) before and after the patch
message, as that is what I observed in my terminal, and it's
consistent with RFC 3676 signatures (two dashes, a space, and a
newline).

Turns out that single space, while present in my terminal indeed, was
completely made up by `less(1)`. `git show` itself doesn't generate
that, neither does it appear when using most pagers, or even when
piping the output of `less` into something (a file, an other pager,
...). It's pretty much just something `less(1)` sends to a terminal
during interactive sessions to fuck with you.

Fixes #1037
2025-01-15 08:51:28 +01:00
Xavier Morel
38c2bc97f3 [IMP] runbot_merge: inspectability of patch parsing
Show patch metadata on the patch screen, so it's easier to understand
what the parser sees in case of issues.

Behaviour is not *entirely* consisten, `file_ids` is correctly set but
it looks like during the initial `web_read` it gets stripped out in at
least some cases and the files list is empty even though files have
been found in the patch. nm.

Fixes #987
2024-12-02 16:32:53 +01:00
Xavier Morel
7f7589c50e [FIX] runbot_merge: normalisation of patches before parsing
- Apparently if a user is on windows the ACE editor can swap out their
  line end from unix to windows. The patch parsers were predicated
  upon all patches being in unix mode (because git, and diff).

  Fixup both parsers to convert windows-style line end to unix before
  trying to parse the patch data. Also add a few fallbacks to limit
  the odds of an unhelpful `StopIteration` (though that might hide
  errors more than reveal them...)
- Make sure we support `format-patch --no-signature`, just requires
  using the correct partition direction: I assume I used `rpartition`
  as a form of micro-optimisation *but*

  - If the separator is not found the "patch body" ends up in the
    third parameter rather than the first, which makes the fallback
    difficult.
  - There doesn't seem to be anything preventing *multiple* signature
    separators in a message, and logically the first one should hold
    and the rest is all part of the signature.

  As a result, for both reasons we need to look *forwards* for the
  signature separator, not backwards. Hence `str.partition`.

Fixes #992
2024-12-02 16:32:53 +01:00
Xavier Morel
c4bdb75d9c [FIX] runbot_merge: EmailMessage.get_content misbehaves
`get_content` round-trips the text part through `ascii` with
`error=replace`, so if the input is not ascii it screws up
tremendously, which leads to either failing to apply patches (the more
likely situation) or corrupting the patches.

`get_payload`, if called without `decode`, pretty much just returns
the payload unless it needs a decoding pass (e.g. because it contains
raw surrogates, but that should not be an issue for us). So this is
really what we want.

While at it, increase `patch`'s verbosity in case it can give us more
info.
2024-11-19 11:22:25 +01:00
Xavier Morel
5441ba12ae [FIX] runbot_merge: format_patch if --no-prefix
Turns out you can configure format-patch with `--no-prefix` and some
people (*cough cough* mat) have that in their standard setup, so the
assumption of needing to strip 1 level of prefix does not necessarily
hold.

Also fix a few more issues:

- some people (*cough cough* still mat) also use `-n` by default,
  which adds the series sequence (`n/m`) even for a single patch,
  handle that correctly
- logging patch application errors is pretty useful when patching
  fails and I'm trying to get the information via logs, do that
- especially when I decide to add error messages to tracking *but
  forgot to show the chatter by default*, fix that as well

The commit-based patcher worked first try, and patch-based would have
worked too if not for those meddling kids. In the future it might be a
good idea to reify the stripping level (`-p`) on the patch object
though, and maybe provide a computed preview of the list of files to
patch, so issues are easier for the operator to diagnose.
2024-11-18 12:37:44 +01:00
Xavier Morel
6a1b77b92c [ADD] runbot_merge: support for unstaged patches
Unstaged changes can be useful or necessary for some tasks
e.g. absolute emergency (where even faking the state of a staging is
not really desirable, if that's even possible anymore), or changes
which are so broad they're difficult to stage (e.g. t10s updates).

Add a new object which serves as a queue for patch to direct-apply,
with support for either text patches (udiff style out of git show or
format-patch) or commits to cherry-pick. In the former case, the part
of the show / format-patch before the diff itself is used for the
commit metadata (author, committer, dates, message) whereas for the
commit version the commit itself is reused as-is.

Applied patches are simply disabled for traceability.

Fixes #926
2024-10-03 12:06:00 +02:00