In my prevous post, we built a workflow, using GitHub Actions to build, test and deploy a static web app to Azure Blob Storage. Throughout this post, I'm extending the previous workflow with bounded CI/CD pipelines to separate concerns.
You can download the sample codes used in this post at this GitHub repository.
Separate Deployment from Build
We discussed four fundamental concepts – Workflow, Event, Runner and Action in my previous post. These concepts are bare minimum information to build a Workflow with GitHub Actions. In addition to them, in order to build bounded pipelines, another concept, Job, needs to bring in. Job is a logical grouping that contains Runner and series of Actions. It can be defined multiple times in one Workflow and run at the same time or one after another, based on the definition.
Redefine Build Job
The last action is
Publish app. In fact, this action is more accurate if we change it to "upload an artifact" as the final step before deployment. Let's change it to the appropriate one. We're going to use the action, called
app is the name of the artifact.
After updating the workflow, push it back to GitHub repo, and it will trigger the updated workflow. The workflow doesn't push the artifact to Azure Blob Storage. Instead, it uploads the artifact to the designated location on the pipeline.
Define Deployment Job
There is no fixed or definite way of the application deployment scenario. But Here are over-simplified two scenarios. One runs the Jobs sequentially, one after another, and the other runs deployment jobs in parallel.
In the first scenario, the
deploy_to_dev job should have a dependency on its previous job,
deploy_to_test. In other words, if one job fails, the next job can't be run. Therefore, declare the dependency like below:
On the other hands, the second scenario shows all deployment job has only the dependency on the
build_and_publish job. Therefore, the Workflow definition can look like below:
In this scenario, we publish two static websites – one for
DEV and the other for
PROD. For the deployment job, we use another action, called
Based on this action, let's add two jobs,
deploy_to_prod, to the existing workflow.
We should make sure one thing here. Each Job has its own Runner and runs on it. Once after one Job is over, the Runner is also removed. In other words, although we logged into Azure in the previous Job, it doesn't necessarily mean that the login credentials are carried over to the next Job. Therefore, like the workflow definition above, each Job should log in to Azure first.
Once redefinition complete, let's push the change and see the result. The first screenshot is the result of the
And this is the last job,
We only defined two distinctive actions – download artifact and deploy to Azure, which is a bare minimum for deployment. But there can be many other scenarios from business requirements. For example, either integration testing or end-to-end testing can be added to each job, respectively.
So far, we've built bounded CI/CD pipelines to separate concerns and responsibilities on each job.