<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Thomas Morris</title>
    <description>The latest articles on Forem by Thomas Morris (@mozzydev).</description>
    <link>https://forem.com/mozzydev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F165338%2F853a9fba-dd2f-4958-b94a-f2d6f754b23d.jpeg</url>
      <title>Forem: Thomas Morris</title>
      <link>https://forem.com/mozzydev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/mozzydev"/>
    <language>en</language>
    <item>
      <title>Umbraco Codegarden 2023</title>
      <dc:creator>Thomas Morris</dc:creator>
      <pubDate>Tue, 01 Aug 2023 00:00:00 +0000</pubDate>
      <link>https://forem.com/mozzydev/umbraco-codegarden-2023-55b</link>
      <guid>https://forem.com/mozzydev/umbraco-codegarden-2023-55b</guid>
      <description>&lt;p&gt;I wrote an article for &lt;a href="https://www.tpximpact.com/" rel="noopener noreferrer"&gt;TPXimpact&lt;/a&gt; about my experience at Umbraco Codegarden 2023.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Recently, a couple of our team had the opportunity to attend the annual Umbraco conference known as &lt;a href="https://codegarden.umbraco.com/" rel="noopener noreferrer"&gt;Codegarden&lt;/a&gt;. Hosted in Odense, Denmark it pulls together 800+ in person to the event, but also a number of people were able to attend online as a hybrid experience.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Read in full here: &lt;a href="https://www.tpximpact.com/knowledge-hub/blogs/tech/umbraco-codegarden-2023/" rel="noopener noreferrer"&gt;Umbraco Codegarden 2023&lt;/a&gt;&lt;/p&gt;

</description>
      <category>umbraco</category>
      <category>codegarden</category>
    </item>
    <item>
      <title>Quick guide: upgrading Umbraco 9 to 10</title>
      <dc:creator>Thomas Morris</dc:creator>
      <pubDate>Fri, 04 Nov 2022 16:38:51 +0000</pubDate>
      <link>https://forem.com/mozzydev/quick-guide-upgrading-umbraco-9-to-10-8mp</link>
      <guid>https://forem.com/mozzydev/quick-guide-upgrading-umbraco-9-to-10-8mp</guid>
      <description>&lt;p&gt;Hey folks, here's a quick guide on how to upgrade Umbraco 9 up to version 10, with some extras around Umbraco Cloud. There's a few gotchas in there, so wanted to share some notes all in one place.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why
&lt;/h2&gt;

&lt;p&gt;First of all, the biggest reason for upgrading is to align with the Long Term Supported (LTS) version of Umbraco. i.e. if there is a version of Umbraco to upgrade to, then this is the one that's going to get support for a longer period of time.&lt;/p&gt;

&lt;p&gt;More details on that here: &lt;a href="https://umbraco.com/products/knowledge-center/long-term-support-and-end-of-life/" rel="noopener noreferrer"&gt;Umbraco LTS&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Outside of that, there are a few new handy updates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Improved cross-platform support, now using SQLite for development&lt;/li&gt;
&lt;li&gt;WebP support for optimised images&lt;/li&gt;
&lt;li&gt;User permissions based on languages&lt;/li&gt;
&lt;li&gt;Read only mode for properties&lt;/li&gt;
&lt;li&gt;&lt;a href="https://our.umbraco.com/documentation/Fundamentals/Setup/Server-Setup/runtime-modes?_ga=2.242434690.1001545183.1667578030-912889740.1667578030" rel="noopener noreferrer"&gt;Runtime modes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Updated dependencies&lt;/li&gt;
&lt;li&gt;Improved performance&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How
&lt;/h2&gt;

&lt;p&gt;Umbraco provide a really handy series of steps in their &lt;a href="https://our.umbraco.com/documentation/Fundamentals/Setup/Upgrading/version-specific#version-9-to-version-10" rel="noopener noreferrer"&gt;docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Check the link for full details, but here's a short summary:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Take some backups!&lt;/li&gt;
&lt;li&gt;Update to .NET 6&lt;/li&gt;
&lt;li&gt;Update &lt;code&gt;{ProjectName}.csproj&lt;/code&gt; to enable implicit usings and &lt;a href="https://our.umbraco.com/Documentation/Implementation/Nullable-Reference-Types/" rel="noopener noreferrer"&gt;nullable reference types&lt;/a&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;PropertyGroup&amp;gt;
    &amp;lt;TargetFramework&amp;gt;net6.0&amp;lt;/TargetFramework&amp;gt;
    &amp;lt;ImplicitUsings&amp;gt;enable&amp;lt;/ImplicitUsings&amp;gt;
    &amp;lt;Nullable&amp;gt;enable&amp;lt;/Nullable&amp;gt;
