nelsonic / practice

Practice makes ...
11 stars 4 forks source link

Autobot: Automate Merging Dependabot PRs #65

Open nelsonic opened 2 years ago

nelsonic commented 2 years ago
document
  .querySelectorAll(".octicon-git-pull-request.color-fg-open")[0]
  .closest(".notification-list-item-link")
  .click();

setTimeout(() => {
  document
    .querySelectorAll(".octicon-file-diff")[0]
    .closest(".tabnav-tab")
    .click();

  setTimeout(() => {
    document.querySelectorAll(".js-reviews-toggle")[0].click();
    var text = "Thanks @dependabot πŸ€– πŸ‘Œ";
    document.getElementById("pull_request_review_body").value = text;
    document.querySelectorAll('[value="approve"]')[0].click();
    document.querySelectorAll("button.float-left")[1].click();
  }, 2000);
}, 2000);

Followed by:

document.querySelectorAll(".hx_create-pr-button")[0].click();
document.querySelectorAll(".js-merge-commit-button")[0].click();

setTimeout(() => {
  document.querySelectorAll('[title="Done"]')[0].click();
}, 2000);

Β Context:

We have quite a few Elixir/Phoenix projects ... github.com/dwyl?q=language=elixir

so when a random dependency is patched and Dependabot creates Pull Requests to update it, we get this kind of thing: image

I don't want to merge them all without supervision because I want to be informed of the updates. But I do want to a generic script I can use to automate. Think of it as "supervised automation" 😜

nelsonic commented 2 years ago

Using my DOM script from #1 as the starting point.

This works manually in Chrome/FF dev tools:

function run() {
  document
    .querySelectorAll(".octicon-git-pull-request.color-fg-open")[0]
    .closest(".notification-list-item-link")
    .click();

  setTimeout(() => {
    document
      .querySelectorAll(".octicon-file-diff")[0]
      .closest(".tabnav-tab")
      .click();

    setTimeout(() => {
      document.querySelectorAll(".js-reviews-toggle")[0].click();
      var text = "Thanks @dependabot πŸ€– πŸ‘Œ";
      document.getElementById("pull_request_review_body").value = text;
      document.querySelectorAll('[value="approve"]')[0].click();
      document.querySelectorAll("button.float-left")[2].click();
      next();
    }, 5000);
  }, 5000);
}
run();

function next() {
  setTimeout(() => {
    document.querySelectorAll(".hx_create-pr-button")[0].click();
    document.querySelectorAll(".js-merge-commit-button")[0].click();

    setTimeout(() => {
      document.querySelectorAll('[title="Done"]')[0].click();
      run();
    }, 4000);
  }, 4000);
}

Due to the full-page-refresh when submitting a PR review which is both server and client rendered πŸ™„ It cannot be run "unsupervised" ... πŸ€¦β€β™‚οΈ Considering building a chrome extension for this. πŸ’­

nelsonic commented 2 years ago

OK. not going to waste any more time on this. It's definitely a distraction!!

But when I need the script it's better to run it in two stages:

document
  .querySelectorAll(".octicon-git-pull-request.color-fg-open")[0]
  .closest(".notification-list-item-link")
  .click();

setTimeout(() => {
  document
    .querySelectorAll(".octicon-file-diff")[0]
    .closest(".tabnav-tab")
    .click();

  setTimeout(() => {
    document.querySelectorAll(".js-reviews-toggle")[0].click();
    var text = "Thanks @dependabot πŸ€– πŸ‘Œ";
    document.getElementById("pull_request_review_body").value = text;
    document.querySelectorAll('[value="approve"]')[0].click();
    document.querySelectorAll("button.float-left")[2].click();
  }, 3000);
}, 3000);

Followed by:

document.querySelectorAll(".hx_create-pr-button")[0].click();
document.querySelectorAll(".js-merge-commit-button")[0].click();

setTimeout(() => {
  document.querySelectorAll('[title="Done"]')[0].click();
}, 4000);

because the DOM loading is incredibly unreliable!

nelsonic commented 2 years ago

Quick demo:

https://user-images.githubusercontent.com/194400/179505817-16fad9f8-a182-40b8-87cc-0195cd822395.mov

nelsonic commented 2 years ago

Once you have run both script blocks once you can use the up arrow and enter keys to repeat. ♻️ This is considerably faster than clicking through, typing, clicking, waiting, locating buttons ... ⏳ πŸ™„

