What we learnt while doing remote angular builds.
TLDR; It makes deploying angular apps a consistent experience.
What is a build — in terms of frontend apps?
We use Angular to make frontend applications. The Angular build process is — ng build which creates js bundles of all the code that drives the web app. Angular 4 has ahead of time compiling that takes the code written and makes a build that has a lot of best practices like tree shaking and transpiling for serving web applications.
Why we do remote builds?
So that everyone in our team can deploy code to the staging and production environments. Well, maybe not anyone. But it makes it easy for the project maintainer to focus on writing and maintaining the code.
Build processes are faster too — since they’re on machines dedicated to just doing that one thing. And consistent. It’s easy for everyone to go through logs in case something fails. It also lets us manage code reviews online. Once a pull request is merged after reviewing it — possibly using the web interface.
We currently don’t do automated tests — but when we do, those can be easily shoehorned into this deploy process.
What we use
We’ve had a great experience with Beanstalk from the wildbit team. We tried Deploybot and since we have a paid plan for Beanstalk — Wildbit was kind enough to give us a free Deploybot account 🎉
What we learnt
- Caching the container that the build is made in decreases build time. While obvious, it took us some time to figure this one out. Deploybot — under advanced settings has an option to for preparation of the container (like installing dependencies) and the building of the source code itself.
Cached build commands are executed only once and then the results are cached for you, until the package.json file changes.
Creating builds and deploying that build go hand in hand.
- Firebase tools has a login for CI which generates a token that can be passed along while doing a remote build which allows us to use firebase hosting. This gives us an inexpensive way to use CDN backed hosting. Firebase hosting has a one-click rollback option to the serve the previously deployed build in case of a buggy build. That has saved our bacon more than once.
- To combat failed production builds we sometimes create a production build locally and bug fix before using the automated system again. We do this mostly before a big feature release.
- We usually have the npm modules defined as the latest ones in our package.json. This would sometimes cause build errors. To counter that we added an ng -v to the build script. This gives clear logs on what version modules were used during the remote build.
- Using environment variables is a good idea to keep production variables away from the dev environment. Adding the output-hashing=all flag worked well as the cache buster for non prod builds.
- We would also have random issues regarding firebase not being able to understand which project was associated.
Adding the — project flag sorted those issues out.
The result of all this:
No one spends time deploying anymore.
Well not most of the time