Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Force waiting for automated merge #40

Open
wants to merge 24 commits into
base: master
Choose a base branch
from

Conversation

eduard-bagdasaryan
Copy link
Contributor

Each GitHub PR has a manual merge button on the GitHub PR page,
which becomes green as soon as all preconditions (mandatory PR checks)
are satisfied. At that time, some admins may click on that button,
resulting in wrong commit messages and missing auto tests (at best).

To reduce the probability of such accidents, Anubis now automatically
adds a "waiting for automated merge" check, marked as required on
GitHub.

  • For the staged commit, the check is satisfied immediately before
    the attempted merge (so that GitHub is happy about all the required
    status checks).

  • For the PR, the check is satisfied only after Anubis merges the
    staged commit.

Each GitHub PR has a manual merge button on the GitHub PR page,
which becomes green as soon as all preconditions (mandatory PR checks)
are satisfied. At that time, some admins may click on that button,
resulting in wrong commit messages and missing auto tests (at best).

To reduce the probability of such accidents, Anubis now automatically
adds a "waiting for automated merge" check, marked as required on
GitHub.

* For the staged commit, the check is satisfied immediately before
  the attempted merge (so that GitHub is happy about all the required
  status checks).

* For the PR, the check is satisfied only after Anubis merges the
  staged commit.
src/Config.js Outdated
automatedMergeStatusUrl() { return this._automatedMergeUrl; }

// the 'context name' of the automated merge test status
automatedMergeStatusContext() { return "Merge automatically"; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
automatedMergeStatusContext() { return "Merge automatically"; }
automatedMergeStatusContext() { return "Automated merge"; }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

}

async _setAutomatedMergeStatusForStaged(state) {
const description = this._automatedMergeStatusDescription();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please declare closer to the first use.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

if (!Config.manageAutomatedMergeStatus())
return;

const state = this._prState.merged() ? "success" : "pending";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we have discussed, this will become pending/success/failure.

this._automatedMergeStatusDescription(), Config.automatedMergeStatusContext());
}

_automatedMergeStatusDescription() { return this._prState.toString(); }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we have discussed, the automated merge status check description should be more detailed. We should also avoid internal/undocumented terminology like "brewing". Here are a few rough suggestions:

  • success (M-merged) and success (will be merged) -- see another change request for details.

  • failure (M-failed-foo) -- where M-failed-foo is a PR label that corresponds to a "problematic" condition "foo" that requires a human action to correct (e.g., M-failed-description). On a logical level, the set of such labels/conditions includes M-failed-review. There is no such label (yet?); we can use PR approval text instead. There can be multiple active M-failed-foo labels (at least in theory). If that can happen in the current code, to avoid noise and to simplify implementation, I would probably list just one label (e.g., the first encountered label or whichever is easier to implement).

  • pending (M-waiting-foo) -- where M-waiting-foo is a PR label that corresponds to a "positive" condition "foo" that Anubis is waiting for (e.g., M-waiting-staging-checks). On a logical level (at least), the set of such labels/conditions includes M-waiting-objections and M-waiting-approvals that are documented but not yet set; we can use their names (because they are documented) or just use PR approval text instead of those two label names (because they are not implemented). My weak recommendation is to do the latter. I do not think there can be multiple active M-waiting-foo labels (today), but please correct me if I am wrong.

When multiple states apply, the state listed higher (above) wins.

For any M-{waiting,failed}-staging-checks label inside the status check description, it would be nice to add a staged commit SHA: pending (M-waiting-staging-checks for SHA) and failure (M-failed-staging-checks for SHA).

Similarly, it would be nice to add SHA to the visible success status -- success (will be merged as SHA) and success (M-merged as SHA). AFAICT, success (will be merged as SHA) will be visible (at least for a while) if the final merge step fails so having SHA here would be useful. If the success (M-merged as SHA) status is never actually visible (except in the merged commit itself), then adding SHA to that specific status would be kind of pointless and, hence, is not necessary. On the other hand, automatic PR closure may fail or a human can reopen an auto-closed request, making even the "final" success status visible, right?

Comment on lines 206 to 208
el.context.trim() === Config.automatedMergeStatusContext() &&
el.state === state &&
el.description === description);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If possible, reorder to place faster and more selective conditions first:

Suggested change
el.context.trim() === Config.automatedMergeStatusContext() &&
el.state === state &&
el.description === description);
el.description === description &&
el.state === state &&
el.context.trim() === Config.automatedMergeStatusContext();

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@@ -1166,6 +1237,8 @@ class PullRequest {

assert(!this._stagingBanned);

await this._setAutomatedMergeStatusForStaged("success");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we are setting this a bit prematurely/optimistically, it would be nice to make this one success (will merge SHA) and then, if the status may become visible anywhere after we successfully merge (as discussed in another change request), change that to success (M-merged as SHA).

including states not covered with labels, such as 'waiting for
approval', 'work in progress', 'failed PR tests' and others.

Also:
* Utilize StatusCheck class when generating/creating automated checks

* Removed all unnecessary status creations except for 'finally' block
 (and required one in_mergeToBase())
Copy link
Contributor Author

@eduard-bagdasaryan eduard-bagdasaryan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done (28113c5, 3cfb8ba).

src/Config.js Outdated
automatedMergeStatusUrl() { return this._automatedMergeUrl; }

// the 'context name' of the automated merge test status
automatedMergeStatusContext() { return "Merge automatically"; }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment on lines 206 to 208
el.context.trim() === Config.automatedMergeStatusContext() &&
el.state === state &&
el.description === description);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

}

async _setAutomatedMergeStatusForStaged(state) {
const description = this._automatedMergeStatusDescription();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

* When M-waiting-staging-checks is on
* Just before merge on base
These statuses now take their description from the
corresponding PrProblem context. I enhanced this context
to keep additional information about labels and the status
itself (pending/fail).

Also improved the staged automated status description with
additional information about the number succeeded/passed/failed
tests.
This allowed to simplify StatusChecks code (also addressing a TODO)
removing many additional checks and conditions related to special
('Approval' and 'Automated') statuses.
I am not sure whether we can add footnotes at the end of a specific
section - so it is better to avoid using them for now.
Fixed a couple of bugs revealed during testing.
Also added Config.manage*() guards.
Also calculate the number of derivative tests
(instead of hardcoding them).
The abandoned staged commit is already marked with the corresponding
'Automated merge' status indicating this state. We do not need
to duplicate this information in the label.
The underlying problem was that the DerivedStatusChecks
object (tracking both Approval and Automated checks) could be
missing at an early stage, i.e., before these checks had been
requested from GitHub or manually created. Now we:

* Ensure that DerivedStatusChecks exists when applying approvals
  (in other words, we ensure that we do not apply approvals at an
  early stage).

* Do not update the automated check in this case. Since no 'known'
  error (aka PrProblem) can occur at this early stage (at least
  for now), it is probably better to consign these general
  (and probably PR-unrelated) errors to labels (such as M-failed-other),
  and update the automated check only after the problems are resolved.
This somehow relates to the second bullet of bd6e9ad. If we have got
a PrProblem we must be sure that there is already the corresponding
statuses object that we can update.

Also removed some stale code and adjusted documentation regarding
M-failed-staging-checks behavior.
This class is now a GitHub representation of the internal
checks (containing cached values). When fresh internal checks
are created, they are compared with the cached ones and applied
only if there is a difference (still keeping the cache in sync).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants