ARTICLE

How To Configure GS DevOps Mate for Bit Bucket Pipelines

Though I want the setup article to be as concise as possible, a few concepts can pose challenges if left unexplained. You are always welcome to jump directly to the next section which talks about the steps to configure. I would highly recommend you to go through the Tell Me More Buttons as and when they appear!

Before we start, we will be assuming that you have a BitBucket repo setup with Admin access in SFDX format and a ‘main’ branch. If you have a master branch instead of main, replace main with master wherever we are referring to main.


The setup will involve the following steps:

  1. Configure your build runtime environment
  2. Define deployment environments
  3. Define environment variables
  4. Configure the pipelines
  5. Testing the pipelines

1. Build Runtime Configuration

Enable the Pipelines.


            Go to Repository Settings => Pipelines => Settings => Enable Pipelines


Create a YAML file by the name bitbucket-pipelines.yml in the root of the repository, as shown below with the image command. Make sure that the name is the same.

This step sets the GS DevOps Mate Docker image as the build runtime. All other commands would now run under the context of this image or simply saying will run under the GS DevOps Mate Docker runtime and thus will have access to all the custom commands and resources we have packaged/dockerized in it.

2. Define Deployment Variables

  1. Go to Pipelines => Deployments
  2. Create QAOrg, UATOrg, and ProdOrg environments under Test, Staging, and Production environments, respectively.


3. Define Repo Variables  

You may wonder what are these $SOME_TEXT things in the steps defined below. So let’s discuss and sort them first. These are Pipeline variables. They come in three flavors.

  1. Repository Variables: User-defined. We will be defining these soon.                                                                                               e.g. DEVHUB_ORG_TYPE, UAT_ORG_TYPE, LATEST_COMMIT_HASH_TAG
  2. Environment Variables: User-defined (We will not be using them in this post but you can define them in the Environment step which we did previously. Can use exactly like Repository variables as long as you have referenced the environment in your step)
  3. Default Variables: Provided by the CI/CD service. So they will vary as we move from one service to another during this blog posts series.

          e.g. BITBUCKET_CLONE_DIR, BITBUCKET_BUILD_NUMBER

          

      Let’s define Repository variables:


Go to Pipelines => Repository Variables

Define these variables with the following values:


LATEST_COMMIT_HASH_TAG: HEAD

SLACK_MESSAGES: off

MIN_OVERALL_CODE_COVERAGE: 90 (Can be anything from 75 to 100)

CI_CD_PROVIDER: BBPipelines

MAJOR_VERSION: 1

MINOR_VERSION: 0

PATCH: 0

TEST_LEVEL: RunLocalTest or RunSpecifiedTest or RunNoTests

MANIFEST_VERSION: 50

LOGGING_LEVEL: error or warn or info or debug or trace

QA_PACKAGE_DIR: QADir

UAT_PACKAGE_DIR: UATDir

PROD_PACKAGE_DIR: ProdDir

QA_ORG_TYPE: Sandbox

UAT_ORG_TYPE: Sandbox

PROD_ORG_TYPE: Production

QA_ORG_USERNAME: Username for a QA Org user with enough rights to deploy, Create, Read and Update custom settings data, preferably someone like System Administrator

QA_ORG_PASSWORD: Password and Security Token concatenated for the above user 

e.g mySecretPasswordmySecretToken

UAT_ORG_USERNAME: Username for a UAT Org user with enough rights to deploy, Create, Read and Update custom settings data, preferably someone like System Administrator

UAT_ORG_PASSWORD: Password and Security Token concatenated for the above user 

PROD_ORG_USERNAME: Username for a Production Org user with enough rights to deploy, Create, Read and Update custom settings data, and create Scratch Orgs, preferably someone like System Administrator

PROD_ORG_PASSWORD: Password and Security Token concatenated for the above user

4. Configure A Pipeline

As an example, we will configure the Feature Branch Workflow also known as GitHub Flow or GitHub Workflow as part of our CI/CD pipeline. 

You can refer to this visual for the pipeline we are configuring here:

STEPS

In the bitbucket-pipelines.yaml file created above we will start adding pipelines and steps as part of these pipelines

The first pipeline is Pull Request Validation Pipeline:

1

