Day One: Getting Started with Bitbucket Pipelines
Bitbucket Pipelines Demo
By the end of this course, you should be able to put together a multi-step Bitbucket Pipeline to lint, scan, test and deploy your CF app. Check out this video for a demonstration of how Bitbucket works to run pipelines on git push.
Bitbucket Pipelines Config File
Bitbucket Pipelines is mainly configured through a bitbucket-pipelines.yml
yaml file in the root of your repository. Remember that yaml files must be carefully indented using spaces, not tabs. Go ahead and create that file now using your favorite editor - we'll add to it as we go.
Every time you push to the Bitbucket repository, Bitbucket will read the configuration from this file and begin running the pipelines per your configuration.
Let's look at a basic configuration file for Bitbucket Pipelines.
This is an example of a pipeline I use on one of my own projects to lint my CFML. Take a good look, because all CI examples in this course will be based on this syntax!
OK? Now let's go through the file line by line until we understand what's going on.
Choosing a Docker Image
TL;DR: Use image: ortussolutions/commandbox:lucee5-alpine
for Lucee apps and image: ortussolutions/commandbox:adobe{release}-alpine
for ACF apps.
In Bitbucket Pipelines, every build runs in a Docker container, which enables us to tweak our CI build environment simply by choosing a Docker image which suits our needs. We "choose" a docker image by specifying an image and tag on line 1 of our configuration file - something like this: image: <imagename>:<tag>
.
The <imagename>
portion specifies which Docker image to use, by default pulling the image from the public Docker Hub. In most cases, unless you are a Docker power user looking for lighter/faster builds, I would recommend you use the Ortus Solutions docker image: image: ortussolutions/commandbox:<tag>
.
The <tag>
portion specifies an exact image version to use. There are many different versions depending on the CF engine or CommandBox configuration you need. For Lucee users, I recommend the lucee5-alpine
tag specifying a Lucee 5 engine and the alpine
version for a slightly smaller build. If you are running on ACF, use the tag to specify an ACF release such as adobe2016-alpine
.
See the full list of ortussolutions/commandbox image tags here.
So the very first line in the bitbucket-pipelines.yml
should look like this:
Configuring Branch Pipelines
Next we'll add a default pipeline to run when we push code on any branch. A pipeline defines a series of CI tasks which are run in sequence when a push or merge is made on the specified branch or branches. This course uses the default pipeline to execute on every push to the repository:
We can limit this pipeline to run on a specific branch or branches - for example, on Day Five of the course, we will set up a deployment pipeline to only run on pushes to the master branch. We can also use a "globbing pattern" to instruct Bitbucket to run our pipeline on any branch starting with feat/
:
See Bitbucket's globbing patterns cheat sheet for more details on configuring a pipeline branch.
Bitbucket Pipeline Steps
The example config shows a step section with a name
and a script
section defining various commands to run. This step should contain every command necessary to perform a given task - in the example given, we first install the CFLint CommandBox module then run CFLint with certain parameters.
Any part of the build process can be organized into a separate step or pipeline, but each pipeline and each step starts with a fresh container so don't run box install testbox
in one step and expect box testbox run
to work in another step - the two commands must be run in the same step, because state is not maintained between pipelines or pipeline steps.
In this course, all pipeline tasks will be run on a single pipeline organized by step, but you should know that Bitbucket supports a maximum of 10 steps per pipeline. In later lessons we will create an additional step for each new CI task - that means we'll have a linting step, a Fixinator step, a testing step, and a deployment step. This will keep our file neat and organized, and allow us to re-run any step individually from Bitbucket:
The following is an example of a pipeline separated into multiple steps:
Bitbucket Pipelines Config Validator
This Bitbucket Pipelines config validator tool can help you check your bitbucket-pipelines.yml
file before you bother committing and pushing. (And spending build minutes). If you're going to be playing with the examples in this course, I suggest you paste them in the validator before running them, at least for a while until you are more familiar with the config syntax.
Bitbucket Pipelines Speed Tips
With Bitbucket Pipelines, build time matters because build minutes cost money. Here's a few quick tips to keep your build times low:
Use "Pre-warmed" Alpine Docker Images
In CommandBox parlance, "pre-warmed" means that a specific version of the Lucee server is copied into the image, unpacked, and ready to start before you ever pull down the image to your local machine. For Docker newbies, this just bootstraps the Lucee server startup time with no effort on your part. To use a pre-warmed commandbox docker image, we'll use the lucee5-alpine
image tag, which specifies a pre-warmed Lucee 5 server installed on Alpine Linux, which is a light Linux option for the Docker image base.
Build Your Own Docker Image
All of the examples in this course are based on the Ortus Solutions CommandBox Docker image. This image optimizes the CommandBox startup time, so every pipeline step using this image will run faster than they would after a manual install in the pipeline, for example.
To further speed up your pipelines, you might consider building your own Docker image to install fixinator
, commandbox-cflint
, and any other system modules you may use in a pipeline. This should speed up the install of those modules during the pipeline - although, to be fair, I haven't tried it myself. :)
Limit Clone Depth
Use the clone depth global option to limit the number of git commits to clone into the pipeline container. Unless you plan to be running git commands like git revert <commit>
or git checkout <commit>
during your build (I don’t!), you should be able to speed up your pipeline through this simple config tip.
Day One Wrap Up: Bitbucket Pipelines Base Configuration
Here's the final bitbucket-pipelines.yml
configuration for Lesson One. Your configuration should look extremely similar to this, with your choice of CF engine on line 2.
Enabling Bitbucket Pipelines
Bitbucket Pipelines does not auto-enable just by committing and pushing a bitbucket-pipelines.yml
file. To enable Bitbucket Pipelines for your repository, you'll need to:
- Navigate to your Bitbucket repo
- Under the "Pipelines" group, click "Settings"
- Click the toggle for "Enable Pipelines"
Once that is done, commit and push your bitbucket-pipelines.yml
file up to the repository. You should be able to browse the repository's "Pipelines" section to see your latest commit trigger a pipelines build. Congrats! Your first pipeline is in place! This early in the course, your pipeline should build successfully - if not you may want to take a look at the Bitbucket Pipelines config validator.
And Lesson One comes to a close. Hope you've got a good handle on Bitbucket Pipelines basics! Any questions? Shoot me an email and I will be happy to give you a hand.
1 comments