I did end up going with alert.js, btw - thanks again! Basically my button js looks like this, for reference of anyone else wanting something like this:
function btnRunAction(recordId) {
url = <our base url>;
//using action instead of workflow so we can piece together a combined return message about what's getting accomplished at each step
var action = "<name of action to run";
//forcing save first, on success show the alert and run the action
Xrm.Page.data.save().then(
function () {
Alert.show("Finalizing...", null, [], "LOADING", 400, 200, url, true);
Process.callAction(action,
[{
key: "Target",
type: Process.Type.EntityReference,
value: new Process.EntityReference(<entity>, recordId)
}],
function (params) {
var messageSuccess = "";
messageSuccess = params["successOutput"].replace(/\./g,'.<br/>');
Alert.show("Success", messageSuccess, null, "SUCCESS", 400, 200, url, true);
Xrm.Page.ui.close();
},
function (messageFail, trace) {
Alert.show("Error", messageFail, null, "ERROR", 400, 200, url, true);
Xrm.Page.ui.reload();
}, url);
},
function() {
//do nothing on save failure since CRM will give its own messaging about why the save failed
}
);
}