Good process for publishing releases? I'm finding myself clicking publish hundreds of times a day

I'm curious how people go about publishing changes to apps they are using regularly. I have a dashboard that my team and I use which I'm constantly tinkering with, and it's a pain because every time I make a change I have to go through like a 5 click process of opening the release menu, creating a release, saying publish now, clicking ok, etc. Is this just how people do it? The only reason I use releases is to save my own work because sometimes changes get lost or overwritten so I wish Retool just tracked history automatically like google docs. Am I doing something wrong? Is there a better way?

1 Like

Same here

1 Like

Someone correct me if I am wrong, but it does track it automatically?

If you want your team to have the latest, can you share the link to the app with _releaseVersion=latest as seen here?

While drinking my coffee this morning...

I decided to tinker with a UserScript to maybe help your dilemma. (It bothers me too so lets do something!)

This seems to work in reducing the amount of steps. I didn't know what to pick for the hotkey, so you can change it to anything you want. Mousetrap docs here.

It's nothing more than automating a few clicks and then focusing the input box to type :slight_smile: If you need assistance installing userscripts, let me know, I'm happy to help.

// ==UserScript==
// @name         Retool - Release Automator
// @namespace    http://gofortuna.com
// @license      MIT
// @version      2024-09-01
// @description  Reduce the number of steps to release an app version with a hotkey.
// @author       Kevin Hill
// @match        https://*.retool.com/editor/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=retool.com
// @require      https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js
// @require      https://cdnjs.cloudflare.com/ajax/libs/mousetrap/1.6.5/mousetrap.min.js
// @grant        none
// ==/UserScript==
 
/* globals Mousetrap, $ */
(function() {
    'use strict';
 
    Mousetrap.bind(['command+/', 'ctrl+/'], async function(e) {
        const panel = $('[data-testid="ReleasesAndHistoryPanel::Container"]');
 
        const steps = [
            () => {
                if (panel && !panel.is(":visible")) {
                    $('[data-testid="ReleaseManagement::Launcher"]').parent("button").click();
                }
            },
            () => panel.find('button:contains("Create")').click(),
            () => $("#createRelease--trigger").click(),
            () => $('#createReleaseBox div[role="option"]').first().click(),
            () => $("#CreateRelease-description").focus()
        ];
 
        return runSteps(steps, 300);
    });
})();
 
async function runSteps(steps, delay) {
    for (const step of steps) {
        await step();
        await new Promise(resolve => setTimeout(resolve, delay));
    }
}
3 Likes

Cleaned up the code a little and posted it on GreasyFork.

1 Like

Thanks for your response, I mean technically it tracks in that you can "undo" things but I've found that functionality to be pretty unreliable. Seems like there's a 25% chance any time I undo that it won't fully undo or will make other unintended changes.

1 Like

Hi @Alex_Long, here is some context on what could be causing this issue: