Saturday, May 10, 2014

Azure Continuous Delivery Build Configuration

Setting up an Azure website with continuous git deliveries from Visual Studio Online was straightforward enough but it wasn't entirely clear to me how you specify which Build Configuration to use (e.g. Debug vs Release). It turns out to resolve this:

1. Open your site up in Azure Management Portal


2. Click on the Visual Studio link (bottom right of the above screenshot). Studio should then open up

3. Within Visual Studio's Team Explorer Tab, click on the Builds button


4. Within the Builds tab, you'll see the build definitions. Interestingly, behind the scenes Azure created a "{site}_CD" build definition


5. Right click on the _CD build definition and select "Edit Build Definition..."

6. On the property page that appears, select the "Process" tab


You can then edit the Configurations and select the Build Configuration you want

Friday, May 9, 2014

Amazon S3 Bucket custom DNS name

Amazon's S3 is an incredibly useful service for storing files and blobs of data. The data is stored in Buckets which are accessibly via an Amazon generated url, similar to:

http(s)://.s3.amazonaws.com/
or, for example, 
http://myFabBucketExample.eoinclayton.net.s3.amazonaws.com

The url does end up being a bit unwieldy though. You may also want to cover the potential future scenario of moving away from S3 and not having to deal with amazonaws.com urls littered throughout your code bases.
To deal with this, if you already have a DNS name (e.g. eoinclayton.net) you can map it to your bucket. To achieve this:

1. Create a bucket in S3 with the same name as you would like your DNS name to appear. E.g. I wanted to end up with a new "assets" subdomain, e.g.  http://assets.eoinclayton.net/{somefile}, so I made a bucket called "assets.eoinclayton.net":


2. If you want the bucket contents to be viewable by the public, modify the S3 bucket so that 'Everyone' has 'Open/Download' access to the contents

2. Next, go to your DNS provider to edit your DNS settings. My domain is held by easyCgi.com so I used their 'DomainCentral' portal to edit my DNS

3. Add a CNAME alias to point your new subdomain to the s3 bucket name


4. Wait a while for the DNS system to update itself and if all is well, you should be able to access your bucket resources directly, e.g.: http://assets.eoinclayton.net/GreenTick.jpg

Thursday, May 8, 2014

HTML5 AppCache with MVC bundles


HTML5 has many handy additions and I recently had the opportunity to use the Appcache Manifest. This feature enables your site to work offline which is particularly useful for mobile orientated sites as users may not always have a reliable 'net connection.

The following guide goes through the approach I took for getting it working via .Net's MVC framework.

Prep the HTML tag

On the page you want to have a manifest for, add the following:

<html lang="en" manifest="/AppCache/AppManifest">

This will tell the browser to look for the appcache manifest.

Setup the Model

We don't need many properties on our Model for the manifest generation. The following will do
public class AppCacheModel
    {
        public string AssemblyVersion { get; set; }
        public List< string> CacheCollection { get; set; }
    }
  • An assembly version which will help update the manifest file contents after every build
  • A CacheCollection list of urls to add to the cache

Add a view

You will need to set various headers to get the manifest file to work correctly. In particular, set the MIME content type to "text/cache-manifest" and set the cache headers so that the manifest never caches.
@model MyWebsite.Models. AppCacheModel
@{
    Layout = null;
    Response.ContentType = "text/cache-manifest";
    Response.Cache.SetCacheability( HttpCacheability.NoCache);
    Response.Cache.SetExpires( DateTime.MinValue);
}CACHE MANIFEST
# Server Assembly Version: @ Model.AssemblyVersion
NETWORK:
*
CACHE:
@foreach (string cacheItem in Model.CacheCollection)
{
    @ cacheItem
}

Instead of hard-coding the individual assets in the Cache section, we are going to get the controller to add them in for us...

Code up the Controller

The controller populates the model with:
  • the assembly version
  • the links to the various assets to be cached. 
The code handles MVC Bundles and also generates a list of asset urls from target folders. If the assets are in a CDN bucket somewhere, you can also provide the link to the CDN.

