Deployments can be painful, especially for large complex infrastructures where there's a lot of moving pieces. On top of this, you have to remember to deploy all those pieces and missing one step can take the site down in a bad way, not just because you're deploying a new version and have a little time between different migrations. A theme through all these tasks, though, are they're all important in one way or another. They help us focus on the real challenges of the work, not the drama in the code review or stumbling through another code deploy or, but another theme, they all require humans to do them.
That means they're prone to human error. And whether it's simply for getting to run something or forgetting to include a particular step, even for getting to do it in the right order, what can we do to actually avoid those human mistakes? Well we can automate it, of course. So let's learn how to automate all the things.
How do we actually automate all the things? If we're deploying anything even moderately complex, we have a bunch of things that we typically have to do in order to actually deploy our full stack. Those 10 commands or buttons that you have to run every time your Rails server and AWS infrastructure, well we can put that in a script. Scripts are probably the simplest form of automation. This helps us automate the manual tasks that we might have to take. So why not put them in a bash script? Or insert your favorite scripting language of choice, like Node, where you can even write it in JavaScript if that's your thing. The goal is to have a list of repeatable steps. And by using that one command with that script, you're able to do the exact same thing every single time. That way you never forget to leave anything out.
But scripts also ultimately rely on something to trigger that. If it's still a human, you might forget to run that script in the first place. Or if somebody's filling in for a day, maybe they don't even know that you have a script to run this setup. A feature that comes baked in to Git itself is Git hooks. With Git hooks, you can trigger something at different points of the Git process. For instance, you can setup a commit hook, where any time you actually run a commit, your hook will run, automating some part of your process, where a good example for that is formatting. Any time someone commits, you can setup Prettier, or any other formatter, to run before the commit actually applies. With your existing scripts to run linting and formatting, this is called a precommit, where, with tools like Husky, you can hook in and manage all those Git hooks. We're also applying lint staged here, which allows us to get the path of all those changes that we actually get in the stage for Git, where that way, when we run our precommit hook, we're not affecting the entire repository tree, we're only impacting the files that actually changed. But once that script finishes, those changes are added onto the Git stage before that commit is actually applied. So when the actual commit happens, all Git knows is that the code is pretty and formatted. All the developer knows is they got their job done, and when the code is actually pushed up to GitHub, it looks like that one person wrote it. But not everything makes sense inside of a Git hook. You don't want to run your tests as a precommit hook, for example, where that's going to be a huge pain for developers. Imagine you're working on a project with a huge test suite and in order to actually commit, you have to run that entire suite.
Comments