Commit Graph

630 Commits

Author SHA1 Message Date
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
7d5c3dcb73 [IMP] mergebot: staging endpoints
- use lingo `staged` and `merged` for clarity (instead of `heads` and
  `commits`)
- convert from json-rpc to regular HTTP to make easier to call
- add the staged and merged heads when returning staging data
- return more complete objects (rather than a list of ids) when
  matching stagings based on commits / heads

Fixes #1018
2025-01-14 15:05:03 +01:00
Xavier Morel
89411f968f [IMP] runbot_merge: return proper http responses from webhooks
The old controller system required `type='json'` which only did
JSON-RPC and prevented returning proper responses.

As of 17.0 this is not the case anymore, `type='http'` controllers can
get `content-type: application/json` requests just fine and return
whatever they want. So change that:

- `type='json'`.
- Return `Response` objects with nice status codes (and text
  mimetypes, as otherwise werkzeug defaults to html).
- Update ping to bypass normal flow as otherwise it requires
  authentication and event sources which is annoying (it might be a
  good idea to have both in order to check for configuration, however
  it's not possible to just send a ping via the webhook UI on github
  so not sure how useful that would be).
- Add some typing and improve response messages while at it.

Note: some "internal" errors (e.g. ignoring event actions) are
reported as successes because as far as I can tell webhooks only
support success (2xy) / failure (4xy, 5xy) and an event that's ignored
is not really *failed* per se.

Some things are reported as failures even though they are on the edge
because that can be useful to see what's happening e.g. comment too
large or unable to lock rows.

Fixes #1019
2024-12-18 14:07:22 +01:00
Xavier Morel
0fd254b5fe [IMP] runbot_merge: auto-trigger cron for issue closing
Probably should create a mixin for this: when a model is used as a
task queue for a cron, the cron should automatically be triggered on
creation. Requiring an explicit trigger after a creation is error
prone and increase the risks that some of the triggers will be
forgotten/missed.
2024-12-16 09:11:19 +01:00
Xavier Morel
a0e237fbfc [IMP] runbot_merge: debug prints in the ngrok tunnel script 2024-12-16 09:11:19 +01:00
Xavier Morel
2e107111f0 [ADD] runbot_merge: basic support for false positive detection
Adds a very limited ability to try and look for false positive /
non-determinstic staging errors. It tries to err on the side of
limiting false false positives, so it's likely to miss many.

Currently has no automation / reporting, just sets a flag on the
stagings which are strongly believed to have failed due to false
positives.

While at it, add link between a "root" staging and its splits. It's
necessary to clear the "false positive" flag, and surfacing it in the
UI could be useful one day.

Fixes #660
2024-12-09 16:02:28 +01:00
Xavier Morel
d6e1516f31 [IMP] runbot_merge: support arbitrary tunnel scripts
Rather than add individual tunnel methods to conftest, just allows
specifying a tunnel script and have that do whatever.

Protocol is uncomplicated: workers run the `$tunnel` with an arbitrary
port, script should create a tunnel to `localhost:$port`, print the
ingress of the tunnel to `STDOUT` with a terminating newline then
close `STDOUT`, and wait for `SIGINT` or `SIGTERM`, doing  whatever
cleanup they need when receiving either of those.

`ngrok` and `localtunnel` adapter scripts are provided out of the box,
though the ngrok one doesn't *really* work when using xdist without a
pre-spawned ngrok worker. Then again using xdist against github actual
is suicidal (because concurrency limits + rate limits) so likely
irrelevant.

Fixes #729
2024-12-09 16:02:28 +01:00
Xavier Morel
461db6a3e7 [ADD] runbot_merge: closing linked issues on merge
Requires parsing the commit messages as github plain doesn't collate
the info from there, but also the descriptions: apparently github only
adds those to the references if the PR targets the default
branch. That's not a limitation we want.

Meaning at the end of the day, the only thing we're calling graphql
for is explicit manual linking, which can't be tested without
extending the github API (and then would only be testable on DC), and
which I'm not sure anyone bothers with...

Limitations
-----------

- Links are retrieved on staging (so if one is added later it won't be
  taken in account).
- Only repository-local links are handled, not cross-repository.

Fixes #777
2024-12-09 16:02:28 +01:00
Xavier Morel
62fbda52a8 [IMP] runbot_merge: a PR can't be reopened if its batch is merged
In that case, ignore the reopen, close the PR, and tell the idiot to
fuck off.

Also the case where a PR is reopened while its batch is staged was
already handled, but probably not tested: it was implicit in
forcefully updating the HEAD of the PR, which triggers an unstage
since c8a06601a7.

Now that scenario is tested, which should lower the odds of breaking
it in the future.

Fixes #965
2024-12-09 16:02:28 +01:00
Xavier Morel
31f3edeea6 [IMP] runbot_merge: minor simplification of test_by_branch
Dedup' the application of statuses. Although it is somewhat slower do
keep applying them one by one to ensure all are required.
2024-12-09 16:02:28 +01:00
Xavier Morel
509c152156 [IMP] *: modernise tests via to_pr
The `to_pr` helper was added a *while* ago to replace the pretty
verbose process of looking a PR with the right number in the right
repository after a `make_pr`. However while I did some ad-hoc
replacement of existing `search` calls as I had to work with existing
tests I never did a full search and replace to try and excise searches
from the test suite.

This is now done. I've undoubtedly missed a few, but a hundred-odd
lines of codes have been simplified.
2024-12-02 16:32:53 +01:00
Xavier Morel
83e588d7fe [FIX] runbot_merge: dropdowns for bs5
BS5 namespaced the data-attributes it uses to trigger JS
behaviours. So for dropdowns `@data-toggle` doesn't do anything
anymore, one has to use `@data-bs-toggle`. Missed that while testing
the migrations.

Also seems like `@aria-expanded` was misapplied when I added the
dropdowns:

> When a menu is displayed, the button object that toggles the
> visibility of that menu has aria-expanded="true" set. When the menu
> is hidden, aria-expanded can be omitted. If specified when the menu
> is hidden, it should be set as aria-expanded="false".