public class AppCacheController : Controller
    {
        public ActionResult AppManifest()
        {
            // Build the model
            var model = new AppCacheModel();

            model.AssemblyVersion = GetType().Assembly.GetName().Version.ToString();
            model.CacheCollection = new List< string>();
            model.CacheCollection.Add(WriteBundle( "~/bundles/jquery"));
            model.CacheCollection.Add(WriteBundle( "~/bundles/site"));
            model.CacheCollection.Add(GetPhysicalFilesToCache( "~/images", "*.jpg" , "http://cdn.eoinclayton.net/website" ));
            model.CacheCollection.Add(GetPhysicalFilesToCache( "~/images", "*.png" , "http://cdn.eoinclayton.net/website" ));
            model.CacheCollection.Add(GetPhysicalFilesToCache( "~/css", "style*.css", string .Empty));

            return View(model);
        }

        private string WriteBundle( string virtualPath)
        {
            var bundleString = new StringBuilder();
            bundleString.AppendLine( Scripts.Url(virtualPath).ToString());
            return bundleString.ToString();
        }

        private string GetPhysicalFilesToCache( string relativeFolderToAssets, string fileTypes, string cdnBucket)
        {
            var outputString = new StringBuilder();
            var folder = new DirectoryInfo(Server.MapPath(relativeFolderToAssets));
            foreach ( FileInfo file in folder.GetFiles(fileTypes))
            {
                string location = ! String.IsNullOrEmpty(cdnBucket) ? cdnBucket : relativeFolderToAssets;
                string outputFileName = (location + "/" + file).Replace("~" , string.Empty);
                outputString.AppendLine(outputFileName);
            }
            return outputString.ToString();
        }
    }


How to test

1. Open your app/site in Firefox
2. Once it is loaded, close down Firefox
3. Re-open and set Firefox to Offline mode (File -> Offline)
4. Hit your app/site. Even though you are offline, it should still work

You can follow a similar approach on your device, just use Airplane mode instead of Offline mode.

Things to watch out for

  1. Do NOT cache the manifest file! Just don't do it. If you do, your site/app may never update for your clients...!
  2. Refrain from using the "No-Store" response header on the manifest file. The offline site continued to work as expected in Chrome, but in Firefox the entire site stopped working offline...
  3. Use Chrome's Javascript Console (Tools -> Javascript Console) to see if the manifest is being loaded correctly. It will give a breakdown for each item being cached and will tell you, for example, if you try to cache a non-existing asset
  4. To deactivate the appcache manifest, just removing it from the HTML tag is not enough. My site stopped updating entirely when I did this. You will also need to remove the manifest url/view.
  5. You do have a additional bucket to store data known as the 'Local Storage' (http://diveintohtml5.info/storage.html)
  6. There are also optional Javascript events to listen to. This handy Stackoverflow post goes through what the different events do: http://stackoverflow.com/a/20045644

Wednesday, May 7, 2014

Setting up SourceTree, BitBucket, SSH with a proxy on Windows

When using SourceTree to connect to Bitbucket with an SSH key through a proxy server, there are a number of steps to follow...

SourceTree setup

1. Open SourceTree, goto Tools and select 'Create or Import SSH Keys'


2. A dialog will open up. Click Generate to generate a public private key pair:
 
  • Provide a suitable passphrase and save both the public and private keys

3. In your system tray, right click on Pageant (PuTTY authentication agent) and select "Add Key"
 
  • Select the private key you created in step 2

Proxy Setup with Putty

1. Setup your HTTP Proxy settings in Putty
  • Click on your Start button and search for Putty
  • When Putty comes up goto the Session Category 'Default Settings' and then Load
  • Goto the Proxy category and add in the proxy settings, making sure to select the right proxy type
  • Go back to the Session Category and save the updates to the Default Settings
 

Bitbucket setup

1. Goto BitBucket, navigate to "Your Account"
2. Under SSH Keys, add the Public Key saved above
 
3. Restart SourceTree and then add a new repo with the ssh url for your repo
To find the right URL to use, navigate to your repo in BitBucket and you'll see the SSH url on the right: