Deployment

Previewing revisions with ember-cli-deploy-s3-index

Michael Klein

· 5 min read

Previewing deployments before rolling them out to your entire audience is one of the most useful features that you can get when deploying your applications with ember-cli-deploy. This post will show you how to do this when deploying to a object-storage like S3 where you are not controlling the servers that deliver your application.

Previewing revisions/deployments of ember applications before releasing them to the public has long been a huge selling-point of ember-cli-deploy . When using a object storage like Amazon S3 to deliver your application you have to do additional work to be able to preview your revisions in production - this post will walk you through the necessary steps to do so.

As described in the lightning-strategy -guide the idea is pretty simple. As you are serving a static asset when delivering your ember application to the public you can have multiple versions of this application available and decide which version to serve based on some backend-server logic. When you want to preview a revision you send a request to your backend-server that decides based on some user-specified information to serve up a different revision of your application than other users see per default. Most people are using query-parameters (e.g. https://example.com?revision_key=new-version-id) for this but you could use whatever mechanism you see fit to decide which version of your application to serve based on the request a user makes to your servers.

When deploying your ember application’s revisions to S3/Cloudfront via the ember-cli-deploy-s3-index -addon this becomes difficult though as you don’t have control over the backend-logic when only serving static files via S3.

Fortunately, you can setup revisions previews when using ember-cli-deploy-s3-index. There are two scenarios:

Hash-Location

Accessing non-active revisions that are stored in S3 is pretty straight forward. You can access these index-files directly from the bucket and your application will try to boot up.

The only problem is that when serving up and index.html-file from a path that is not the root-object of your bucket the URL will contain the file-name of the index-file you are trying to access and Ember’s router will throw an UnrecognizedURLError because it tries to treat the url (e.g. https://example.com/index.html:7bcfabc323599a8b95d33759c2353996) as a path to an ember-route. Your application most likely does not contain a route with a path of index.html:7bcfabc323599a8b95d33759c2353996 of course thus the error.

You can fix this by configuring a locationType of hash in your application’s configuration though:

This will give you pretty ugly URLs but your ember-application will now only consider everything after a #-in your URL an application-URL and will happily boot up your revision-files.

An url of https:://example.com/index.html:7bcfabc323599a8b95d33759c2353996#/about will now try to serve the route that is connected to the about-path.

History-Location

You can also get revision-previews working with the history-location. The default locationType of auto will not work due to the way it detects the location-type it can use.

History-API is supported by all major browser of today but if you need to support really old browsers you might be out of luck and can't use this workaround.

As discussed before the only problem when serving revision-files directly from a bucket is that Ember’s router gets confused by the URL-structure.

We can help the router to understand the URL-structure by creating an instance-initializer:

When accessing https:://example.com/index.html:7bcfabc323599a8b95d33759c2353996 we simply tell the ember-router to ignore the revision-identifier.

The tricky part comes when we want to access nested routes. Due to the way S3 works, we can’t simply access a URL like https:://example.com/index.html:7bcfabc323599a8b95d33759c2353996/about as S3 would try to serve the about-file in the index.html:7bcfabc323599a8b95d33759c2353996-directory and the ember-application would not boot up before we receive back an error from S3.

To make nested routes for previews work we follow the same URL-structure as we do for the hash-location. When we access the revision we want to preview via a URL like https:://example.com/index.html:7bcfabc323599a8b95d33759c2353996#/about S3 will serve up the index.html:7bcfabc323599a8b95d33759c2353996-file in the bucket and the initializer will run. We will then tell the router to ignore the # in the path and start up the application in the /about-path.

This of course is only necessary for previewing revisions. This does not change the way your application behaves for your normal users.

Conclusion

Previewing revisions is possible when using ember-cli-deploy-s3-index but as you might have already figured out, it’s kind of messy because you have to change the way the ember router behaves when booting up the application.

Depending on your use case this might be a good-enough-solution for you but if you need to get fancy with a/b-testing, feature-branch-deployments etc., you might be better off considering the use of other deployment-addons like ember-cli-deploy-redis in combination with backend-servers to serve your application. You just have much more control over how you are serving your application to your users that way.

ember-cli-deploy makes it easy to setup deployments for your Ember.js application but sometimes teams have very complex requirements for their deployment workflow. Don’t hesitate to if your team does. We are here to help your teams deliver ambitious applications with confidence.

If you have questions or want to share your thoughts about this post with me you can find me on Twitter - I’m always interested in hearing about your experiences with ember-cli-deploy and the challenges you face when deploying your Ember.js apps.

Schedule a call

We are here to enable your team to deliver ambitious applications. Let's discuss how we can help.

European flag

© 2020 effective ember All rights reserved.