Auto Merge Dependabot PRs

Automatically clicks the merge button on Dependabot PRs and "Done" button on the notification bar

Versão de: 04/12/2024. Veja: a última versão.

  1. // ==UserScript==
  2. // @name Auto Merge Dependabot PRs
  3. // @namespace https://github.com/Nick2bad4u/UserStyles
  4. // @version 1.3
  5. // @description Automatically clicks the merge button on Dependabot PRs and "Done" button on the notification bar
  6. // @author Nick2bad4u
  7. // @match https://github.com/*/*/pull/*
  8. // @grant none
  9. // @icon https://www.google.com/s2/favicons?sz=64&domain=github.com
  10. // @license UnLicense
  11. // ==/UserScript==
  12.  
  13. (function () {
  14. 'use strict';
  15.  
  16. let lastCheck = 0;
  17. const CHECK_INTERVAL = 1000;
  18. let observer;
  19.  
  20. function checkAndMerge() {
  21. const now = Date.now();
  22. if (now - lastCheck < CHECK_INTERVAL) return;
  23. lastCheck = now;
  24.  
  25. console.log('checkAndMerge function called');
  26.  
  27. const authorElement =
  28. document.querySelector('.author');
  29. if (
  30. authorElement &&
  31. /dependabot(\[bot\])?|Nick2bad4u/.test(
  32. authorElement.textContent.trim(),
  33. )
  34. ) {
  35. setTimeout(() => {
  36. const mergeButton =
  37. document.querySelector('.btn.btn-sm');
  38. if (
  39. mergeButton &&
  40. !mergeButton.disabled
  41. ) {
  42. console.log(
  43. 'Merge button is enabled, clicking it',
  44. );
  45. mergeButton.click();
  46. if (observer) observer.disconnect();
  47. observeDoneButton();
  48. } else {
  49. console.log(
  50. 'Merge button is disabled or not found',
  51. );
  52. }
  53. }, 500);
  54. } else {
  55. console.log(
  56. 'PR is not created by dependabot',
  57. );
  58. }
  59. }
  60.  
  61. function observeDoneButton() {
  62. console.log('Observing for Done button...');
  63. const notificationBar =
  64. document.querySelector(
  65. '.js-flash-container',
  66. ); // Adjust as necessary
  67.  
  68. if (!notificationBar) {
  69. console.log('Notification bar not found');
  70. return;
  71. }
  72.  
  73. const doneButtonObserver =
  74. new MutationObserver(() => {
  75. const doneButton = document.querySelector(
  76. 'button[aria-label="Done"].btn.btn-sm',
  77. );
  78. if (doneButton) {
  79. console.log(
  80. 'Done button found, clicking it',
  81. );
  82. doneButton.click();
  83. doneButtonObserver.disconnect(); // Stop observing after clicking
  84. }
  85. });
  86.  
  87. doneButtonObserver.observe(notificationBar, {
  88. childList: true,
  89. subtree: true,
  90. });
  91. }
  92.  
  93. globalThis.addEventListener(
  94. 'load',
  95. function () {
  96. console.log('Page loaded');
  97.  
  98. const targetNode = document.querySelector(
  99. '.gh-header-meta',
  100. );
  101. if (!targetNode) {
  102. console.log(
  103. 'Target node for observation not found',
  104. );
  105. return;
  106. }
  107.  
  108. observer = new MutationObserver(() => {
  109. console.log(
  110. 'Relevant DOM mutation detected',
  111. );
  112. checkAndMerge();
  113. });
  114.  
  115. observer.observe(targetNode, {
  116. childList: true,
  117. subtree: true,
  118. });
  119. checkAndMerge();
  120. },
  121. false,
  122. );
  123. })();