Since the dropdowns are hidden by default, the button should be
`@aria-expanded="false"`.
2024-12-02 16:32:53 +01:00
Xavier Morel
876ec92059 [IMP] runbot_merge: add quick link projects on the main dashboard
As the number of projects is starting to grow pretty large, provide
quick links and stable jump targets for projects on the home page /
main dashboard.

Fixes #991
2024-12-02 16:32:53 +01:00
Xavier Morel
679d556c90 [FIX] project creation: handling of mergebot info
- don't *fail* in `_compute_identity`, it causes issues when the token
  is valid but doesn't have `user:email` access as the request is
  aborted and saving doesn't work
- make `github_name` and `github_email` required rather than ad-hoc
  requiring them in `_compute_identity` (which doesn't work correctly)
- force copy of `github_name` and `github_email`, with o2ms being
  !copy this means duplicating projects now works out of the box (or
  should...)

Currently errors in `_compute_identity` are reported via logging which
is not great as it's not UI visible, should probably get moved to
chatter eventually but that's not currently enabled on projects.

Fixes #990
2024-12-02 16:32:53 +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
749382a1e7 [REM] runbot_merge: freeze wizard auto-refresh
Turns out to not work well in 17.0, and after consideration moc hasn't
really used the auto-update feature (or the required-prs gate in
general to be honest), usually he knows what PRs he's waiting for and
only validates once he's confirmed every which way.

So it's probably not worth fixing the thing. According to jpp, this
should probably use something based on bus subscriptions to update
just the field (though tbf the `root.update` call doesn't really seem
to be "deep" anymore, so in reality rather than update the *form*'s
record I should probably have tried reloading the required_pr_ids
records to fetch the new color).

Closes #997
2024-12-02 16:32:53 +01:00
Xavier Morel
8c70e44ae9 [IMP] runbot)merge: 17.0 migration
`runbot_merge.patch` is a mail.thread model added since the last
migration attempt, see 36786d51c8
2024-11-21 15:47:09 +01:00
Xavier Morel
bf20127da9 [FIX] runbot_merge: tracked value ordering
Apparently in odoo 17.0 tracking values are always ordered by field
name.
2024-11-20 12:40:15 +01:00
Xavier Morel
31c13ca9a0 [FIX] runbot_merge: attrs not supported in 17.0
Basically the next part of aa1df22657
which requires replacing @attrs by the corresponding attribute &
python predicates: new attrs were added to 15.0 since.
2024-11-20 12:38:57 +01:00
Xavier Morel
1f83007675 [FIX] runbot_merge: global acl removed on subtype access
Because of tracking, `test_patch_acl` needs access to message subtypes
during patch creation. If the user *only* has
`runbot_merge.group_patcher` or `runbot_merge.group_admin` they don't
have any of the "core" user groups (public, portal, internal) and thus
don't have access to mail subtypes.

Fix that by having the runbot_merge groups imply being an internal
user.
2024-11-20 12:35:19 +01:00
Xavier Morel
3d33d0406e [FIX] runbot_merge: tracking author is already a res.partner
Not sure why it didn't break tests in 16...
2024-11-20 12:33:00 +01:00
Xavier Morel
0a17454838 [MERGE] runbot_merge, forwardport: latest updates
Got a bunch of updates since the initial attempt to migrate the
mergebot before the odoo days.
2024-11-20 08:05:41 +01:00
Xavier Morel
667aa69f5b [FIX] runbot_merge, forwardport: create_single is deprecated
Update a bunch of `create` overrides to work in batch. Also fix a few
`super()` calls unnecessarily in legacy style.
2024-11-19 15:09:01 +01:00
Xavier Morel
c7523c0429 [MERGE] runbot_merge, forwardport: latest updates
Got a bunch of updates since the initial attempt to migrate the
mergebot before the odoo days.
2024-11-19 12:18:59 +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
4563fc5fc0 [FIX] runbot_merge: dashboard image is branch created via SQL
If a branch is created via SQL directly, one might forget to set its
`write_date`, leading the computation of the `last_modified` to be
*really* unhappy as it's asked to compare a bunch of datetime objects
to `False` in order to compute the `max`.

Substitute missing `write_date` with `datetime.min` so they are
extremely unlikely to influence the computation until and unless the
branch gets updated.
2024-11-18 14:52:15 +01:00
Xavier Morel
63a0ee90b2 [ADD] runbot_merge: views from custom
Add a few views / view extensions set as custom on the production
mergebot which I never remembered to implement in the actual source.
2024-11-18 14:45:21 +01:00
Xavier Morel
fbfb96be53 [IMP] runbot_merge: ping commenter when fetching PR due to comment
If a comment causes an unknown PR to be fetched, it's a bit odd to
ping the author (and possibly reviewer) anyway as they're not super
concerned (and technically we could be ignoring the purported /
attempted reviewer).

So if a fetch job was created because of a comment, remember the
comment author and ping *them* instead of using the default ping
policy.

Fixes #981
2024-11-18 13:52:27 +01:00
Xavier Morel
c974f51036 [IMP] runbot_merge: trigger staging if re-enabled for branch
If staging gets re-enabled on a branch (or the branch itself gets
re-enabled), immediately run a staging cron as there may already be
PRs waiting, and no trigger enqueued: cron triggers have no payload,
they just get removed when the cron runs which means if a bunch of PRs
become ready for branch B with staging disabled, the cron is going to
run, it's going to stage nothing on that branch (because staging is
disabled) then it's going to delete all the triggers.

Fixes #979
2024-11-18 13:09:23 +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
a12e593fba [FIX] runbot_merge: backport wizard
- fix incorrect view specs (the action id comes first)
- add a wizard form and hook it into the PR, completely forgot to do
  that
- usability improvements: filter branches to be in the same project as
  the PR being backported, and older than the current PR's branch

The latter is a somewhat incomplete condition: ideally we'd want to
only allow selecting branches preceding the target of the *source* of
the PR being backported, that way we don't risk errors when
backporting forward-ports (the condition should be checked in the
final action but still).

Also we're only filtering by sequence, so we're missing the name part
of the ordering, hence if multiple branches have the same sequence we
may not allow selecting some of the preceding branches.
2024-11-18 09:48:48 +01:00
Xavier Morel
5b94dcce35 [FIX] runbot_merge: reset markdown renderer
pymarkdown's footnotes plugin *saves footnotes across invocations by
default*. Even if I understand the documented use case it seems wild
that it's not opt-in...

Anyway disable that resetting all internal state. Thanks rfr for the
inital report that things were looking odd.
2024-10-29 13:13:59 +01:00
Xavier Morel
11f2231e82 [FIX] runbot_merge: missing model description 2024-10-22 15:08:00 +02:00
Xavier Morel
e7716f8b77 [FIX] *: fw=no reflection in the PR dashboard
Like limit, fw=no should restrict the table length, in this case to
just the current branch (as we're not forward porting at all).

Before this, `no` would not be applied as a limit visually, the table
would still go up to the main branch which is very confusing.

Fixes #962
2024-10-22 15:05:48 +02:00
Xavier Morel
2fea318830 [IMP] runbot_merge: hide concurrent update errors
As far as I can tell they are properly handled:

- In `handle_status` we let the http layer retry the query, which
  pretty much always succeeds.
- In `Commit.notify`, we rollback the application of the current
  commit, meaning it'll be processed by the next run of the cron,
  which also seems to succeed every time (that is going through the
  log I pretty much never notice the same commit being serialization
  failure'd twice in a row).

  Which we can trigger for faster action, this last item is not
  entirely necessary as statuses should generally come in fast and
  especially if we have concurrency errors, but it can't hurt.

This means the only genuine issue is... sql_db logging a "bad query"
every time there's a serialization failure.

In `handle_status`, just suppress the message outright, if there's an
error other than serialization the http / dispatch layer should catch
and log it.

In `Commit._notify` things are slightly more difficult as the execute
is implicit (`flush` -> `_write` -> `execute`) so we can't pass the
flag by parameter. One option would be to set and unset
`_default_log_exception`, but it would either be a bit dodgy or it
would require using a context manager and increasing the indentation
level (or using a custom context manager).

Instead just `mute_logger` the fucking thing. It's a bit brutish and
mostly used in tests, but not just, and feels like the least bad
option here...

Closes #805
2024-10-22 14:12:04 +02:00
Xavier Morel
2174d7da31 [IMP] runbot_merge: optimise edited event
For the longest time Github's `change` key was borked when
transitioning a description to and from empty. They fixed that during
2023, which I already saw and impacted on
DC (xmo-odoo/dummy_central@1ebed9d418
and xmo-odoo/dummy_central@937e87c2a4)
but this had yet to be taken in account by the mergebot.

This is now done, the code is functionally reverted to what it was
before I realised `changes` was hosed and moved off of it in
3da1874196.

Fixes #743
2024-10-22 13:12:28 +02:00
Xavier Morel
cf4d162907 [ADD] *: PR backport wizard
This is not a full user-driven backport thingie for now, just one
admins can use to facilitate thing and debug issues with the
system. May eventually graduate to a frontend feature.

Fixes #925
2024-10-22 11:41:58 +02:00
Xavier Morel
ed1f084c4f [IMP] runbot_merge: style fixes
- replace manual token_urlsafe by actual token_urlsafe
- make conditional right side up and more readable
- replace match by fullmatch, should not change anything since we end
  with a greedy universal match but is slightly more explicit
2024-10-22 10:51:47 +02:00
Xavier Morel
632763d390 [CHG] runbot_merge: move labels cron to triggered
Missed it during the previous pass, probably because it's in the
middle of `pull_requests.py`. It's a classic template for triggered
crons since the model is just a queue of actions for the cron.
2024-10-22 10:50:09 +02:00
Xavier Morel
5748c086e5 [FIX] runbot_merge: status of closed PRs in extant batches
If a PR is closed but part of an ongoing batch, the change in status
of the batch might be reflected on the PR still:

- if a PR is closed and the batch gets staged, the PR shows up as
  being staged
- if the PR is merged then the batch gets merged, the PR shows up as
  merged

Fixes #914

Also remove the unused `_tagstate` helper property.
2024-10-16 12:17:30 +02:00
Xavier Morel
20a4e97b05 [CHG] runbot_merge: make merge method non-blocking
Because of the false negatives due to github's reordering of events on
retargeting, blocking merge methods can be rather frustrating or the
user as what's happening and how to solve it isn't clear in that case.

Keep the warnings and all, but remove the blocking factor: if a PR
doesn't have a merge method and is not single-commit, just skip it on
staging. This way, PRs which are actually single-commit will stage
fine even if the mergebot thinks they shouldn't be.

Fixes #957
2024-10-07 08:07:59 +02:00
Xavier Morel
4215be770d [IMP] runbot_merge: move read_tracking_value to utils
And use it in test_trivial_flow instead of the kinda half-assed manual
version.
2024-10-07 08:06:03 +02: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
Xavier Morel
aac987f2bb [FIX] runbot_merge: dashboard display nits
- fix staging reasons containing escaped quotes (would render as
  ` ` to the end user)
- remove extra spacing around PR title @title/popovers
- simplify a few view conditionals through judicious use of `t-elif`
  and nesting
- make `staging_end` non-computed as it's not computed anymore, just
  set if and when the staging gets disabled
  (146564a90a)
2024-09-27 14:13:43 +02:00
Xavier Morel
430ccab2cb [IMP] runbot_merge: suppress view validation warning
This is a dumb false positive, kill it.
2024-09-27 12:53:51 +02:00
Xavier Morel
8f27773f8d [IMP] forwardport: surfacing of modify/delete conflicts
Given branch A, and branch B forked from it. If B removes a file which
a PR to A later modifies, on forward port Git generates a
modify/delete conflict (as in one side modifies a file which the
other deleted).

So far so good, except while it does notify the caller of the issue
the modified file is just dumped as-is into the working copy (or
commit), which essentially resurrects it.

This is an issue, *especially* as the file is already part of a
commit (rather tan just a U local file), if the developer fixes the
conflict "in place" rather than re-doing the forward-port from scratch
it's easy to miss the reincarnated file (and possibly the changes that
were part of it too), which at best leaves parasitic dead code in the
working copy. There is also no easy way for the runbot to check it as
adding unimported standalone files while rare is not unknown
e.g. utility scripts (to say nothing of JS where we can't really track
the usages / imports at all).

To resolve this issue, during conflict generation post-process
modify/delete to insert artificial conflict markers, the file should
be syntactically invalid so linters / checkers should complain, and
the minimal check has a step looking for conflict markers which should
fire and prevent merging the PR.

Fixes #896
2024-09-27 12:37:49 +02:00
Xavier Morel
98868b5200 [IMP] runbot_merge: add notifications on inactive branch interactions
Add warnings when trying to send comments / commands to PRs targeting
inactive branches.

This was missing leading to confusion, as one warning is clearly not
enough.

Fixes #941
2024-09-24 10:22:07 +02:00
Xavier Morel
e309e1a3a2 [FIX] runbot_merge: don't over-bump timeout
By updating the staging timeout every time we run `_compute_state` and
still have a `pending` status, we'd actually bump the timeout *on
every success CI* except for the last one. Which was never the
intention and can add an hour or two to the mergebot-side timeout.

Instead, add an `updated_at` attribute to statuses (name taken from
the webhook payload even though we don't use that), read it when we
see `pending` required statuses, and update the staging timeout based
on that if necessary.

That way as long as we don't get *new* pending statuses, the timeout
doesn't get updated.

Fixes #952
2024-09-20 12:17:17 +02:00
Xavier Morel
154e610bbc [IMP] *: modernize TestPRUpdate
- Switch to just `default` ci.
- Autouse fixture to init the master branch.
- Switch to `make_commits`.
- Merge `test_reopen_update` and `test_update_closed_revalidate` into
  `test_update_closed`: the former did basically nothing useful and
  the latter could easily be folded into `test_update_closed` by just
  validating the new commit.
2024-09-19 12:17:59 +02:00
Xavier Morel
c8a06601a7 [FIX] *: unstage on status going from success to failure
And unconditionally unstage when the HEAD of a PR is synchronised.

While a rebuild on a PR which was previously staged can be a false
positive (e.g. because it hit a non-derministic test the second time
around) it can also be legitimate e.g. auto-rebase of an old PR to
check it out. In that case the PR should be unstaged.

Furthermore, as soon as the PR gets rebuilt it goes back into
`approved` (because the status goes to pending and currently there's
no great way to suppress that in the rebuild case without also fucking
it up for the sync case). This would cause a sync on the PR to be
missed (in that it would not unstage the PR), which is broken. Fix
that by not checking the state of the PR beforehand, it seems to be an
unnecessary remnant of older code, and not really an optimisation (or
at least one likely not worth bothering with, especially as we then
proceed to perform a full PR validation anyway).

Fixes #950
2024-09-18 15:19:13 +02:00
Xavier Morel
a046cf2f7c [FIX] *: UX around fw=no
The UX around the split of limit and forward port policy (and
especially moving "don't forward port" to the policy) was not really
considered and caused confusion for both me and devs: after having
disabled forward porting, updating the limit would not restore it, but
there would be no indication of such an issue.

This caused odoo/enterprise#68916 to not be forward ported at merge
(despite looking for all the world like it should be), and while
updating the limit post-merge did force a forward-port that
inconsistency was just as jarring (also not helped by being unable to
create an fw batch via the backend UI because reasons, see
10ca096d86).

Fix this along most axis:

- Notify the user and reset the fw policy if the limit is updated
  while `fw=no`.
- Trigger a forward port if the fw policy is updated (from `no`) on a
  merged PR, currently only sources.
- Add check & warning to limit update process so it does *not* force a
  port (though maybe it should under the assumption that we're
  updating the limit anyway? We'll see).

Fixes #953
2024-09-17 11:31:20 +02:00
Xavier Morel
851656bec0 [IMP] runbot_merge: set status on skipchecks & use that
- rather than enumerate states, forward-porting should just check if
  the statuses are successful on a PR
- for the same consistency reasons explained in
  f97502e503, `skipchecks` should force
  the status of a PR to `success`: it very odd that a PR would be
  ready without being validated...
2024-09-16 12:49:23 +02:00
Xavier Morel
fe7cd8e1f0 [IMP] runbot_merge: name PR correctly on staging success
Logging PRs by id is unusual, unreadable, and inconvenient.
2024-09-16 12:48:42 +02:00
Xavier Morel
60188063f8 [FIX] *: ensure I don't get bollocked up again by tags
Today (or really a month ago) I learned: when giving git a symbolic
ref (e.g. a ref name), if it's ambiguous then

1. If `$GIT_DIR/$name` exists, that is what you mean (this is usually
   useful only for `HEAD`, `FETCH_HEAD`, `ORIG_HEAD`, `MERGE_HEAD`,
   `REBASE_HEAD`, `REVERT_HEAD`, `CHERRY_PICK_HEAD`, `BISECT_HEAD` and
   `AUTO_MERGE`)
2. otherwise, `refs/$name` if it exists
3. otherwise, `refs/tags/$name` if it exists
4. otherwise, `refs/heads/$name` if it exists
5. otherwise, `refs/remotes/$name` if it exists
6. otherwise, `refs/remotes/$name/HEAD` if it exists

This means if a tag and a branch have the same name and only the name
is provided (not the full ref), git will select the tag, which gets
very confusing for the mergebot as it now tries to rebase onto the tag
(which because that's not fun otherwise was not even on the branch of
the same name).

Fix by providing full refs to `rev-parse` when trying to retrieve the
head of the target branches. And as a defense in depth opportunity,
also exclude tags when fetching refs by spec: apparently fetching a
specific commit does not trigger the retrieval of tags, but any sort
of spec will see the tags come along for the ride even if the tags are
not in any way under the fetched ref e.g. `refs/heads/*` will very
much retrieve the tags despite them being located at `refs/tags/*`.

Fixes #922
2024-09-06 15:09:08 +02:00
Xavier Morel
d0723499a2 [IMP] runbot_merge: stage by first ready
This is an approximation under the assumption that stored computes
update the `write_date`, and that there's not much else that will be
computed on a batch.

Eventually it might be a good idea for this to be a proper field,
computed alongside the unblocking of the batch.

Fixes #932
2024-09-06 13:51:55 +02:00
Xavier Morel
146564a90a [FIX] runbot_merge: set staging_end on all terminations
Rather than only setting `staging_end` on status change, set it when
the staging gets deactivated. This way cancelling a staging (whether
explicitely or via a PR update) will also end it, so will a staging
timeout, etc..., rather than keep the counter running.

Fixes #931
2024-09-06 13:16:37 +02:00
Xavier Morel
64f9dcbc22 [FIX] *: unnecessary warning on r- of forward port
Reminding users that `r-` on a forward port only unreviews *that*
forwardport is useful, as `r+;r-` is not a no-op (all preceding
siblings are still reviewed).

However it is useless if all siblings are not approved or already
merged. So avoid sending the warning in that case.

Fixes #934
2024-09-06 13:04:13 +02:00
Xavier Morel
1d106f552d [FIX] runbot_merge: missing feedback on fw r+
In some cases, feedback to the PR author that an r+ is redundant went
missing.

This turns out to be due to the convolution of the handling of
approval on forward-port, and the fact that the target PR is treated
exactly like its ancestors: if the PR is already approved the approval
is not even attempted (and so no feedback if it's incorrect).

Straighten up this bit and add a special case for the PR being
commented on, it should have the usual feedback if in error or already
commented on.

Furthermore, update `PullRequests._pr_acl` to kinda work out of the
box for forward-port: if the current PR is a forward port,
`is_reviewer` should check delegation on all ancestors, there doesn't
seem to be any reason to split "source_reviewer", "parent_reviewer",
and "is_reviewer".

Fixes #939
2024-09-05 13:25:19 +02:00
Xavier Morel
ccca46c992 [FIX] runbot_merge: layout backend issues galore
- Odoo 17 seems to not be adjusting `nolabel` fields to be `colspan=2`
  by default, so every such occurrence has to be adjusted by hand or
  it gets squeezed in just the labels column.
- Because of the loss of readonly mode, some fields / setups which
  previously looked ugly during the rare edition (e.g. Pr titles) now
  look ugly all the time. Rework layout and force them to always be
  readonly (hopefully we won't need to edit those).
- This is compounded by unfortunate styling I can't find how to
  override e.g. char fields are 100% width even if readonly.
- `<header>` system requires some workarounds to have the right layout
  and spacing (notably `header` has a bunch of awful rules which we
  need to work around via an interstitial div to set up our own
  flexbox).
2024-08-16 15:12:04 +02:00
Xavier Morel
0d653620c2 [FIX] *: styling
- reduce font-size and bold-ness a hair as it causes issues in the
  backend
- remove font adjustment on root object
- add `text-bg-primary` in the oustanding FP view, apparently BS5 does
  not do anything like that by default when setting `bg-primary` for
  some reason so the current team or user appears in black on dark
  blue leading to sub-par readability
2024-08-16 14:20:39 +02:00
Xavier Morel
7eb25234f5 [FIX] runbot_merge: menus
Turns out having the same ids for the feedback template and feedback
object actions was kinda dumb, who'd have thought?

Split them apart so I can get both objects in my menu...
2024-08-16 14:19:13 +02:00
Xavier Morel
8ad186c204 [FIX] runbot_merge: styling on Odoo 17
Fix a few issues with migrated bootstrap classes (left -> start, right
-> end), revert a bunch of shitty colors from standard, fixup
backgrounds.

Tried to remove the background overrides what with having used
variables but it does completely wrong for info, and I can't be
arsed (also force primary alerts for the same reason, I don't
understand what either bootstrap or standard does and how to override
it properly but it's shit). It'll keep.
2024-08-13 14:39:09 +02:00
Xavier Morel
99ae369d69 [FIX] runbot_merge: update freeze wizard widget for 17.0
It was all borken and the web client couldn't even load.

The logic is basically the same, except the new client doesn't support
forcing onchanges maybe, so we need to `read()` the entire thing if
the form is not modified.
2024-08-13 12:50:13 +02:00
Xavier Morel
36786d51c8 [ADD] runbot_merge: 17.0 migration
`message_main_attachment_id` removed from `mail.thread` in
odoo/odoo@f8c7f2e5bb (16.2), however
precise inheritance tracking was only added in
odoo/odoo@b27eb20a41 (17.1), so
stock migration only handles stock models for this migration.
2024-08-13 08:00:21 +02:00
Xavier Morel
aa1df22657 [MERGE] bot from 16.0 to 17.0
Broken (can't run odoo at all):

- In Odoo 17.0, the `pre_init_hook` takes an env, not a cursor, update
  `_check_citext`.
- Odoo 17.0 rejects `@attrs` and doesn't say where they are or how to
  update them, fun, hunt down `attrs={'invisible': ...` and try to fix
  them.
- Odoo 17.0 warns on non-multi creates, update them, most were very
  reasonable, one very wasn't.

Test failures:

- Odoo 17.0 deprecates `name_get` and doesn't use it as a *source*
  anymore, replace overrides by overrides to `_compute_display_name`.
- Multiple tracking changes:
  - `_track_set_author` takes a `Partner` not an id.
  - `_message_compute_author` still requires overriding in order to
    handle record creation, which in standard doesn't support author
    overriding.
  - `mail.tracking.value.field_type` has been removed, the field type
    now needs to be retrieved from the `field_id`.
  - Some tracking ordering have changed and require adjusting a few
    tests.

Also added a few flushes before SQL queries which are not (obviously
at least) at the start of a cron or controller, no test failure
observed but better safe than sorry (probably).
2024-08-12 13:13:03 +02:00
Xavier Morel
61b92b2224 [IMP] runbot_merge: use native support for tracking messages
odoo/odoo@1341d52 added native support for tracking / overriding
tracking message so we don't need `change-message `anymore. The calls
had to be modified a bit as `_track_set_log_message` has to be invoked
on the records for which the tracking message is being set / updated.

Sadly the same for authors was only added in 16.3 *and* it's
unsuitable for our needs as we want to set the author without knowing
the scope of affected records (at least in the controller).

That way hopefully in 17.0 we can remove the `_message_compute_author`
override and things should work out. And maybe for 19.0 we can get the
ability to set a per-model (or even global) fallback author into
standard.
2024-08-09 10:10:01 +02:00
Xavier Morel
f378689a0d [FIX] runbot_merge: dumbshit 16.0 view validation complaints 2024-08-09 10:09:50 +02:00
Xavier Morel
a567960d52 [FIX] runbot_merge: 16.0 orm warning
Regular indexing doesn't work if unaccent is enabled, and the ORM
warns about it.
2024-08-09 10:08:36 +02:00
Xavier Morel
d5bda3d3e2 [MERGE] bot from 15.0 to 16.0
Breakages:

- the entire http.py API was updated requiring fixing the uses of
  `request.jsonrequest` and the patches to `WebRequest` to hook in
  sentry
- `fontawesome` was moved
- `*[@groups]` are now completely removed from the view if not
  matching, so any field inside of them which needs to be used outside
  (e.g. attrs) has to be added as invisible outside the element
- discuss removed the mail tracking value helpers from RPC in
  odoo/odoo#88547, so reimplement locally (and better)
2024-08-08 10:37:42 +02:00
Xavier Morel
0334225114 [FIX] runbot_merge: read sha first in commit statuses broadcast
Because the first operation the notification task performs is updating
the commit, this has to be flushed in order to read-back the commit
hash (probably fixed in later version).

This means if updating the flag triggers a serialization
failure (which happens and is normal) we transition to the `exception`
handler, which *tries to retrieve the sha again* and we get an "in
failed transaction" error on top of the current "serialization
failure", leading to a giant traceback.

Also an unhelpful one since a serialization failure is expected in
this cron.

- Move the reads with no write dependency out of the `try`, there's no
  reason for them to fail, and notably memoize the `sha`.
- Split the handling of serialization failures out of the normal one,
  and just log an `info` (we could actually log nothing, probably).
- Also set the precommit data just before the commit, in case staging
  tracking is ever a thing which could use it.

Fixes #909
2024-08-05 16:16:17 +02:00
Xavier Morel
52f2b1e381 [FIX] runbot_merge: don't show details of merged PR on GH
Detailed statuses are useful in the actual PR dashboard as that allows
direct access to the builds, however in the PR where it's only a
picture it's useless, so fold that information. Also fold it when a PR
is staged.

And while at it add a note / sub-title that the PR is staged.

Fixes #919
2024-08-05 15:18:19 +02:00
Xavier Morel
ff6f046811 [CHG] runbot_merge: deskill mergebot feedback
twas heehee in the moment but it's not really a long term hoohoo
haahaa.
2024-08-05 09:09:23 +02:00
Xavier Morel
ec01523875 [IMP] runbot_merge: prune repo during maintenance
The weekly maintenance would not prune refs. This is not an issue on
odoo/odoo because development branches are in a separate repository,
thus never fetched (we push to them but only using local commits and
remote refs).

However on repos like odoo/documentation the reference and development
branches are collocated, the lack of pruning thus keeps every
development branch alive locally, even years after the branch has been
deleted in the repository.

By pruning remote-tracking refs before GC-ing, we should have cleaner
local clones, and better packing.
2024-08-05 09:03:39 +02:00
Xavier Morel
8131271a9c [FIX] runbot_merge: flaky test
`test_inconsistent_target` was, appropriately, inconsistent, but would
only fail a very small fraction of the time: the issue is that a PR
would switch target between `other` and `master` assuming neither was
an intrinsic blocker *but* the branches are created independently,
just with the same content.

This means if a second ticked over between the creation of the
`master` branch's commit and that of `other`, they would get different
commit hashes (because different timestamp), thus the PR would get 2
commits (or complete nonsense) when targeted to `other`, and the PR
itself would be blocked for lack of a merge method.

The solution is to be slightly less lazy, and create `other` from
`master` instead of copy/pasting the `make_commits` directive. This
means the PR has the exact same number of commits whether targeted to
`master` or `other`, and we now test what we want to test 60 seconds
out of every minute.
2024-08-05 08:58:05 +02:00
Xavier Morel
78cc8835ce [IMP] rubnbot_merge: avoid triggering every cron on every test
Since every cron runs on a fresh database, on the first `run_crons`
every single cron in the db will run even though almost none of them
is relevant.

Aside from the slight inefficiency, this creates unnecessary extra
garbage in the test logs.

By setting the `nextcall` of all crons to infinity in the template we
avoid this issue, only triggered crons (or the crons whose nextcall we
set ourselves) will trigger during calls.

This requires adjusting the branch cleanup cron slightly: it didn't
correctly handle the initial run (`lastcall` being false).
2024-08-05 08:03:56 +02:00
Xavier Morel
157657af49 [REM] *: default_crons fixture
With the trigger-ification pretty much complete the only cron that's
still routinely triggered explicitly is the cross-pr check, and it's
that in all modules, so there's no cause to keep an overridable
fixture.
2024-08-02 15:14:50 +02:00
Xavier Morel
3ee3e9cc81 [IMP] *: trigger-ify staging cron
The staging cron turns out to be pretty reasonable to trigger, as we
already have a handler on the transition of a batch to `not blocked`,
which is exactly when we want to create a staging (that and the
completion of the previous staging).

The batch transition is in a compute which is not awesome, but on the
flip side we also cancel active stagings in that exact scenario (if it
applies), so that matches.

The only real finesse is that one of the tests wants to observe the
instant between the end of a staging (and creation of splits) and the
start of the next one, which because the staging cron is triggered by
the failure of the previous staging is now "atomic", requiring
disabling the staging cron, which means the trigger is skipped
entirely. So this requires triggering the staging cron by hand.
2024-08-02 15:14:50 +02:00
Xavier Morel
f367a64481 [IMP] *: trigger-ify merge cron
The merge cron is the one in charge of checking staging state and
either integrating the staging into the reference branch (if
successful) or cancelling the staging (if failed).

The most obvious trigger for the merge cron is a change in staging
state from the states computation (transition from pending to either
success or failure). Explicitly cancelling / failing a staging marks
it as inactive so the merge cron isn't actually needed.

However an other major trigger is *timeout*, which doesn't have a
trivial signal. Instead, it needs to be hooked on the `timeout_limit`,
and has to be re-triggered at every update to the `timeout_limit`,
which in normal operations is mostly from "pending" statuses bumping
the timeout limit. In that case, `_trigger` to the `timeout_limit` as
that's where / when we expect a status change.

Worst case scenario with this is we have parasitic wakeups of this
cron, but having half a dozen wakeups unnecessary wakeups in an hour
is still probably better than having a wakeup every minute.
2024-08-02 15:14:50 +02:00
Xavier Morel
029957dbeb [IMP] *: trigger-ify task queue type crons
These are pretty simple to convert as they are straightforward: an
item is added  to a work queue (table), then a cron regularly scans
through the table executing the items and deleting them.

That means the cron trigger can just be added on `create` and things
should work out fine.

There's just two wrinkles in the port_forward cron:

- It can be requeued in the future, so needs a conditional trigger-ing
  in `write`.
- It is disabled during freeze (maybe something to change), as a
  result triggers don't enqueue at all, so we need to immediately
  trigger after freeze to force the cron re-enabling it.
2024-08-02 15:14:50 +02:00
Xavier Morel
57a82235d9 [IMP] *: rely only on triggers to run statuses propagation
The cron had been converted to using mostly triggers in
7cd9afe7f2 but I forgot to update
the *tests* to avoid explicitly triggering it.
2024-08-02 12:12:20 +02:00
Xavier Morel
dd17730f4c [IMP] *: crons tests running for better triggered compatibility
Mergebot / forwardport crons need to run in a specific ordering in
order to flow into one another correctly. The default ordering being
unspecified, it was not possible to use the normal cron
runner (instead of the external driver running crons in sequence one
at a time). This can be fixed by setting *sequences* on crons, as the
cron runner (`_process_jobs`) will use that order to acquire and run
crons.

Also override `_process_jobs` however: the built-in cron runner
fetches a static list of ready crons, then runs that.

This is fine for normal situation where the cron runner runs in a loop
anyway but it's any issue for the tests, as we expect that cron A can
trigger cron B, and we want cron B to run *right now* even if it
hadn't been triggered before cron A ran.

We can replace `_process_job` with a cut down version which does
that (cut down because we don't need most of the error handling /
resilience, there's no concurrent workers, there's no module being
installed, versions must match, ...). This allows e.g. the cron
propagating commit statuses to trigger the staging cron, and both will
run within the same `run_crons` session.

Something I didn't touch is that `_process_jobs` internally creates
completely new environments so there is no way to pass context into
the cron jobs anymore (whereas it works for `method_direct_trigger`),
this means the context values have to be shunted elsewhere for that
purpose which is gross. But even though I'm replacing `_process_jobs`,
this seems a bit too much of a change in cron execution semantics. So
left it out.

While at it tho, silence the spammy `py.warnings` stuff I can't do
much about.
2024-08-02 09:00:34 +02:00
Xavier Morel
cabab210de [FIX] *: don't send merge errors to logging
Merge errors are logical failures, not technical, it doesn't make
sense to log them out because there's nothing to be done technically,
a PR having consistency issues or a conflict is "normal". As such
those messages are completely useless and just take unnecessary space
in the logs, making their use more difficult.

Instead of sending them to logging, log staging attempts to the PR
itself, and only do normal logging of the operation as an indicative
item. And remove a bunch of `expect_log_errors` which don't stand
anymore.

While at it, fix a missed issue in forward porting: if the `root.head`
doesn't exist in the repo its `fetch` will immediately fail before
`cat-file` can even run, so the second one is redundant and the first
one needs to be handled properly. Do that. And leave checking
for *that* specific condition as a logged-out error as it should mean
there's something very odd with the repository (how can a pull request
have a head we can't fetch?)
2024-07-26 14:48:59 +02:00
Xavier Morel
6f0aea799f [IMP] *: add test for r- on forward ports
Apparently I'd already fixed that in
286c1fdaee but it has yet to be
deployed.

While at it, add a feedback message to clarify that, unlike `r+`, `r-`
on forward ports does *not* propagate.

Fixes #912
2024-07-26 12:29:52 +02:00
Xavier Morel
a0d4bb0d0c [ADD] runbot_merge: expanded view for current batch
The PR dashboard picture provides a great overview of the batch state
both horizontally and vertically *but* apparently people can't for the
life of them go check the actual dashboard when things don't line
up. So expand the "current batch" to a view more similar to
dashboard *page*, which gives details of the sub-checks being
performed and whether they are or are not fulfilled.

Fixes #908
2024-07-26 10:01:33 +02:00
Xavier Morel
f5eb7447fb [IMP] runbot_merge: reorganise composition of PR dashboard pic
The previous version worked but was extremely plodding and
procedural. Initially I wanted to compose the table in a single pass
but that turns out not to really be possible as the goal for #908 is
to have a "drawer" for extended information about the current batch:
this means different cells of the same row can have different heights,
so we can't one-pass the image either vertically (later cells of the
current column might be wider) or horizontally (later cells of the
current row might be taller).

However what can be done is give the entire thing *structure*,
essentially defining a very cut down and ad-hoc layout system before
committing the layout to raster.

This also deduplicates formatting and labelling information which was
previously in both the computation first step and the rasterisation
second step.
2024-07-25 15:34:23 +02:00
Xavier Morel
6cc9a6ca11 [IMP] runbot_merge: show batch inconsistency in PR dash picture
Extract current table generation into a separate function, add an
other function to render an alert / list of PR targets if the batch is
not consistent.

This means an extra pass on the table contents to precompute the image
size, but we can delay loading fonts until after etag computation
which might be a bigger gain all things considered: there aren't many
cells in most PR tables, but fonts are rather expensive to
load (I should probably load them at import and cache them in the module...)
2024-07-24 13:27:26 +02:00
Xavier Morel
bca8adbdc4 [IMP] runbot_merge: move inconsistency block higher in batches
Should probably take priority over a PR being misconfigured.
2024-07-24 12:35:21 +02:00
Xavier Morel
fd6eae0d1d [IMP] runbot_merge: ensure inconsistent batches don't merge
I was pretty sure it wouldn't happen but it doesn't hurt to make sure,
also to check that splitting the batch does correctly make things work
out.
2024-07-23 13:00:43 +02:00
Xavier Morel
015c97b2cc [IMP] runbot_merge: add an alert that a batch is inconsistent
Trying to fit an inconsistent batch in the nice table turns out to be
quite difficult (for me anyway) so give up and display *just* the
alert.
2024-07-23 13:00:43 +02:00
Xavier Morel
82ec48c8da [IMP] runbot_merge: track PR label
It's not modified super often, but seems important to track if it
happens to be modified.
2024-07-23 13:00:19 +02:00
Xavier Morel
4a40c0338c [ADD] runbot_merge: small wizard to split a PR off of its batch 2024-07-23 13:00:19 +02:00
Xavier Morel
e6a743bdc2 [FIX] runbot_merge: the batch target should prioritise open PRs
From the previous version of `_compute_target` this was clearly
intended otherwise the fallback makes no sense, but just as clearly I
completely missed / forgot about it halfway through (and the lack of
test didn't help).

The compute is also way overcomplicated, it's not clear why (the only
explanation I can think of is that an intermediate version had a
string target but if that ever happened it was squashed away).
2024-07-23 13:00:19 +02:00
Xavier Morel
7a0a6d4415 [IMP] runbot_merge: backend UI
- Update branch name to prefix with project as it can be hard to
  differentiate when filtering by or trying to set targets, given some
  targets are extremely common (e.g. `master`/`main`) and not all
  fields are filtered by project (or even can be).
- Add a proper menu item and list view for batches, maybe it'll be of
  use one day.
- Upgrade label in PR search, it's more likely to be needed than
  author or target.
- Put PRs first in the mergebot menu, as it's *by far* the most likely
  item to look for, unless it's staging in order to cancel one.
2024-07-23 13:00:19 +02:00
Xavier Morel
47df8fac84 [FIX] runbot_merge: bg-unmerged color
This color was altered in 232aa271b0, it
was moved from a cyan-ish green to a yellow quite close to the warning
color.

There is no explanation why, the commit concerns itself with *PR*
dashboards but this class / color is only used on the main
dashboard. It may have been a victim of the color refactoring in that
commit and I fucked up.

This is very disagreeable as it shows up as basically a warning
between the end of staging and it actually getting merged. Rollback
this change back to a green-cyan.
2024-07-15 10:32:25 +02:00
Xavier Morel
d6bb18e358 [ADD] runbot_merge: rendering of PR descriptions
Previously PR descriptions were displayed as raw text in the PR
dashboard. While not wrong per se, this was pretty ugly and not always
convenient as e.g. links had to be copied by hand.

Push descriptions through pymarkdown for rendering them, with a few
customisations:

- Enabled footnotes & tables & fenced code blocks because GFM has
  that, this doesn't quite put pymarkdown's base behaviour on par with
  gfm (and py-gfm ultimately gave up on that effort moving to just
  wrap github's own markdown renderer instead).
- Don't allow raw html because too much of a hassle to do it
  correctly, and very few people ever do it (mostly me I think).
- Added a bespoke handler / renderer for github-style references.

  Note: uses positional captures because it started that way and named
  captures are not removed from that sequence so mixing and matching
  is not very useful, plus python does not support identically named
  groups (even exclusive) so all 4 repo captures and all 3 issue
  number captures would need different names...
- And added a second bespoke handler for our own opw/issue references
  leading to odoo.com, that's something we can't do via github[^1] so
  it's a genuine value-add.

Fixes #889

[^1]: github can do it (though possibly not with the arbitrary
    unspecified nonsense I got when I tried to list some of the
    reference styles, some folks need therapy), but it's not available
    on our plan
2024-07-15 10:28:28 +02:00
Xavier Morel
02013a53d9 [IMP] runbot_merge: message when approving a PR in error
I thought I'd removed the error message when approving an already
approved PR but apparently not?

However we can improve the message in that specific case, to make the
expected operation clearer.

Fixes #906
2024-07-09 15:18:48 +02:00
Xavier Morel
b1d3278de1 [CHG] forwardport: perform forward porting without working copies
The goal is to reduce maintenance and odd disk interactions &
concurrency issues, by not creating concurrent clones, not having to
push forks back in the repository, etc... it also removes the need to
cleanup "scratch" working copies though that looks not to have been an
issue in a while.

The work is done on isolated objects without using or mutating refs,
so even concurrent work should not be a problem.

This turns out to not be any more verbose (less so if anything) than
using `cherry-pick`, as that is not really designed for scripted /
non-interactive use, or for squashing commits thereafter. Working
directly with trees and commits is quite a bit cleaner even without a
ton of helpers.

Much of the credit goes to Julia Evans for [their investigation of
3-way merges as the underpinnings of cherry-picking][3-way merge],
this would have been a lot more difficult if I'd had to rediscover the
merge-base trick independently.

A few things have been changed by this:

- The old trace/stderr from cherrypick has disappeared as it's
  generated by cherrypick, but for a non-interactive use it's kinda
  useless anyway so I probably should have looked into removing it
  earlier (I think the main use was investigation of the inflateinit
  issue).
- Error on emptied commits has to be hand-rolled as `merge-tree`
  couldn't care less, this is not hard but is a bit annoying.
- `merge-tree`'s conflict information only references raw commits,
  which makes sense, but requires updating a bunch of tests. Then
  again so does the fact that it *usually* doesn't send anything to
  stderr, so that's usually disappearing.

Conveniently `merge-tree` merges the conflict marker directly in the
files / tree so we don't have to mess about moving them back out of
the repository and into the working copy as I assume cherry-pick does,
which means we don't have to try and commit them back in ether. That
is a huge part of the gain over faffing about with the working copy.

Fixes #847

[3-way merge]: https://jvns.ca/blog/2023/11/10/how-cherry-pick-and-revert-work/
2024-07-08 14:37:14 +02:00
Xavier Morel
3062f30245 [IMP] runbot_merge: pass commit-tree message via stdin
Automating via parameters is riskier as we can hit the CLI
limitations (cf 0a839a4857). Going
through stdin is a lot safer and cleaner when automating, and it's not
much of an imposition here.
2024-07-05 13:29:20 +02:00
Xavier Morel
94cf3e9647 [IMP] *: convert fw=no to a genuine forward-porting policy
After seeing it be used, I foresee confusion around the current
behaviour (where it sets the limit), as one would expect the `fw=`
flags to affect one another when it looks like that would make sense
e.g. no/default/skipci/skipmerge all specify how to forward port, so
`fw=default` not doing anything after you've said `fw=no` (possibly by
mistake) would be fucking weird.

Also since the author can set limits, allow them to reset the fw
policy to default (keep skipci for reviewers), and for @d-fence add a
`fw=disabled` alias.

Fixes #902
2024-06-28 16:06:20 +02:00