There have been several requests on our support forum on how to customize environments to specific branches while running Continuous Integration (CI) builds for a repository that has multiple branches. In this tutorial, I'll go over a common scenario and review the multiple ways we can configure branch-specific actions during the CI build.
The scenario I use for this tutorial is, to pull a Docker image in the CI process and upon completion, use different tags for the branches when pushing the Docker image to Docker Hub. The Docker tags should be customized to the specific branch where the CI was processed and should include the build number. The final results of successful CI process tagging different branches looks as shown.
Prerequisite
To maximize your understanding of this tutorial, ensure you have:
- An account with Shippable (sign up for free, using your GitHub/Bitbucket credentials)
- Forked this node.js application from Shippable Samples
- Enable the (node.js) project on Shippable, to follow along
- An account on Docker Hub (sign up for free) to view the results from this tutorial
- Pull the sample_node_eb_docker image locally using the command
docker pull abhijitkini/sample_node_eb_docker
. - Tag it with 'latest'
- Push this image to your Docker Hub account
- Pull the sample_node_eb_docker image locally using the command
Look out for 'ACTION' titles in this tutorial, where you'll have to make changes on your fork.
Ways to customize the environment for different branches
There are many ways one can accomplish the scenario of customizing the tags for a Docker image, per branch, before pushing it to a Docker Registry. I'll go over three of them:
- Modifying the
shippable.yml
file for each branch - Keeping the
shippable.yml
file consistent for both branches - Using a script
Before we jump into each of the ways, I would like to call out the use of 'BRANCH', a standard environment variable, available for use within the build. This env variable, gives you the current branch being built and can be used to trigger various actions as shown in the scenarios.
Let's get started with the first scenario.
Modifying the shippable.yml
file for each branch
When the logic for each branch is different, the shippable.yml
file for each branch can be modified to have different results. For example, I would like to tag the 'Master' branch with the branch name and the build number after every CI run. On the other hand, I want to tag the 'Tutorial' branch with the name of the repository and the build number after every CI run.
ACTION: For this scenario, do the following on your fork of the sample application:
- Update the
shippable.yml
file for the 'Master' branch using the sample below - Add a
shippable.yml
file to the 'Tutorial' branch using the 'Tutorial' sample below - Commit the changes to both the branches which triggers two builds on the Shippable platform
# yml file for the Master Branch
# Language settings language: node_js build: ci: - docker pull abhijitkini/sample_node_eb_docker:latest post_ci: - docker tag -f abhijitkini/sample_node_eb_docker:latest abhijitkini/sample_node_eb_docker:$BRANCH.$BUILD_NUMBER - docker push abhijitkini/sample_node_eb_docker:$BRANCH.$BUILD_NUMBER integrations: hub: - integrationName: "Docker Hub" type: docker branches: only: - master
# yml file for the Tutorial Branch # Language settings
language: node_js build: ci: - docker pull abhijitkini/sample_node_eb_docker:latest post_ci: - docker tag -f abhijitkini/sample_node_eb_docker:latest abhijitkini/sample_node_eb_docker:$REPO_NAME.$BUILD_NUMBER - docker push abhijitkini/sample_node_eb_docker:$REPO_NAME.$BUILD_NUMBER integrations: hub: - integrationName: "Docker Hub" type: docker branches: only: - tutorial
I leverage the standard environment variables to achieve my objective for each branch. With these shippable.yml
files in place, the output of the CI run for each branch on the Shippable platform is shown below:
With the successful runs on both the branches, the output is:
- 'Tutorial' branch: Docker image abhijitkini/sample_node_eb_docker hosted on Docker Hub is tagged with BRANCH = sample_node_eb_docker and BUILD NUMBER = 21
- 'Master' branch: Docker image abhijitkini/sample_node_eb_docker is tagged with BRANCH = Master and BUILD NUMBER = 22
Keep the shippable.yml
file consistent for both branches
To keep the shippable.yml
file consistent across all branches, I'll use a custom environment variable to set an env_name value based on a logic I want to implement. For example, I would like to tag the 'Master' branch with a customized branch name and tag the 'Tutorial' branch with another customized branch name after every CI run.
ACTION: For this scenario, do the following on your fork of the sample application:
- Update the
shippable.yml
file for both the 'Master' and 'Tutorial' branches using the sample below - Commit the changes to both the branches which triggers two builds on the Shippable platform
# yml file for both Master and Tutorial Branch
# Language settings language: node_js build: ci: - docker pull abhijitkini/sample_node_eb_docker:latest post_ci: - if [ "$BRANCH" == "master" ]; then TAG="master_env"; fi - if [ "$BRANCH" == "tutorial" ]; then TAG="tutorial_env"; fi - docker tag -f abhijitkini/sample_node_eb_docker:latest abhijitkini/sample_node_eb_docker:$TAG - docker push abhijitkini/sample_node_eb_docker:$TAG integrations: hub: - integrationName: "Docker Hub" type: docker
The shippable.yml
files for both branches are consistent and same. The output of the CI run for both branches are similar. The 'Master' branch output is shown below:
Based on the successful run on both branches, the output is:
- 'Master' branch: Docker image abhijitkini/sample_node_eb_docker hosted on Docker Hub is tagged as 'master_env'
- 'Tutorial' branch: Docker image abhijitkini/sample_node_eb_docker will have the tag 'tutorial_env'.
Using a script
For scenarios where several commands need to be executed and are unique to each branch, then the logic can be built into a script and then used in the ci
section of the shippable.yml
file. In this example, I would like to tag only the 'Tutorial' branch with a string 'script' using a deployment script, after every CI run for this branch.
ACTION: For this scenario, do the following on your fork of the sample application:
- Update the
shippable.yml
file for both the 'Master' and 'Tutorial' branches using the sample below - Commit the changes to both the branches which triggers two builds on the Shippable platform
# yml file for both Master and Tutorial Branches
# Language settings language: node_js build: ci: - docker pull abhijitkini/sample_node_eb_docker:latest post_ci: - if [ "$BRANCH" == "tutorial" ]; then ./deployment_script.sh; fi integrations: hub: - integrationName: "Docker Hub" type: docker
branches:
only:
- tutorial
I have a simple script in the file deployment_script.sh
that tags the Docker image with the string 'script' and pushes it to Docker Hub. You can use scripts with a logic to include several commands, as needed.
#!/bin/bash docker tag -f abhijitkini/sample_node_eb_docker:latest abhijitkini/sample_node_eb_docker:script docker push abhijitkini/sample_node_eb_docker:script
In this example, shippable.yml
files for both branches are consistent and same. The output of the CI run for both branches are similar. The 'Tutorial' branch output is shown below:
Based on the successful run on both branches, the output is:
- 'Tutorial' branch: Docker image abhijitkini/sample_node_eb_docker hosted on Docker Hub is tagged as 'script'
- 'Master' branch: No tag is set on the Docker image
Review tags in Docker Hub
We've gone through three scenarios where the outputs were Docker images tagged in unique ways for each branch after a successful CI run. Let's take a look at those tagged images on Docker Hub.
ACTION:
- Log in to your Docker Hub account
- Access your sample_node_eb_docker repository
- Review the 'Tags' tab
This tutorial gives you simple examples of customizing environments for different branches of your repository while running Continuous Integration. Per your requirements, use these examples and expand on them to include more complex logic to achieve your objectives.
Questions or feedback, use the 'Comments' section below. Alternatively, you can also contact us through support.