Will automatically execute a pending Umbraco upgrade on startup without prompting the user.
Last active
November 1, 2018 10:28
-
-
Save tomvanenckevort/0d1de85a3ec9cc2e5b4b66ca4789df88 to your computer and use it in GitHub Desktop.
Automatic Umbraco upgrade module.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Web; | |
using Umbraco.Core; | |
using Codery.AutoUpgrade.Services; | |
namespace Codery.AutoUpgrade.App_Start | |
{ | |
public class ApplicationEvents : ApplicationEventHandler | |
{ | |
// make sure event handler gets registered when Umbraco hasn't been configured (i.e. pending an upgrade) | |
protected override bool ExecuteWhenApplicationNotConfigured => true; | |
protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) | |
{ | |
UmbracoApplicationBase.ApplicationInit += UmbracoApplicationBase_ApplicationInit; | |
} | |
private static void UmbracoApplicationBase_ApplicationInit(object sender, System.EventArgs e) | |
{ | |
if (sender is HttpApplication application) | |
{ | |
application.PostResolveRequestCache += Application_PostResolveRequestCache; | |
} | |
} | |
private static void Application_PostResolveRequestCache(object sender, System.EventArgs e) | |
{ | |
AutoUpgradeService.Upgrade(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Newtonsoft.Json; | |
using Newtonsoft.Json.Linq; | |
using System.Configuration; | |
using System.Linq; | |
using System.Web; | |
using System.Web.Http; | |
using Umbraco.Core; | |
using Umbraco.Core.Logging; | |
using Umbraco.Web.Install.Controllers; | |
using Umbraco.Web.Install.Models; | |
using Umbraco.Web.Security; | |
namespace Codery.AutoUpgrade.Services | |
{ | |
internal class AutoUpgradeService | |
{ | |
internal static void Upgrade() | |
{ | |
if (!IsEnabled || ApplicationContext.Current.IsConfigured) | |
{ | |
// automatic upgrades not enabled, or already configured | |
return; | |
} | |
if (!ApplicationContext.Current.DatabaseContext.IsDatabaseConfigured) | |
{ | |
// database hasn't been configured, so we can't do automatic upgrade | |
return; | |
} | |
if (upgradeAttemptFailed) | |
{ | |
// a previous upgrade attempt has failed, skip automatic upgrade for now to allow a manual upgrade instead | |
return; | |
} | |
using (var controller = new InstallApiController()) | |
{ | |
// get setup steps | |
var installSetup = controller.GetSetup(); | |
var instructions = new InstallInstructions() | |
{ | |
InstallId = installSetup.InstallId, | |
Instructions = installSetup.Steps.ToDictionary(k => k.Name, v => JToken.Parse(JsonConvert.SerializeObject(v.ViewModel))) | |
}; | |
// run each upgrade step until there are no more steps to run | |
bool hasNextStep = true; | |
while (hasNextStep) | |
{ | |
try | |
{ | |
var result = controller.PostPerformInstall(instructions); | |
if (string.IsNullOrEmpty(result.NextStep)) | |
{ | |
hasNextStep = false; | |
} | |
} | |
catch (HttpResponseException ex) | |
{ | |
LogHelper.Error<AutoUpgradeService>("Failed to complete automatic upgrade", ex); | |
upgradeAttemptFailed = true; | |
hasNextStep = false; | |
} | |
} | |
} | |
var security = new WebSecurity(new HttpContextWrapper(HttpContext.Current), ApplicationContext.Current); | |
if (security.IsAuthenticated() && security.GetUserId() == 0) | |
{ | |
// log out the admin user, since this might be from an automatic login during the upgrade | |
security.ClearCurrentLogin(); | |
} | |
var request = HttpContext.Current?.Request; | |
if (request?.Url == null) | |
{ | |
return; | |
} | |
// check if user was redirected to installation page | |
if (request.QueryString["redir"] == "true" && request.QueryString["url"] != null) | |
{ | |
// redirect user to initial page | |
HttpContext.Current?.Response.Redirect(request.QueryString["url"], true); | |
return; | |
} | |
// redirect to current page to force a reload | |
HttpContext.Current?.Response.Redirect(request.Url.ToString(), true); | |
} | |
private static bool upgradeAttemptFailed; | |
private static bool? isEnabled; | |
/// <summary> | |
/// Returns whether automatic upgrades have been enabled. | |
/// </summary> | |
private static bool IsEnabled | |
{ | |
get | |
{ | |
if (isEnabled == null) | |
{ | |
// read AutoUpgrade setting from web.config | |
isEnabled = ConfigurationManager.AppSettings["AutoUpgrade.Enabled"].InvariantEquals("true"); | |
} | |
return isEnabled.Value; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment