Auto-Click Review Deployments

Automatically click "Review deployments" button on GitHub Actions runs pages

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         Auto-Click Review Deployments
// @namespace    http://tampermonkey.net/
// @version      1.6
// @description  Automatically click "Review deployments" button on GitHub Actions runs pages
// @locale       en
// @match        https://github.*.co.nz/*/*/actions/runs/*
// @match        https://github.*.co.nz/*/*/actions/workflows/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    let currentInterval = null;

    function clickReviewButton() {
        // Look for all "Review deployments" buttons
        const buttons = document.querySelectorAll('button[data-show-dialog-id]');
        console.log(`[RL - Auto-Click Review] Found ${buttons.length} buttons with data-show-dialog-id`);

        let clickedCount = 0;
        for (const button of buttons) {
            const text = button.textContent.trim();
            console.log(`[RL - Auto-Click Review] Button text: "${text}"`);

            // Check for both button text variations
            if (text.includes('Review pending deployments') || text.includes('Review deployments')) {
                const dialogId = button.getAttribute('data-show-dialog-id');
                console.log(`[RL - Auto-Click Review] ✓ Review button found: "${text}", dialog ID: ${dialogId}`);

                // Click the button
                button.click();
                clickedCount++;

                // Wait a bit and check if dialog opened
                setTimeout(() => {
                    const dialog = document.getElementById(dialogId);
                    if (dialog) {
                        console.log(`[RL - Auto-Click Review] Dialog ${dialogId} exists, has 'open' attribute: ${dialog.hasAttribute('open')}`);

                        // Force the dialog to open if it's not already
                        if (!dialog.hasAttribute('open')) {
                            console.log(`[RL - Auto-Click Review] ⚠️ Dialog not open, forcing it to open...`);
                            dialog.setAttribute('open', '');
                            dialog.showModal?.();
                        }

                        // Ensure dialog is visible
                        dialog.style.display = 'block';
                        dialog.style.visibility = 'visible';
                        dialog.style.opacity = '1';
                        console.log(`[RL - Auto-Click Review] ✓ Dialog ${dialogId} should now be visible`);
                    } else {
                        console.log(`[RL - Auto-Click Review] ✗ Dialog ${dialogId} not found in DOM`);
                    }
                }, 300);
            }
        }

        return clickedCount > 0;
    }

    function startSearching() {
        // Clear any existing interval
        if (currentInterval) {
            clearInterval(currentInterval);
        }

        let attempts = 0;
        const maxAttempts = 5; // Try for 2.5 seconds (5 * 500ms)

        console.log('[RL - Auto-Click Review] 🔍 Starting search for Review deployments button...');

        currentInterval = setInterval(() => {
            attempts++;
            console.log(`[RL - Auto-Click Review] === Attempt ${attempts} ===`);

            if (clickReviewButton()) {
                clearInterval(currentInterval);
                console.log('[RL - Auto-Click Review] ✓ Buttons clicked successfully!');
            } else if (attempts >= maxAttempts) {
                clearInterval(currentInterval);
                console.log('[RL - Auto-Click Review] ✗ Buttons not found after 2.5 seconds, stopping search.');
            }
        }, 650);
    }

    // Start on initial page load
    startSearching();

    // Listen for Turbo/PJAX navigation events (GitHub's internal navigation)
    document.addEventListener('turbo:load', () => {
        console.log('[RL - Auto-Click Review] 🔄 Turbo navigation detected, restarting search...');
        startSearching();
    });

    // Fallback: Listen for URL changes using MutationObserver
    let lastUrl = location.href;
    new MutationObserver(() => {
        const url = location.href;
        if (url !== lastUrl) {
            lastUrl = url;
            console.log('[RL - Auto-Click Review] 🔄 URL changed, restarting search...');
            startSearching();
        }
    }).observe(document, { subtree: true, childList: true });

    console.log('[RL - Auto-Click Review] ✅ Script initialized with navigation listeners');
})();