&amp;lt;/PropertyGroup&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Upgrade package references, the Umbraco HQ packages are now using &lt;code&gt;10.x.x&lt;/code&gt;. Check any other dependencies if you have them added, e.g. &lt;a href="https://github.com/leekelleher/umbraco-contentment" rel="noopener noreferrer"&gt;Contentment&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Update &lt;code&gt;Program.cs&lt;/code&gt; with the following:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class Program
{
    public static void Main(string[] args)
        =&amp;gt; CreateHostBuilder(args)
            .Build()
            .Run();

    public static IHostBuilder CreateHostBuilder(string[] args) =&amp;gt;
        Host.CreateDefaultBuilder(args)
            .ConfigureUmbracoDefaults()
            .ConfigureWebHostDefaults(webBuilder =&amp;gt;
            {
                webBuilder.UseStaticWebAssets();
                webBuilder.UseStartup&amp;lt;Startup&amp;gt;();
            });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Remove the following files/folders used by Umbraco:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/wwwroot/umbraco
/umbraco/PartialViewMacros
/umbraco/UmbracoBackOffice
/umbraco/UmbracoInstall
/umbraco/UmbracoWebsite
/umbraco/config/lang
/umbraco/config/appsettings-schema.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Remove the following files/folders used by Umbraco Forms:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/App_Plugins/UmbracoForms
/Views/MacroPartials/InsertUmbracoFormWithTheme.cshtml
/Views/MacroPartials/RenderUmbracoFormScripts.cshtml
/Views/Partials/Forms/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;To re-enable the appsettings IntelliSense, update your &lt;code&gt;appsettings.json&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"$schema": "./appsettings-schema.json",
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Commit your changes and get ready to deploy!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note, if using Umbraco Cloud, you'll also need to delete the files/folders through KUDU from both the &lt;code&gt;repository&lt;/code&gt; and &lt;code&gt;wwwroot&lt;/code&gt; folders before pushing the upgrade changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://our.umbraco.com/documentation/Umbraco-Cloud/Upgrades/Upgrading-from-9-to-10/" rel="noopener noreferrer"&gt;Umbraco Cloud upgrade notes&lt;/a&gt;&lt;br&gt;
&lt;a href="https://our.umbraco.com/documentation/Add-ons/UmbracoForms/Installation/Version-Specific#version-10" rel="noopener noreferrer"&gt;Umbraco Forms upgrade notes&lt;/a&gt;&lt;br&gt;
&lt;a href="https://our.umbraco.com/documentation/Add-ons/Umbraco-Deploy/Upgrades/version-specific#version-10" rel="noopener noreferrer"&gt;Umbraco Deploy upgrade notes&lt;/a&gt;&lt;/p&gt;

</description>
      <category>umbraco</category>
    </item>
    <item>
      <title>Breaking down Umbraco</title>
      <dc:creator>Thomas Morris</dc:creator>
      <pubDate>Tue, 16 Mar 2021 00:00:00 +0000</pubDate>
      <link>https://forem.com/mozzydev/breaking-down-umbraco-13l7</link>
      <guid>https://forem.com/mozzydev/breaking-down-umbraco-13l7</guid>
      <description>&lt;p&gt;I wrote an article for &lt;a href="https://www.tpximpact.com/" rel="noopener noreferrer"&gt;TPXimpact&lt;/a&gt; about why you might choose Umbraco for a project.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Umbraco’s benefits are many. Using technologies we’re already familiar with, the CMS allows our solutions to achieve a breadth of functionality and remain malleable post production.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Read in full here: &lt;a href="https://www.tpximpact.com/knowledge-hub/insights/breaking-down-umbraco/" rel="noopener noreferrer"&gt;Breaking down Umbraco&lt;/a&gt;&lt;/p&gt;

</description>
      <category>umbraco</category>
    </item>
    <item>
      <title>GitHub Actions: an intro</title>
      <dc:creator>Thomas Morris</dc:creator>
      <pubDate>Wed, 19 Aug 2020 00:00:00 +0000</pubDate>
      <link>https://forem.com/mozzydev/github-actions-an-intro-3oa1</link>
      <guid>https://forem.com/mozzydev/github-actions-an-intro-3oa1</guid>
      <description>&lt;p&gt;There are quite a few build and deploy options available to developers these days. Previously, I have wrote about using a combination of &lt;a href="http://mozzy.dev/posts/continuous-delivery-for-dotnet-revisited/" rel="noopener noreferrer"&gt;Team City and Octopus Deploy&lt;/a&gt;. These are still good tools, but will likely require a bit of setup and probably require a VM.&lt;/p&gt;

&lt;p&gt;A more recent trend is to have your actions linked to your repository, where you can have it all self contained and in one place. There are pros and cons to both, but I'm gonna show you how you might do that with GitHub Actions.&lt;/p&gt;

&lt;h2&gt;
  
  
  dotnet
&lt;/h2&gt;

&lt;p&gt;I work mostly with .NET, so lets take a look at the workflow for that. With .NET Core you can now use Linux (and macOS) as your build target. Here we're using &lt;code&gt;ubuntu-latest&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We're also setting the relevant &lt;code&gt;DOTNET_VERSION&lt;/code&gt; and running our commands, &lt;code&gt;dotnet build&lt;/code&gt; and &lt;code&gt;dotnet publish&lt;/code&gt;. Problems with the build will be visible within GitHub and you can follow along with the progress.&lt;/p&gt;

&lt;p&gt;Finally, we're pushing our published version of the app to Azure Web Apps using a publish profile. You could also choose to generate a NuGet package and push to a feed for distribution.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Note, you can also build &lt;a href="https://github.com/Azure-Samples/dotnet-sample/blob/master/.github/workflows/aspnet.yml" rel="noopener noreferrer"&gt;.NET Framework apps&lt;/a&gt;, that will look a little different but the concept is the same. You'll target &lt;code&gt;windows-latest&lt;/code&gt; as that is a prerequisite for .NET Framework, and the commands will be &lt;code&gt;msbuild&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  node.js
&lt;/h2&gt;

&lt;p&gt;If you've got a FE repo, then you'll likely want to use npm to compile some assets and package them up. Here's how you can do that.&lt;/p&gt;

&lt;p&gt;We've set up our &lt;code&gt;NODE_VERSION&lt;/code&gt; and then run the commands, &lt;code&gt;npm install&lt;/code&gt; and &lt;code&gt;npm build&lt;/code&gt;. At that point, we might want to package up the assets or deploy as an application.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  other
&lt;/h2&gt;

&lt;p&gt;There are lots of other options available to you, without going into all of them here, I encourage you to take a look through the &lt;a href="https://docs.github.com/en/actions/language-and-framework-guides" rel="noopener noreferrer"&gt;docs&lt;/a&gt; and see what you might want for your needs.&lt;/p&gt;

&lt;p&gt;If you're interested in what's installed on the runners, then take a look at &lt;a href="https://github.com/actions/virtual-environments" rel="noopener noreferrer"&gt;this repo&lt;/a&gt; which contains the full list of software and spec for each.&lt;/p&gt;

&lt;p&gt;The approach here can also be used for similar tools such as &lt;a href="https://bitbucket.org/product/features/pipelines" rel="noopener noreferrer"&gt;Bitbucket Pipelines&lt;/a&gt; or &lt;a href="https://azure.microsoft.com/en-us/services/devops/pipelines/" rel="noopener noreferrer"&gt;Azure Pipelines&lt;/a&gt;. Choose what fits the bill for you.&lt;/p&gt;

&lt;p&gt;Have fun!&lt;/p&gt;

</description>
      <category>github</category>
    </item>
    <item>
      <title>Building a bottle shop</title>
      <dc:creator>Thomas Morris</dc:creator>
      <pubDate>Mon, 10 Aug 2020 00:00:00 +0000</pubDate>
      <link>https://forem.com/mozzydev/building-a-bottle-shop-3bep</link>
      <guid>https://forem.com/mozzydev/building-a-bottle-shop-3bep</guid>
      <description>&lt;p&gt;One of the things that is important to an ecommerce experience is the speed at which you can make informed decisions and place items in your cart. From there, the next phase will be to checkout and proceed with the order. Typically, this is classed as a conversion and you want as many as possible. You might do various tests to achieve that end goal and nudge the customer along that path.&lt;/p&gt;

&lt;p&gt;What if you were open to the idea of not pushing the customer to checkout immediately and provide them time to make their choices, even over a few weeks. This was a concept that we played with at &lt;a href="https://beerbods.co.uk/" rel="noopener noreferrer"&gt;BeerBods&lt;/a&gt;, centred around a reservation of beer, to build a case of beers you pick in your own time. The experience itself is more about exploration and finding the beer you want.&lt;/p&gt;

&lt;p&gt;Not only does that shift the UX in a slightly different direction, it also has some technical challenges. Namely, how do you reserve a beer, how is this stock controlled and how do I come back to my continue with my purchase.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pX379ZqA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://mozzy.dev/images/buildacase-concept.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pX379ZqA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://mozzy.dev/images/buildacase-concept.jpg" title="Build a Case - concept" width="800" height="591"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing Umbraco
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://umbraco.com/" rel="noopener noreferrer"&gt;Umbraco&lt;/a&gt; as a CMS allows for a lot of variation in terms of document types and property editors. Essentially, you can build a custom editing interface relatively easily to manage your content. In my case, I wanted to add products to Umbraco and have these editable by anyone in the team. There was no data warehouse, so adding directly into Umbraco was ok in this scenario. I was able to define the required information and set up some basic stock control with SKUs and pricing. Since we were already using Umbraco, it was comfortable to use on this front.&lt;/p&gt;

&lt;p&gt;The product pages themselves can be rendered using traditional patterns and templates. The more interesting part came when adding the functionality to add a beer to your case.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enter VueJS and Algolia
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://vuejs.org/" rel="noopener noreferrer"&gt;VueJS&lt;/a&gt; is a javascript framework that allows for building SPA (single page applications) like functionality, introducing more dynamic and responsive user interfaces. It can be added with relative ease to an existing website, which made it a good option for building our 'shop' front. VueJS would be responsible for rendering components, handling FE state and making calls to our API.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.algolia.com/" rel="noopener noreferrer"&gt;Algolia&lt;/a&gt; is a search platform that has a number of pre-built components to integrate with it's service. There was one of particular interest that near enough provided the basis for our &lt;a href="https://www.algolia.com/doc/guides/building-search-ui/widgets/showcase/vue/" rel="noopener noreferrer"&gt;'shop'&lt;/a&gt; and the required functionality. This included a list of results, options to filter, sort and search. The idea of adding this kind of service had a number of benefits, it was quick to get started and by having an external service handling search powered by a CDN, it was very responsive to customers. We could push data to the service (whenever a product was updated) and query the results wherever we needed.&lt;/p&gt;

&lt;p&gt;Combined, we were able to build a UI that was quick to load, easy to filter and visually interesting with a lot of customisation options. All of the API calls would be triggered from the FE and the state would update our UI to present back to the user.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding Fluidity
&lt;/h2&gt;

&lt;p&gt;So, we've got our products and our UI for the front end. We now need to persist changes and provide a stateful system for the current user. This was done by implementing custom database tables and an API to enable adding items, removing items and saving these items for a later date.&lt;/p&gt;

&lt;p&gt;These custom database tables can be exposed in our Umbraco instance by using a package called &lt;a href="https://github.com/mattbrailsford/umbraco-fluidity/" rel="noopener noreferrer"&gt;Fluidity&lt;/a&gt;. It provides a CRUD like experience for the editors so that we can see what's being added and when, as well as allowing us to add beers on the behalf of a customer.&lt;/p&gt;

&lt;p&gt;It's important to note that the idea of persistance is 2-fold, once when we are on the FE and we need to ensure state between sessions and also on the BE, where we need to actually store the data and reserve the beer. This distinction means that we don't get people adding multiple beers filling up stock until they commit to saving that data. At which point we've got their details and can follow up if necessary.&lt;/p&gt;

&lt;p&gt;When it comes to purchase or if the customer comes back to their choices, we can load these from the API and allow the customer to proceed. The items can be locked in and an order can be made just like any other checkout, allowing the next stage of fulfilment in the warehouse.&lt;/p&gt;

&lt;p&gt;If the customer didn't come back (which did happen), then we'd prompt them to finish their case via email. If after the 30 days they hadn't made a purchase, then we would need to remove their reservation and put the beers back into the shop for other customers. This was done by using &lt;a href="https://www.hangfire.io/" rel="noopener noreferrer"&gt;Hangfire&lt;/a&gt;, a tool for running background tasks at desired times.&lt;/p&gt;

&lt;h2&gt;
  
  
  The result
&lt;/h2&gt;

&lt;p&gt;What we were looking for was a responsive, easy to use 'shop' front for customers to pick beer and save until they were ready to make a purchase. We needed the ability to add beers to our shop and view details about what was in progress or had been ordered. By using a combination of Umbraco on the back end, and VueJS / Algolia on the front end, the result turned out how we wanted it to and we saw great customer interaction.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: This functionality is no longer live and BeerBods subsequently joined Beer Hawk, another online beer company.&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Enabling features in production</title>
      <dc:creator>Thomas Morris</dc:creator>
      <pubDate>Wed, 18 Dec 2019 00:00:00 +0000</pubDate>
      <link>https://forem.com/mozzydev/enabling-features-in-production-11ii</link>
      <guid>https://forem.com/mozzydev/enabling-features-in-production-11ii</guid>
      <description>&lt;p&gt;When deploying features or new changes to our websites, we might not want them to be available to all users at once. It would be nice if we could slowly introduce new features to our users. We might even want to completely disable them and have them there in secret. In this article, I'm going to present a few different ways in which you can release features into production, even when they might not be fully complete.&lt;/p&gt;

&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;Before we look into the ways in which we can get our features into production, it's useful to think about how we might have typically developed new changes in our website before a release.&lt;/p&gt;

&lt;p&gt;One of the most common ways is to use feature branches in a &lt;a href="https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow" rel="noopener noreferrer"&gt;gitflow scenario&lt;/a&gt;, where you would build your new feature, deploy to a test environment and then try and merge those changes with anything else that has changed in the meantime. You'll probably bundle a number of changes together and then release those to production.&lt;/p&gt;

&lt;p&gt;Some of the issues at this stage might be that you've got a tricky merge, you've tested something in isolation and when you bring it all together other issues might arise. You also haven't really trialled those changes with actual users, so those changes may not be desired or there could be problems with how it all works.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits and options
&lt;/h2&gt;

&lt;p&gt;Therefore, it's probably a good idea to highlight some of the benefits as to why you might want to integrate your new changes sooner rather than later.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;your features get into production quicker&lt;/li&gt;
&lt;li&gt;you can get feedback earlier&lt;/li&gt;
&lt;li&gt;you can test things in reduced quantities&lt;/li&gt;
&lt;li&gt;you should end up with a better product&lt;/li&gt;
&lt;li&gt;your client will be happy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You might have seen reasons like this elsewhere, and that's because they actually run true for agile development and the scrum process, which in turn is a good fit for &lt;a href="https://continuousdelivery.com/" rel="noopener noreferrer"&gt;continuous delivery&lt;/a&gt;. A notion that your app is always in a deliverable state, since any new changes have been safely integrated somehow.&lt;/p&gt;

&lt;p&gt;On to the ways in which we can enable our changes...&lt;/p&gt;

&lt;h3&gt;
  
  
  App settings
&lt;/h3&gt;

&lt;p&gt;One of the easiest ways is to define in your web.config, application settings somewhere, or provide settings in your Umbraco solution to features on and off. You'll need to check this setting within your code before including the new changes for your users.&lt;/p&gt;

&lt;p&gt;This can be done with a feature helper, which you can query the app setting and then return a true or false as to whether the new changes should be included or not.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public static class FeatureHelper
{
    public static bool IsFeatureEnabled(string featureFlag)
    {
        // check if we have enabled functionality via web.config
        bool.TryParse(ConfigurationManager.AppSettings.Get(featureFlag), out var setting);
        return setting;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you'd like to turn off entire controllers or action methods, one of the ways in which you can do that is via the use of &lt;a href="https://docs.microsoft.com/en-us/aspnet/mvc/overview/older-versions-1/controllers-and-routing/understanding-action-filters-cs" rel="noopener noreferrer"&gt;attributes&lt;/a&gt;. These will decorate your actions and apply the filter before any of the other code is run. In the attribute logic, it will call our feature helper to determine whether or not a feature should be applied.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class FeatureAttribute : ActionFilterAttribute
{
    public string ConfigVariable { get; set; }        

    public FeatureAttribute(string configVariable)
    {
        ConfigVariable = configVariable;        
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        // if the feature is not enabled, then redirect to 404
        if (!FeatureHelper.IsFeatureEnabled(ConfigVariable))
        {
            filterContext.HttpContext.Response.Redirect("/404/");
        }
        else
        {
            base.OnActionExecuting(filterContext);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows for features to be controlled relatively easy in terms of when it is available, but it's an all or nothing solution which might not be desired when you want to tentatively introduce customers to your new feature.&lt;/p&gt;

&lt;h3&gt;
  
  
  Session
&lt;/h3&gt;

&lt;p&gt;We can apply changes based on a user's session data, which could be enabled via a campaign to help with testing. Ask for people to click a link and become part of the session. You can then trigger an update that will kill off any session data if there are issues. The code above that we used for checking app setting can be amended to apply with session data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public static class FeatureHelper
{
    public static bool IsFeatureEnabled(string sessionFlag)
    {
        // check if we have a valid session to enable functionality
        var sessionVar = HttpContext.Current?.Session[sessionFlag];
        if (sessionVar == null)
        {
            return false;
        }

        return bool.Parse(sessionVar.ToString());
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is great for ad hoc testing, as everything can return to normal after the session. This is ideal if you don't have an account system set up, but it is helpful if you can target or segment your users if you have a hypothesis you want to test.&lt;/p&gt;

&lt;p&gt;A/B testing would be a good scenario here. One set of users could get the feature enabled and the other set could continue as normal to see if anything is improved if your feature relates to performance or conversions. It's important that you can define what improvement looks like or can at least get some feedback from your users.&lt;/p&gt;

&lt;h3&gt;
  
  
  User preference
&lt;/h3&gt;

&lt;p&gt;If you do have an account section, you could provide the user the choice as to whether they want to opt in to a newly released feature that you might want to test further before enabling for all. You would need to check against the current logged in user as to whether or not they would like to see those changes.&lt;/p&gt;

&lt;p&gt;In Umbraco, you could define this as a member property or &lt;a href="https://our.umbraco.com/Documentation/Getting-Started/Data/Members/#creating-member-groups" rel="noopener noreferrer"&gt;membership group&lt;/a&gt; so you can see within the backoffice which users have enabled your feature and segment your users that way. If your changes are more granular, then using properties is probably preferred.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Just to note, for members in Umbraco there is the concept of role based access, which is tied with membership groups, so could be an option if you wanted to hook in that way instead. This uses .NET authorisation under the hood.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oUCwMgzK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://mozzy.dev/images/umbraco-membership-features.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oUCwMgzK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://mozzy.dev/images/umbraco-membership-features.png" title="Image with list of features that can be enabled for an Umbraco member" alt="Umbraco member properties" width="800" height="381"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This puts the control on to your users, and they are more likely to be actively engaged with a feature and also understand that there may be issues. If they're not happy with how it works, then they can easily opt back out and carry on as normal. Within your website, you can provide an option for feedback based on whether a new feature has been turned on. They can submit reports and you can gain some quality insight as to how your users are actually using your changes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Deployment slots
&lt;/h3&gt;

&lt;p&gt;If you're doing your deployments via Azure App Services, then another option at your dispense, is to use &lt;a href="https://docs.microsoft.com/en-us/azure/app-service/deploy-staging-slots#route-traffic" rel="noopener noreferrer"&gt;deployment slots&lt;/a&gt;. The main use case for this is to run a staging slot alongside your live slot, and to swap them when doing a deployment to ensure that you've tested your changes, warmed up your site beforehand and traffic is switched over without downtime.&lt;/p&gt;

&lt;p&gt;There is another benefit to it though, in that it can allow you to drive traffic to either slot based on a percentage. That way you can test with 20% of users before rolling out to the other 80% and this is managed through deployment. You can do similar with traffic manager or other load balancing rules.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8UKf6Ahn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://mozzy.dev/images/deploymentslots-routetraffic.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8UKf6Ahn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://mozzy.dev/images/deploymentslots-routetraffic.png" title="Image showing the options for routing in Azure deployment slots" alt="Azure deployment slots" width="613" height="254"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With this option, it's even more important that you can provide suitable metrics and logs to determine how your new changes are performing. Without reasonable guidance, you're in the dark as to whether or not it's a good idea to roll out.&lt;/p&gt;

&lt;h3&gt;
  
  
  Features as a service
&lt;/h3&gt;

&lt;p&gt;With the rise of microservices, why not make use of a service that can handle our features? One of those services is &lt;a href="https://launchdarkly.com/" rel="noopener noreferrer"&gt;LaunchDarkly&lt;/a&gt;, which provides a dashboard for your features and has a number of libraries (inc. JS and .NET) that you can integrate with. As a solution, it'll allow you to get a full feature management tool pretty quickly, and one that should provide plenty of options albeit at a price. Useful to consider, and there may well be others out there. The concepts should still be the same as we've outlined in this article.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[Update]&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Since originally writing this article, another option which I've found is the &lt;a href="https://github.com/microsoft/FeatureManagement-Dotnet" rel="noopener noreferrer"&gt;.NET Feature Management&lt;/a&gt; library. This is built on top of the .NET configuration system and provides a nice set of APIs for using in your applications. It looks like a great option. Here's a &lt;a href="https://docs.microsoft.com/en-us/azure/azure-app-configuration/quickstart-feature-flag-dotnet" rel="noopener noreferrer"&gt;quick start guide&lt;/a&gt; to set up with Azure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Testing features in production is a big part of continuous improvement and ties in well with the continuous development way of doing things. You can deliver changes quicker and have greater confidence in when a feature is enabled for all. Ideally, you can ramp up usage in a controlled manner.&lt;/p&gt;

&lt;p&gt;You can gain feedback on your changes from real users and scenarios, which may in turn provide much greater insight as to how something works. The end goal being that your changes have been well integrated and are of better quality overall.&lt;/p&gt;

</description>
      <category>umbraco</category>
      <category>deployments</category>
    </item>
    <item>
      <title>App offline strategies for your website</title>
      <dc:creator>Thomas Morris</dc:creator>
      <pubDate>Tue, 09 Oct 2018 00:00:00 +0000</pubDate>
      <link>https://forem.com/mozzydev/app-offline-strategies-for-your-website-faf</link>
      <guid>https://forem.com/mozzydev/app-offline-strategies-for-your-website-faf</guid>
      <description>&lt;p&gt;It's undesirable, but sometimes you'll be in a scenario where you may need to take your sife offline for maintenance. This could be an upgrade to your CMS of choice (e.g. &lt;a href="https://umbraco.com/" rel="noopener noreferrer"&gt;Umbraco&lt;/a&gt;), processing of changes behind the scenes or simply restricting users at high traffic.&lt;/p&gt;

&lt;h3&gt;
  
  
  app_offline.htm
&lt;/h3&gt;

&lt;p&gt;The simplest way to do this is to place an &lt;a href="https://docs.microsoft.com/en-gb/iis/publish/deploying-application-packages/taking-an-application-offline-before-publishing" rel="noopener noreferrer"&gt;app_offline.htm&lt;/a&gt; file in the root directory of the website. This will instruct .NET to route all traffic to that file and show this to the user. It'll need to be simple html and you'll need to inline any CSS that you want applied.&lt;/p&gt;

&lt;p&gt;This is great if you want to restrict traffic altogether, but if you want to do stuff in the background then you are a bit stuck.&lt;/p&gt;

&lt;h3&gt;
  
  
  IIS Rewrite
&lt;/h3&gt;

&lt;p&gt;So, one way in which you can get around that is by using a rewrite rule which negates a certain IP. This will allow whoever visits your site via the IP added, to browse the website without obstruction. Anyone else, will get served the offline file. Below is an example transform that you can use to achieve that.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;rule name="App-offline" stopProcessing="true" enabled="true" xdt:Transform="InsertIfMissing" xdt:Locator="Match(name)"&amp;gt;
    &amp;lt;match url="^(.*)$" ignoreCase="false"/&amp;gt;
    &amp;lt;conditions logicalGrouping="MatchAll"&amp;gt;
        &amp;lt;add input="{URL}" pattern="/offline.htm$" ignoreCase="false" negate="true"/&amp;gt;
        &amp;lt;add input="{REMOTE_ADDR}" pattern="^127.0.0.1$" ignoreCase="false" negate="true"/&amp;gt;            
    &amp;lt;/conditions&amp;gt;
    &amp;lt;action type="Redirect" url="/offline.htm" redirectType="Found"/&amp;gt;
&amp;lt;/rule&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Maintenance manager
&lt;/h3&gt;

&lt;p&gt;Perhaps you don't have a specific IP you want to allow and are interested in being able to turn this off and on. Well, the good news is if you are using Umbraco, then Kevin Jump has created a package for that. It's called maintenance mode for Umbraco. You can login to Umbraco and then you'll be given the option to apply the restriction to everyone, as well enabling access for back office users if you wish.&lt;/p&gt;

&lt;p&gt;You can download that here: &lt;a href="https://our.umbraco.com/packages/backoffice-extensions/maintenance-manager/" rel="noopener noreferrer"&gt;https://our.umbraco.com/packages/backoffice-extensions/maintenance-manager/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Limited downtime?
&lt;/h3&gt;

&lt;p&gt;There's a few ways to achieve this. One of the most common being &lt;a href="https://octopus.com/docs/deployment-patterns/blue-green-deployments" rel="noopener noreferrer"&gt;blue-green deployments&lt;/a&gt; where you alternate between active and inactive versions of the website, resulting in one being live and the other being updated and switched to. Usually this will require some kind of load balancer although with deployment slots in Azure you can achieve a similar thing.&lt;/p&gt;

&lt;p&gt;You could use tooling such as &lt;a href="https://octopus.com/" rel="noopener noreferrer"&gt;Octopus Deploy&lt;/a&gt; to set up a variety of deployment strategies, with the ability to run custom scripts and actions throughout the deployment. You can also configure a deployment to run at scheduled times (e.g. 2am where there is expected to be little traffic).&lt;/p&gt;

</description>
      <category>offline</category>
      <category>umbraco</category>
    </item>
    <item>
      <title>Using Models Builder in an Umbraco project</title>
      <dc:creator>Thomas Morris</dc:creator>
      <pubDate>Sun, 03 Jun 2018 00:00:00 +0000</pubDate>
      <link>https://forem.com/mozzydev/using-models-builder-in-an-umbraco-project-2pp4</link>
      <guid>https://forem.com/mozzydev/using-models-builder-in-an-umbraco-project-2pp4</guid>
      <description>&lt;p&gt;A while back I gave &lt;a href="https://mozzy.dev/posts/getting-started-with-models-builder/" rel="noopener noreferrer"&gt;an overview&lt;/a&gt; of the different options that Models Builder provides you. I didn't go into a lot of detail, but I did cover why you might want to use one option over another.&lt;/p&gt;

&lt;h3&gt;
  
  
  Structure
&lt;/h3&gt;

&lt;p&gt;Fast forward a little, and I think I've reached an approach that I'm happy with and allows me to build things in a way I want without adding extra complication. I'm more familiar with an MVC type scenario and so here's the kind of solution I normally end up with for Umbraco projects.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Project.Web.Core - class library&lt;/li&gt;
&lt;li&gt;Project.Web.UI - website project (reference to the above)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There will likely be some other projects in there as well, e.g. tests.&lt;/p&gt;

&lt;p&gt;I would typically place my models within the Core project and then utilise these within the views of the UI project. To do that, there are some configuration options to instruct Models Builder as to how to create models.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;add key="Umbraco.ModelsBuilder.Enable" value="true" /&amp;gt;
&amp;lt;add key="Umbraco.ModelsBuilder.ModelsMode" value="AppData" /&amp;gt;
&amp;lt;add key="Umbraco.ModelsBuilder.ModelsNamespace" value="Project.Web.Core.Models.Content" /&amp;gt;
&amp;lt;add key="Umbraco.ModelsBuilder.ModelsDirectory" value="~/../Project.Web.Core/Models/Content/" /&amp;gt;
&amp;lt;add key="Umbraco.ModelsBuilder.AcceptUnsafeModelsDirectory" value="true" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above will place the models generated by Models Builder into my Project.Web.Core project, so that I can then use them how I wish. Include them in the project and do a build, and they will be included in the project dll.&lt;/p&gt;

&lt;p&gt;The good thing about this is if you already have a project that was using &lt;code&gt;Model.Content.GetPropertyValue("propertyAlias")&lt;/code&gt; it's not too difficult to change them over to strongly typed models. Models Builder itself is essentially doing all that for you. If you're starting fresh on a project, then there a few other options for your model/mapping needs. None of the below generate models, so are quite different in usage to Models Builder. They do offer more complex scenarios in terms of mapping and granular view models, and may be something you prefer.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/AndyButland/UmbracoMapper" rel="noopener noreferrer"&gt;Umbraco Mapper&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/JimBobSquarePants/UmbMapper" rel="noopener noreferrer"&gt;UmbMapper&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/umco/umbraco-ditto" rel="noopener noreferrer"&gt;Ditto&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Using the models
&lt;/h3&gt;

&lt;p&gt;I've now got a bunch of files that provide me with the generated models from Umbraco. These are content models and they all inherit from &lt;code&gt;PublishedContentModel&lt;/code&gt;. They are partial classes. When it comes to using these models, it might be instantiated via a controller or it might just be there for me via Umbraco's routing.&lt;/p&gt;

&lt;p&gt;In a view, this is what we can do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@inherits UmbracoViewPage&amp;lt;MyModel&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, within the view there will be intellisense and I will be notified of compilation errors. A nice benefit of using strongly typed models. Since we made use of &lt;code&gt;UmbracoViewPage&lt;/code&gt; we also get access to all the Umbraco helper methods.&lt;/p&gt;

&lt;p&gt;Ok, that sounds great. But, there's something a little iffy with using a model that Umbraco generated for me and is closely tied with the content in Umbraco. What if I wanted to extend this or have my own properties? Well, there's a solution for that. The official docs suggest that we create another partial class and add what we need there, but I think I prefer this method. We can just inherit from the model that Models Builder gave us.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class FridayBeersViewModel : FridayBeers
{ 
  public FridayBeersViewModel(IPublishedContent content) 
    : base(content) { } 

  // custom properties 
  public bool ShowBanner =&amp;gt; BannerImage != null;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We've still got all the properties from the generated model and we can also build up a custom view model, which more closely matches the output in our views. As a side note, if you're view model ends up with little relation to the generated model then you probably shouldn't be inheriting from it and can just roll your own.&lt;/p&gt;

&lt;p&gt;In the controller, you would then have something like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class FridayBeersController : BasePageController
{ 
  public ActionResult FridayBeers() 
  { 
    var model = new FridayBeersViewModel(CurrentPage); 
    // apply any other updates on the model 
    return CurrentTemplate(model); 
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I'm hijacking the route so that I can amend the default behaviour of Umbraco. I'm also making use of the template based routing in Umbraco, where the template name matches my action. &lt;code&gt;BasePageController&lt;/code&gt; just inherits from &lt;code&gt;SurfaceController&lt;/code&gt; and &lt;code&gt;IRenderMvcController&lt;/code&gt;, and has a method called &lt;code&gt;CurrentTemplate&lt;/code&gt; that resolves the template and passes the model to the view. Here's the example in Umbraco core: &lt;a href="https://github.com/umbraco/Umbraco-CMS/blob/7ee510ed386495120666a78c61497f58ff05de8f/src/Umbraco.Web/Mvc/RenderMvcController.cs#L96" rel="noopener noreferrer"&gt;view on github&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Compositions
&lt;/h3&gt;

&lt;p&gt;The above example would work well for a page or a block of content, but we might want to break things up a little more and make better use of sharing code. When we use compositions, what we get from a generated sense is an interface and then our content models implement those properties. They can also make use of many compositions. This is great, because it means we can then define the interface as the model within a view if we want to. For example, if we had a interface such as IMetaData we can create a related partial that handles the meta tags on our site.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@inherits UmbracoViewPage&amp;lt;IMetaData&amp;gt; 
&amp;lt;meta name="description" content="@Model.MetaDescription" /&amp;gt;
// etc.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or we might have a couple of pages that have a banner, and a few without. We just let our doc types use the compositions and they know how to render the banner.&lt;/p&gt;

&lt;h3&gt;
  
  
  ModelTypeAlias
&lt;/h3&gt;

&lt;p&gt;I'm sure at one point during development of an Umbraco website you would have created a class with some constants in them, relating to the alias of the doc type. An easy way to vary your code depending on the doc type. Well, Models Builder provides this in a straightforward way.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public partial class ExamplePage : PublishedContentModel
{ 
  public new const string ModelTypeAlias = "ExamplePage"; 
  public new const PublishedItemType ModelItemType = PublishedItemType.Content; 

  public BasePage(IPublishedContent content) 
    : base(content) { } 

  // other properties
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To use this, just do &lt;code&gt;ExamplePage.ModelTypeAlias&lt;/code&gt; when you need it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;I've outlined a few ways in which you can use Models Builder on a project above perhaps what you get out of the box, so that you can get the most out of it in a simple manner. As a pattern, this should allow for easy extensibility and a quick way of consuming the content from Umbraco.&lt;/p&gt;

&lt;h4&gt;
  
  
  Further reading
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://our.umbraco.org/documentation/Reference/Templating/Modelsbuilder/Builder-Modes" rel="noopener noreferrer"&gt;Builder-Modes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://our.umbraco.org/documentation/Reference/Templating/Modelsbuilder/Understand-And-Extend" rel="noopener noreferrer"&gt;Understand-And-Extend&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://our.umbraco.org/documentation/Reference/Routing/custom-controllers" rel="noopener noreferrer"&gt;Routing/custom-controllers&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>umbraco</category>
    </item>
    <item>
      <title>Upgrading Umbraco</title>
      <dc:creator>Thomas Morris</dc:creator>
      <pubDate>Tue, 17 May 2016 00:00:00 +0000</pubDate>
      <link>https://forem.com/mozzydev/upgrading-umbraco-4bgo</link>
      <guid>https://forem.com/mozzydev/upgrading-umbraco-4bgo</guid>
      <description>&lt;p&gt;During a recent project, I was tasked with upgrading a site from v4 of Umbraco to the latest and greatest. There are a few reasons for this and it doesn't come without it's challenges, but I think the end result is definitely worth it.&lt;/p&gt;

&lt;p&gt;&lt;br&gt;
Note: For reference, I am talking mainly around upgrading an existing implementation of Umbraco and not migrating to another instance. Also, specifically around major releases, since patch updates rarely cause any issues and where possible you should always keep up to date if you can.&lt;br&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Upgrade?
&lt;/h3&gt;

&lt;p&gt;Well, who wouldn't want to make use of the updated UI and far improved underlying architecture of Umbraco. There are many things which the HQ team (and others within the community) have been working on and a lot can change in a relatively short time in the tech world.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Complete redesign&lt;/li&gt;
&lt;li&gt;Works in mobile formats&lt;/li&gt;
&lt;li&gt;Better editing experience&lt;/li&gt;
&lt;li&gt;New service layer&lt;/li&gt;
&lt;li&gt;Better performance&lt;/li&gt;
&lt;li&gt;Greater support for latest technology&lt;/li&gt;
&lt;li&gt;Packages!&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On the other hand, there may be problems around how the site used to be built (think WebForms/XSLT) which render it difficult to upgrade or simply too time consuming to get back on to the upgrade path and work with the &lt;strong&gt;best version&lt;/strong&gt; of Umbraco. These are choices which are largely down to the client and will require some conversations around. Obviously, we'd all like to work to the latest version and be on a common playground, but sometimes other things hinder us from taking these steps.&lt;/p&gt;

&lt;p&gt;The good news is that with some planning and a little bit of perserverance and knowledge it isn't actually as daunting as you think it might be. I've heard many a time that the concept of upgrading a site that was built 3-5 years ago was better off with a complete rewrite and rework of the content, including fresh designs. Whilst this might be the path you go down more often than not, sometimes it's not exactly feasible or best placed to migrate a bunch of content and then factor in all of the changes around that. For larger sites, this certainly becomes the case.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's the process?
&lt;/h3&gt;

&lt;p&gt;Since 7.3, largely an Umbraco upgrade can be done via NuGet without too much extra work required. This is all dealt with by the migration scripts that were added and are included with each minor release from now on (even dating back to &lt;a href="https://github.com/umbraco/Umbraco-CMS/tree/dev-v7/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionFourOneZero" rel="noopener noreferrer"&gt;FourOneZero&lt;/a&gt;). When you update all the files to the latest version, Umbraco will perform a check against the database and if it finds that it needs to update then you will be prompted to upgrade the database via the installer. Click the button and wait until you see the new Umbraco UI.&lt;/p&gt;

&lt;p&gt;But things might not go as smooth as that, sometimes the installer might fallover or it will report that there are incompatible data types. What do you do then? When it comes to the data types, I found that you could map these to the newer counterparts or simply take a note and update those once you have performed the base upgrade. Take a note of what was there before and what you want to have afterwards. As for when it fails, find the error and look for support on the forums, or place an issue on the tracker. Everyone that does this, will help Umbraco to help others and make the process better for all.&lt;/p&gt;

&lt;p&gt;At this point I'm referring mostly towards the concept of getting Umbraco working in terms of the back-office and having a working CMS. We still need to take a look at our code that actually runs the website. Above I mentioned that you might be using old technology or you might be using packages / data types that are no longer compatible. The prep work around figuring out this stuff before is important and will provide a decent comparison between where you are and where you want to be. I found that exporting the doc types, templates and macros from the database was a particularly useful exercise for this. It's quite possible that there aren't many custom implementations and that actually once you've done the database side of things, Umbraco works without any major adjustments.&lt;/p&gt;

&lt;p&gt;Some of the other things you might want to look into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;update the icons&lt;/li&gt;
&lt;li&gt;update data types (if required)&lt;/li&gt;
&lt;li&gt;figure out best use of packages&lt;/li&gt;
&lt;li&gt;assess the use of doc types (it's possible to change them and sort into folders)&lt;/li&gt;
&lt;li&gt;assess the use of macros (could it just be a Razor partial?)&lt;/li&gt;
&lt;li&gt;check over the content&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Switching out WebForms/XSLT for MVC/Razor can be a time consuming task, but in the end it turns out to be an opportunity to amend some of the methods from before and update to new techniques. It's also a rather nice way of realising that XSLT was rather nasty, and in getting rid of it all you can brief a sigh of relief that another Umbraco site has moved on from the not so distant past. Figuratively speaking of course. Unfortunately, you won't be able to switch out too much when it comes to content structure, but you may be able to upgrade some of those old packages to their equivalent v7 counterparts. For example, Embedded Content now becomes Nested Content and everyone is happy.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;So, you've got an old site and are thinking about taking the leap. Assess your options, figure out what is important and how big the scale of the job might be. Take backups and compare. Embrace the changes and enjoy the new world of Umbraco. It's quite a good CMS you know.&lt;/p&gt;

</description>
      <category>umbraco</category>
    </item>
    <item>
      <title>Continuous delivery for .NET (revisited)</title>
      <dc:creator>Thomas Morris</dc:creator>
      <pubDate>Fri, 03 Jul 2015 00:00:00 +0000</pubDate>
      <link>https://forem.com/mozzydev/continuous-delivery-for-net-revisited-2pb9</link>
      <guid>https://forem.com/mozzydev/continuous-delivery-for-net-revisited-2pb9</guid>
      <description>&lt;p&gt;Last year I wrote about deployments and the idea of &lt;a href="https://mozzy.dev/posts/continuous-delivery-for-dotnet/" rel="noopener noreferrer"&gt;continuous delivery for .NET&lt;/a&gt;. During that article I spoke about how to set up and configure TeamCity and Octopus Deploy as tools for deployment as well as adding some notes around process.&lt;/p&gt;

&lt;p&gt;Well, things change and constant improvements are made, so this is a look back on that article and an update as to how the process has been modified. The good news is that the tools chosen in the first article have become staples in the deployment process and what we are talking about here is a refinement. To reiterate the purpose...&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;TeamCity is the build tool, Octopus Deploy is the deployment tool.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  TeamCity
&lt;/h2&gt;

&lt;p&gt;As mentioned before we are using TeamCity to build the solution, perform tests and create an artifact for deployment. We also use a template so this can be shared across projects.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Configure version (&lt;a href="https://github.com/GitTools/GitVersion" rel="noopener noreferrer"&gt;GitVersion&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Fetch packages, build solution and run OctoPack&lt;/li&gt;
&lt;li&gt;Front end tasks (e.g. npm install / grunt / gulp)&lt;/li&gt;
&lt;li&gt;Perform tests and check code coverage&lt;/li&gt;
&lt;li&gt;Publish package to Octopus Deploy NuGet server&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You may want to split this out into 2 or 3 configurations depending on requirements. Reasons for doing this would be if you wanted to run your unit tests separately (they might take a long time) or if you wanted to publish your artifact as a dependency (i.e. manual task to push the artifact which is created in your other configuration).&lt;/p&gt;

&lt;h3&gt;
  
  
  GitVersion
&lt;/h3&gt;

&lt;p&gt;We are using this as a meta-runner within TeamCity, there are other options as to how you use this tool such as command line or MSBuild tasks. What this does is create our SemVer or NuGet version automatically for us based on our git history. Previously we were doing a lot of the versioning manually and then we came up with a powershell script to achieve a similar outcome until we stumbled upon this which does it all for us. It follows Gitflow and Github flow conventions and can be applied to other branching strategies with some configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Octopus Deploy
&lt;/h2&gt;

&lt;p&gt;Used to deploy an artifact (NuGet package) to a given environment, as well as setting up a website in IIS and updating variables for different SQL connections. Our process here is largely the same, yet Octopus Deploy has grown up a little since then and now has support for lifecycles, automatic release creation and (in next release) offline deployments amongst some other really useful features.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Test SQL connection&lt;/li&gt;
&lt;li&gt;Grab NuGet package&lt;/li&gt;
&lt;li&gt;Create / update website in IIS&lt;/li&gt;
&lt;li&gt;Deploy files to website folder&lt;/li&gt;
&lt;li&gt;Update variables / apply transforms&lt;/li&gt;
&lt;li&gt;Test URL (200 OK)&lt;/li&gt;
&lt;li&gt;Notify status of deployment via Slack&lt;/li&gt;
&lt;li&gt;Clean up / apply retention policies&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Steps 2, 3, 4 and 5 can actually be done via one step in Octopus Deploy (deploy a NuGet package), but I have split it out here for better readability. We have also added some basic tests around our deployment...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Test SQL connection : if we can't access the database using the provided connection string, we don't deploy&lt;/li&gt;
&lt;li&gt;Test URL : we ensure that we get a 200 OK status back once we have deployed&lt;/li&gt;
&lt;li&gt;Notify status : we use Slack for sending out a deployment status (could also send an email if you prefer traditional methods)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Depending on the project or usage case you might want to do other steps such as backup the database or website folder, grant permissions to a certain user, or install a package required for deployment via Chocolatey for example. There are loads of other options in the step template library: &lt;a href="https://library.octopusdeploy.com/" rel="noopener noreferrer"&gt;https://library.octopusdeploy.com/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Lifecycles
&lt;/h3&gt;

&lt;p&gt;This was introduced in 2.6 and allowed for structuring your deployment process between environments. So, you could set it up to no longer allow a release package to be deployed straight to Production without any testing for example. This forces you to take a release through the proper deployment process and get sign-off before promoting.&lt;/p&gt;

&lt;p&gt;So, an example lifecycle could be set up like this...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Internal testing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dev (auto-deploy)&lt;/li&gt;
&lt;li&gt;QA&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Client testing&lt;/strong&gt; (any 1)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;UAT&lt;/li&gt;
&lt;li&gt;Pre Prod&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Go live&lt;/strong&gt; (any 1)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Production&lt;/li&gt;
&lt;li&gt;DR (backup servers)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Within this you can specify whether all of the environments need to be deployed to or at least one in the lifecycle phase, denoted in brackets above. You can also set different retention policies per phase, so you would probably want to keep all releases in the 'go live' phase, but maybe the latest 5 in the 'internal testing' and 'client testing' phase.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.0
&lt;/h3&gt;

&lt;p&gt;A &lt;a href="http://octopusdeploy.com/blog/octopus-3.0-pre-release-is-here" rel="noopener noreferrer"&gt;new version&lt;/a&gt; of Octopus Deploy is in pre-release. With this comes a bunch of changes and new features...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deployment targets which allow for offline deployments, Azure websites, SSH and Linux support&lt;/li&gt;
&lt;li&gt;Rebuilt with SQL Server rather than RavenDB&lt;/li&gt;
&lt;li&gt;Improved performance&lt;/li&gt;
&lt;li&gt;Something called &lt;a href="http://octopusdeploy.com/blog/the-octopus-deploy-3.0-time-saver-delta-compression" rel="noopener noreferrer"&gt;delta compression&lt;/a&gt;, which only transfers things that have changed in your package and should make deployments a lot quicker.&lt;/li&gt;
&lt;li&gt;Migration tool so you can export your configuration into JSON and import into other instances of Octopus Deploy&lt;/li&gt;
&lt;li&gt;Changes to tentacle architecture, which means that the deployment aspect of a tentacle is no longer tightly coupled to the Octopus version. Enter Calamari, a command-line tool invoked by Tentacle during a deployment for doing deployment tasks. It is also &lt;a href="https://github.com/OctopusDeploy/Calamari" rel="noopener noreferrer"&gt;open-source&lt;/a&gt;, so you can fork and make it your own.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>dotnet</category>
      <category>teamcity</category>
      <category>octopusdeploy</category>
    </item>
    <item>
      <title>Awesome Umbraco</title>
      <dc:creator>Thomas Morris</dc:creator>
      <pubDate>Fri, 01 May 2015 00:00:00 +0000</pubDate>
      <link>https://forem.com/mozzydev/awesome-umbraco-2c98</link>
      <guid>https://forem.com/mozzydev/awesome-umbraco-2c98</guid>
      <description>&lt;p&gt;Many of you are probably aware that one of the great things about Umbraco is the fact that it is easily extendable and can be used for all sorts of flexible solutions. This is mostly down to the community and the people who are constantly building upon a solid foundation.&lt;/p&gt;

&lt;p&gt;It would be a shame for all this great work to go unnoticed and so &lt;a href="https://twitter.com/leekelleher" rel="noopener noreferrer"&gt;Lee Kelleher&lt;/a&gt; has created a repository that showcases some of these packages and groups them into their use.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A collection of awesome Umbraco 7 packages, resources and shiny things.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Next steps
&lt;/h3&gt;

&lt;p&gt;Check out the &lt;a href="https://github.com/leekelleher/awesome-umbraco" rel="noopener noreferrer"&gt;Github repo&lt;/a&gt; and add some packages to the list!&lt;/p&gt;

</description>
      <category>umbraco</category>
    </item>
    <item>
      <title>Continuous delivery for .NET (part 1)</title>
      <dc:creator>Thomas Morris</dc:creator>
      <pubDate>Thu, 09 Oct 2014 00:00:00 +0000</pubDate>
      <link>https://forem.com/mozzydev/continuous-delivery-for-net-2392</link>
      <guid>https://forem.com/mozzydev/continuous-delivery-for-net-2392</guid>
      <description>&lt;p&gt;One very important factor of being a developer is deploying your code to the appropriate environment without anything failing. In order to do this, we should be automating as many tasks as possible to reduce human failure. Of course, some degree of human interaction should happen but by in large, we shouldn't need to do much once we have set up our deployment process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Simple guide
&lt;/h2&gt;

&lt;p&gt;At it's very basic, this should happen every time we work on a project.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create project + repo&lt;/li&gt;
&lt;li&gt;Write some code&lt;/li&gt;
&lt;li&gt;Push some code to repo&lt;/li&gt;
&lt;li&gt;Grab code and push to server&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now... parts 1, 2 and 3 will largely be the same wherever, but 4 could be done a number of different ways and there are various different settings / updates required to get a working website. Let's not go into too much details of the different options, but look at a particular method for making this work.&lt;/p&gt;

&lt;h2&gt;
  
  
  TeamCity and Octopus Deploy
&lt;/h2&gt;

&lt;p&gt;In order to for us to deploy, we are going to use TeamCity and Octopus Deploy. There is a bit of configuration required to do so, but this should be simpler than the traditional Web Deploy method.&lt;/p&gt;

&lt;p&gt;It is worth noting that one of the goals in deployment is to allow different roles within the process. So, the devs can push code and then the sysadmins or tech leads can manage deployments. Therefore, publish from Visual Studio is completely out of the question. This has a few advantages in that the relevant people are in charge of their remit. For example, a dev doesn't have the ability to push changes to Production and therefore a degree of protection / sign-off is involved. sysadmins can create a new server and see at a granular level what gets pushed if they choose to. Important server details are not exposed, which can be the case with Web Deploy.&lt;/p&gt;

&lt;p&gt;Below is the basic overview of steps required in set up...&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install TeamCity on build server (one time only)&lt;/li&gt;
&lt;li&gt;Install &lt;a href="http://docs.octopusdeploy.com/display/OD/TeamCity" rel="noopener noreferrer"&gt;Octopus TeamCity plugin&lt;/a&gt; (one time only)&lt;/li&gt;
&lt;li&gt;Install &lt;a href="http://docs.octopusdeploy.com/display/OD/Installing+Octopus" rel="noopener noreferrer"&gt;Octopus Server&lt;/a&gt; on build server (one time only)&lt;/li&gt;
&lt;li&gt;Create servers for project (one time only for each project)&lt;/li&gt;
&lt;li&gt;Install &lt;a href="http://docs.octopusdeploy.com/display/OD/Installing+Tentacles" rel="noopener noreferrer"&gt;Octopus Tentacle&lt;/a&gt; on required servers (one time only for each server)&lt;/li&gt;
&lt;li&gt;Install &lt;a href="http://docs.octopusdeploy.com/display/OD/Using+OctoPack" rel="noopener noreferrer"&gt;OctoPack&lt;/a&gt; in project via NuGet (one time only for each project)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As shown, a lot of these tasks you will not need to revisit and once completed, will allow you to deploy without the need for manual intervention.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TeamCity&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Used to build the solution, perform tests and create an artifact for deployment. This will have continuous integration set up for the dev branch so that we don't have to trigger the release each time. We can use a template to share this across projects.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Checkout repository and build solution (run OctoPack)&lt;/li&gt;
&lt;li&gt;Perform tests and check code coverage&lt;/li&gt;
&lt;li&gt;Publish package to Octopus NuGet server&lt;/li&gt;
&lt;li&gt;Create Octopus release (trigger Octopus Deploy)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Octopus Deploy&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Used to deploy an artifact to a given environment, as well as setting up a website in IIS and updating variables for different SQL connections. This all happens on the server we are deploying to via a secure connection.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Grab NuGet package&lt;/li&gt;
&lt;li&gt;Create website in IIS&lt;/li&gt;
&lt;li&gt;Deploy files to website folder&lt;/li&gt;
&lt;li&gt;Update variables / apply transforms&lt;/li&gt;
&lt;li&gt;Clean up / apply retention policies&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When a release is created, Octopus Deploy will keep this indefinitely unless you tell it to. This means that you can rollback quickly to a prior release, but also means that you could be left with a number of files left on the server that you don't want. Therefore, within Octopus Portal you can amend the number of releases you want to keep and for how many days. More info can be found in the &lt;a href="http://docs.octopusdeploy.com/display/OD/Retention+policies" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why use both?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It is true that you could use TeamCity to deploy to each environment and perform configurations for you. However, this is reliant on Web Deploy being installed on the server you wish to deploy to. This is not a requirement for Octopus Deploy, which uses the idea of tentacles to open up a communication between the build server and the web server. This has several &lt;a href="http://docs.octopusdeploy.com/pages/viewpage.action?pageId=360622" rel="noopener noreferrer"&gt;security enhancements&lt;/a&gt; and is generally easier to configure. You could also get Octopus Deploy to set up a site in IIS or perform Powershell tasks for you, something TeamCity and other build platforms are not built for.&lt;/p&gt;

&lt;p&gt;All in all, it is about using what is built for the task at hand. TeamCity can be used for building the code, running the tests and creating a single release package. Octopus Deploy can then be used to deploy this NuGet package wherever you want and ensure that the configuration is correct for the environment, even cleaning up files in the process.&lt;/p&gt;

&lt;p&gt;If you would like to read more, there is a &lt;a href="http://octopusdeploy.com/blog/octopus-vs-build-server" rel="noopener noreferrer"&gt;blog post&lt;/a&gt; detailing this approach, which explains why Octopus Deploy was created.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example setup
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;1 build server with TeamCity and Octopus server installed&lt;/li&gt;
&lt;li&gt;1 web/db server for internal Development/QA (shared web and db)&lt;/li&gt;
&lt;li&gt;1 web/db server for UAT (could be separate web and db)&lt;/li&gt;
&lt;li&gt;1 web/db server for Production (could be separate web and db)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In your project you would need the following &lt;strong&gt;transforms&lt;/strong&gt;...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Web.Development.config&lt;/li&gt;
&lt;li&gt;Web.QA.config&lt;/li&gt;
&lt;li&gt;Web.UAT.config&lt;/li&gt;
&lt;li&gt;Web.Production.config&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These will get run automatically when uploaded to the web server by Octopus Deploy. There are a couple of things to take note of, however. Ensure that the transform matches the environment name in Octopus Deploy and make sure that the files are included in the NuGet package. For more notes on this, check the &lt;a href="http://docs.octopusdeploy.com/display/OD/Configuration+files" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Octopus Deploy also has this idea of &lt;strong&gt;variables&lt;/strong&gt; that can be set within the Octopus Portal (admin area). This means that you can define your variables and specify which environment these will apply to. As long as you have these turned on for your project, they will overwrite the name/value pairs within your config files (not just web.config). There is also the added benefit of being able to define variable sets and inherit these on a project. One such example, could be a set of logging options that you only enable for UAT and Production, but you tend to do this on every project. With a variable set, you can ensure they are included with little configuration. See the &lt;a href="http://docs.octopusdeploy.com/display/OD/Variables" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; for more examples.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>teamcity</category>
      <category>octopusdeploy</category>
    </item>
  </channel>
</rss>