pipelines:

  pull-requests:

      feature/*: #any branch with a feature prefix


#----------------------------Step 1------------------------------------

        - step:

            name: Creating Deployment Package for CI(Continuous Integration)

            script:

              - echo 'Getting Target Org Status From QA/Partial Dev Org'

              - sfDeploymentInfo get -u $QA_ORG_USERNAME -t $QA_ORG_TYPE -i $BITBUCKET_BUILD_NUMBER -n All -s $QA_ORG_PASSWORD

              - echo 'Creating a Git Diff based artifact/package'

              - sfPackages source-combined -p $BITBUCKET_CLONE_DIR/$QA_PACKAGE_DIR -n $LATEST_COMMIT_HASH_TAG -i $BITBUCKET_BUILD_NUMBER || if test $? -eq 21; then exit 0; else exit 1; fi

              - echo 'Scanning Source Code'

              - sfScan pmd-eslint -t "$BITBUCKET_CLONE_DIR/$QA_PACKAGE_DIR/Artifacts/"

            artifacts:

              - QADir/Artifacts/**



Step One

Triggered On: Pull Request from feature branch (Regex ‘feature/*’ can be modified to support trigger from different branches if you wish)


Actions

  1. Creates a delta package based on the last successful deployment commit, which is stored in the target org.
  2. Runs a PMD and ESLint based Static Code Analysis (Currently if any violation with severity 1 is found, the pipeline will fail at this step itself) 
  3. Marks the package created as an artifact to be utilized in later steps


#----------------------------Step 2-------------------------------------


        - step:

            name: Scratch Org Deployment Validation

            script:

              - echo 'Create Scratch Org'

              - sfOrgs createOrg -x 'CIOrg-$BITBUCKET_BUILD_NUMBER' -p ./config/project-scratch-def.json -t $PROD_ORG_TYPE -u $PROD_ORG_USERNAME -s $PROD_ORG_PASSWORD

              - echo 'Create a full deployment artifact/package'

              - sfPackages source-combined -f true -v $MAJOR_VERSION.$MINOR_VERSION.$PATCH.$BITBUCKET_BUILD_NUMBER -p $BITBUCKET_CLONE_DIR -n $LATEST_COMMIT_HASH_TAG || if test $? -eq 21; then exit 0; else exit 1; fi

              - echo 'Deploy the package to Scratch Org'

              - sfDeploy mdapipackage -L $TEST_LEVEL -p $BITBUCKET_CLONE_DIR -a 'CIOrg-$BITBUCKET_BUILD_NUMBER' -v $MAJOR_VERSION.$MINOR_VERSION.$PATCH.$BITBUCKET_BUILD_NUMBER

Step Two

2

Triggered On: Completion of Step 1

Actions: 

  1. Creates a Scratch Org
  2. Creates a full repo package to be deployed to Scratch Org
  3. Deploys the package to the Scratch Org


Special Instructions: For the scratch org creation command which is sfOrgs createOrg, make sure to have a project-scratch-def.json file in the config folder in your repo


Step Three

#-------------------------------Step 3----------------------------------

       

         - step:

            name: Deployment Validation On QA/Partial-Dev Org/Environment

            script:

              - echo 'Getting Target Org Status From QA/Partial Dev Org'

              - sfDeploymentInfo get -u $QA_ORG_USERNAME -t $QA_ORG_TYPE -i $BITBUCKET_BUILD_NUMBER -n All -s $QA_ORG_PASSWORD

              - echo 'Deployment Validation On QA/Partial-Dev Org.'

              - sfDeploy mdapipackage -p $BITBUCKET_CLONE_DIR/$QA_PACKAGE_DIR -c true -u $QA_ORG_USERNAME -s $QA_ORG_PASSWORD -t $QA_ORG_TYPE --successSHA $LATEST_COMMIT_HASH_TAG -i $BITBUCKET_BUILD_NUMBER -l $TEST_LEVEL

            artifacts:

              - QADir/Artifacts/**

3

Triggered On: Completion of Step 2

Actions: Runs a Deployment validation based on the artifact created in Step1 on the QA or a CI Org

Notes:  

  1. You can choose to go with Step 2 or Step 3. If you are not using Scratch Orgs in your development model, you do not need Step 2. If you are using Scratch Orgs and your project is not a huge one and the whole Scratch Org deployment can be done fairly quickly based on your requirements, you can go with both step 2 and step 3. If you have a huge project, Step 2 can be moved to a custom deployment pipeline which can be run daily on a scheduled basis. We will cover this in more details towards the end of this section.
  2. Once this pipeline is green and the code review is done, you are good to merge the feature branch to the main or the master branch.

Now we will define the second pipeline and look into its steps. We can name it Deployment Pipeline.


# Pipeline for the master branch

  branches:

    'main':


#--------------------------------Step 4----------------------------------


      # Automated step as BB Pipeline can not start with a manual step

      - step:

          name: Feature Ready for QA

          script:

             - echo 'Ready for QA'

Step Four

Triggered On: When the feature branch is merged to the main branch

Action: Echoes a custom message.

Special Instructions: This is a dummy step, as BitBucket Pipelines can not start with a manual step and step 5 is a manual or approval based step


4

#QA Org Deployment

      - step:

          name: QA Org Deployment

          deployment: QAOrg

          trigger: manual

          script:

            - echo 'Getting Target Org Status From QA Org'

            - sfDeploymentInfo get -u $QA_ORG_USERNAME -t $QA_ORG_TYPE -i $BITBUCKET_BUILD_NUMBER -n All -s $QA_ORG_PASSWORD

            - echo 'Creating a Git Diff based artifact/package'

            - sfPackages source-combined -p $BITBUCKET_CLONE_DIR/$QA_PACKAGE_DIR -n $LATEST_COMMIT_HASH_TAG -i $BITBUCKET_BUILD_NUMBER || if test $? -eq 21; then exit 0; else exit 1; fi

            - echo 'Deployment On QA Org.'

            - sfDeploy mdapipackage -p $BITBUCKET_CLONE_DIR/$QA_PACKAGE_DIR -u $QA_ORG_USERNAME -s $QA_ORG_PASSWORD -t $QA_ORG_TYPE --successSHA $LATEST_COMMIT_HASH_TAG -i $BITBUCKET_BUILD_NUMBER -l RunLocalTests

5

Step Five

Triggered On: Manual Run/Approval

Action:

  1. Creates a delta package for deployment to QA Org
  2. Deploys the package to QA Org


#--------------------------------Step 6----------------------------------


      - step:

          name: Creating Package for UAT Org Deployment

          trigger: manual

          script:

            - echo Getting Target Org Status from UAT Org

            - sfDeploymentInfo get -u $UAT_ORG_USERNAME -t $UAT_ORG_TYPE -i $BITBUCKET_BUILD_NUMBER -n All -s $UAT_ORG_PASSWORD

            - echo Creating a Git Diff based artifact/package

            - sfPackages source-combined -p $BITBUCKET_CLONE_DIR/$UAT_PACKAGE_DIR -n $LATEST_COMMIT_HASH_TAG -i $BITBUCKET_BUILD_NUMBER || if test $? -eq 21; then exit 0; else exit 1; fi

          artifacts:

            - UATDir/Artifacts/**

Step Six

6

Triggered On: Manual Run/Approval

Action: 

  1. Creates a delta package for deployment to UAT Org
  2. Marks the package as an Artifact to be used in further steps



#--------------------------------Step 7----------------------------------


      - step:

          name: UAT Validation

          script:

            - echo Getting Target Org Status from UAT Org

            - sfDeploymentInfo get -u $UAT_ORG_USERNAME -t $UAT_ORG_TYPE -i $BITBUCKET_BUILD_NUMBER -n All -s $UAT_ORG_PASSWORD

            - echo UAT Org Deployment

            - sfDeploy mdapipackage -p $BITBUCKET_CLONE_DIR/$UAT_PACKAGE_DIR -c true -u $UAT_ORG_USERNAME -s $UAT_ORG_PASSWORD -t $UAT_ORG_TYPE --successSHA $LATEST_COMMIT_HASH_TAG -i $BITBUCKET_BUILD_NUMBER -l RunLocalTests

7

Step Seven

Triggered On: On completion of Step 6

Action: Runs a deployment validation based on the package created in Step 6 on the UAT Org



#---------------------------------Step 8---------------------------------


      - step:

          name: UAT Quick Deployment

          deployment: UATOrg

          trigger: manual

          script:

            - echo Getting Target Org Status from UAT Org

            - sfDeploymentInfo get -u $UAT_ORG_USERNAME -t $UAT_ORG_TYPE -i $BITBUCKET_BUILD_NUMBER -n All -s $UAT_ORG_PASSWORD

            - echo UAT Org Deployment

            - sfDeploy quick-deploy -p $BITBUCKET_CLONE_DIR/$UAT_PACKAGE_DIR -u $UAT_ORG_USERNAME -s $UAT_ORG_PASSWORD -t $UAT_ORG_TYPE --successSHA $LATEST_COMMIT_HASH_TAG -i $BITBUCKET_BUILD_NUMBER

Step Eight

Triggered On: Manual Run/Approval

Action: Runs a deployment based on the package created in Step 6 on the UAT Org



8

#---------------------------------Step 9----------------------------------


      - step:

          name: Creating Package for Prod Org Deployment

          trigger: manual

          script:

            - echo Getting Target Org Status from Prod Org

            - sfDeploymentInfo get -u $PROD_ORG_USERNAME -t $PROD_ORG_TYPE -i $BITBUCKET_BUILD_NUMBER -n All -s $PROD_ORG_PASSWORD

            - echo Creating a Git Diff based artifact/package

            - sfPackages source-combined -p $BITBUCKET_CLONE_DIR/$PROD_PACKAGE_DIR -n $LATEST_COMMIT_HASH_TAG -i $BITBUCKET_BUILD_NUMBER || if test $? -eq 21; then exit 0; else exit 1; fi

          artifacts:

            - ProdDir/Artifacts/**

9

Step Nine

Triggered On: Manual Run/Approval

Action:

  1. Creates a delta package for deployment to Production Org
  2. Marks the package as an Artifact to be used in further steps


#--------------------------------Step 10----------------------------------

       - step:

          name: Prod Validation

          script:

            - echo Getting Target Org Status from Prod Org

            - sfDeploymentInfo get -u $PROD_ORG_USERNAME -t $PROD_ORG_TYPE -i $BITBUCKET_BUILD_NUMBER -n All -s $PROD_ORG_PASSWORD

            - echo UAT Org Deployment

            - sfDeploy mdapipackage -p $BITBUCKET_CLONE_DIR/$PROD_PACKAGE_DIR -c true -u $PROD_ORG_USERNAME -s $PROD_ORG_PASSWORD -t $PROD_ORG_TYPE --successSHA $LATEST_COMMIT_HASH_TAG -i $BITBUCKET_BUILD_NUMBER -l RunLocalTests

Step Ten

Triggered On: On completion of Step 9

Action: Runs a deployment validation based on the package created in Step 9 on the Production Org



10

#--------------------------------Step 11---------------------------------

      

       - step:

          name: Prod Quick Deployment

          deployment: ProdOrg

          trigger: manual

          script:

            - echo Getting Target Org Status from UAT Org

            - sfDeploymentInfo get -u $PROD_ORG_USERNAME -t $PROD_ORG_TYPE -i $BITBUCKET_BUILD_NUMBER -n All -s $PROD_ORG_PASSWORD

            - echo UAT Org Deployment

            - sfDeploy quick-deploy -p $BITBUCKET_CLONE_DIR/$PROD_PACKAGE_DIR -u $PROD_ORG_USERNAME -s $PROD_ORG_PASSWORD -t $PROD_ORG_TYPE --successSHA $LATEST_COMMIT_HASH_TAG -i $BITBUCKET_BUILD_NUMBER

11

Step Eleven

Triggered On: Manual Run/Approval

Action: Runs a deployment based on the package created in Step 9 on the Production Org


With this we are good to save the bitbucket-pipelines.yaml file. You can find the whole file here.


5. Test the pipelines

Finally, we are ready to test the pipelines


Testing PR Validation pipelines: Create a PR from a feature branch to the main branch. This will kick off the PR Validation Pipeline. Make sure that your feature branch is following the naming convention which is feature/<any-valid-name>


e.g. feature/rks-221


Please note that based on the regex we defined in the pipeline YAML file, something like feature/rohan/rks-221 will not work, instead, you have to go with feature/rohan-rks-221 or you have to change the regex in the YAML

                  

Testing Deployment Pipeline: Once the PR validation pipeline is successful and you are happy to merge, merge the feature branch to main. That will kick off the deployment pipeline.

                   

These pipelines can be monitored and checked by clicking on the Pipelines tab and then clicking on the individual pipelines. 


MORE ON CI/CD SERVICES 

What one would you like to see first?

Next time, we will cover how to configure and run the same CI/CD workflow on one of the other CI/CD services: 

Azure DevOps, Circle CI, or GitHub Actions. 

Please feel free to let us know which one would you like to see first or if you have any other questions.


LEARN MORE

 GS DevOps Mate

Copyright © 2021. All rights reserved.