There are an almost infinite number of ways to set up an automated deployment pipeline. Taking code changes from a repository on push or pull-request and automatically deploying to servers for automated testing, user testing, content staging and finally production.
There are also a number of very good reasons to implement an automated pipeline at the start of development rather than tacking one on at the end.
- It ensures that there is a clearly defined process for getting code to where it needs to be
- It avoids any issues that could be introduced by human interaction, such as forgetting to update a file
- But one overlooked reason is - it documents the onboarding process for a project. It tells a developer what they need to do/have to run the project they're working on.
Given the overwhelming number of options in front of you when it comes to building a pipeline - based on code languages, hosting environments (both physical - infrastructure, and virtual - operating system) and personal preferences - this post will focus on a pipeline that takes code for a PHP website from a Git repository (on Github, but that's not entirely relevant) and deploys it to a Linux server.
Continuous integration
Continuous integration - or CI for short - is the process of taking the raw source code and running whatever processes are required to transform it into a state ready to be run wherever it is hosted.
This could be compiling the source code from C/C#/Java/Golang/etc. to its binary format, it could be transpiling and minimising Typescript into a Javascript package.
It can also include steps for running unit tests and reporting on code coverage.
The output should be a package that can be dropped onto a server and run without any further interaction, some environment-specific configuration may be necessary but that should be configured within the environment. The CI process should have the same flow regardless of the environment to ensure consistency and idempotency.
Idempotency simply means that the process should be able to run with the same inputs and produce the same outputs, there should be no variability.
See here for an example of a Github Actions configuration that will build a package based on the code in the repository. The steps it takes are:
- Checkout the code for the repository
- Configure the PHP environment for v8.0
- Run a
composer install
to gather the referenced packages - Compress the folder into a "bzipped tarball" for deployment
Notice how this workflow doesn't care what environment this package is destined for. The only filter is on the branches it will run on.
Continuous deployment
This step is a work in progress. Check back later for an update. 😊