nelsonic commented 2 years ago

Reading: https://violentmonkey.github.io/get-it/

image

Given that Microsoft already know everything I'm doing on GitHub ... Considering installing Edge browser: https://www.microsoft.com/en-us/edge image

And using it as my GitHub Notifications browser ... πŸ’­

nelsonic commented 2 years ago

Let's come back to this.

nelsonic commented 2 years ago

Top tip. if you don't quite the Chrome App your DevTools Console history maintains any scripts/code you have run so even though I had closed the tab I could still retrieve the script from history. just used it. so glad I wrote it. let's see how long the DOM attributes/classes last before GH inevitably does another re-design. πŸ™„

nelsonic commented 2 years ago

Installing Microsoft Edge on Mac requires 730 MB of storage ... πŸ™„

image
nelsonic commented 2 years ago

πŸ™„

image
nelsonic commented 2 years ago

Literally just downloaded Edge from the Microsoft site and there's already an update ...

image

Not even 5 mins later. πŸ€¦β€β™‚οΈ Why didn't they just update the binary and save me this noise?!

nelsonic commented 1 year ago

Yay! GitHub updated their markup, again ... πŸŽ‰ (πŸ™„)

image

Gotta update the script. πŸ§‘β€πŸ’» βŒ›

nelsonic commented 1 year ago

Easy enough, the number of buttons on the page was reduced from 3 to 2 so the index for the "Submit review" button is now 1 not 2:

document
  .querySelectorAll(".octicon-git-pull-request.color-fg-open")[0]
  .closest(".notification-list-item-link")
  .click();

setTimeout(() => {
  document
    .querySelectorAll(".octicon-file-diff")[0]
    .closest(".tabnav-tab")
    .click();

  setTimeout(() => {
    document.querySelectorAll(".js-reviews-toggle")[0].click();
    var text = "Thanks @dependabot πŸ€– πŸ‘Œ";
    document.getElementById("pull_request_review_body").value = text;
    document.querySelectorAll('[value="approve"]')[0].click();
    document.querySelectorAll("button.float-left")[1].click();
  }, 2000);
}, 2000);

I would still like to make the whole script run as one but now is not the time to be messing with that because of network latency ... ⏳

nelsonic commented 1 year ago
var links = document
  .querySelectorAll(".octicon-git-pull-request.color-fg-open");
links[links.length - 1].closest(".notification-list-item-link").click();
setTimeout(() => {
  document
    .querySelectorAll(".octicon-file-diff")[0]
    .closest(".tabnav-tab")
    .click();

  setTimeout(() => {
    document.querySelectorAll(".js-reviews-toggle")[0].click();
    var text = "Thanks @dependabot πŸ€– πŸ‘Œ";
    document.getElementById("pull_request_review_body").value = text;
    document.querySelectorAll('[value="approve"]')[0].click();
    document.querySelectorAll("button.float-left")[1].click();
  }, 2000);
}, 2000);
nelsonic commented 1 year ago
document.querySelectorAll(".hx_create-pr-button")[0].click();
document.querySelectorAll(".js-merge-commit-button")[0].click();

setTimeout(() => {
  document.querySelectorAll('[aria-label="Done"]')[0].click();
}, 2000);
nelsonic commented 1 year ago

Attempt single script:

var links = document
  .querySelectorAll(".octicon-git-pull-request.color-fg-open");
links[links.length - 1].closest(".notification-list-item-link").click();
setTimeout(() => {
  document
    .querySelectorAll(".octicon-file-diff")[0]
    .closest(".tabnav-tab")
    .click();

  setTimeout(() => {
    document.querySelectorAll(".js-reviews-toggle")[0].click();
    var text = "Thanks @dependabot πŸ€– πŸ‘Œ";
    document.getElementById("pull_request_review_body").value = text;
    document.querySelectorAll('[value="approve"]')[0].click();
    document.querySelectorAll("button.float-left")[1].click();
    // merge:
    setTimeout(() => {
        document.querySelectorAll(".hx_create-pr-button")[0].click();
        document.querySelectorAll(".js-merge-commit-button")[0].click();

        setTimeout(() => {
          document.querySelectorAll('[aria-label="Done"]')[0].click();
        }, 1000);
    }, 2000);
  }, 2000);
}, 2000);