How to automate a rollback on failing tests?
Asked by Jared Evans:

I have setup my pipeline to include unit tests and integration tests.

Before deployment of my code, I run unit tests on the code in the pipeline, where if they fail the code will not be deployed. My pipeline looks a little like this:

```
.build_&_test_template: &build_test_template |
  nvm install 18
  nvm use 18
  npm ci
  npm run coverage

pipelines:
? branches:
? ? uat:
? ? ? - step:
 ? ? ? ? ?name: Deploy to UAT
 ? ? ? ? ?deployment: test
 ? ? ? ? ?script:
   ? ? ? ? ?-?*build_test_template
            - *shared_deploy_template
```

So if that *npm run coverage* fails the conditions I have set on my jasmine test configuration, the code will not get to the **shared_deploy_template**.

I have since added an integration step that would run after the code has deployed (**shared_deploy_template**), looking a little like this:

```
.shared_postman_test_template: &shared_postman_test_template |
  npm run postmanTests

pipelines:
? branches:
? ? uat:
? ? ? - step:
        ...
        script:
          - *build_test_template
          - *shared_deploy_template
          - *shared_postman_test_template
```

Now if there are any failures resulting from **shared_postman_test_template**, I'd like to be able to roll back the deployment automatically.

Is there a way to automate the rollback of a deployment based on testing conditions?


Answers:
author: Theodora Boudale
body: Hi Jared,

By rollback of a deployment, I assume that you mean redeploying the last successful deployment?

This should be pretty straightforward to do from the UI, from the **Deployments** page of the repo. If you select an environment on that page, you will see the Environment History and you can Redeploy a specific deployment (this is possible only for 14 days after, for builds that use artifacts). Automating this in Pipelines will require some additional scripting.

You will need to use our APIs to get all deployments to this specific environment:

* <https://developer.atlassian.com/cloud/bitbucket/rest/api-group-deployments/#api-repositories-workspace-repo-slug-deployments-get>

The one with state name IN_PROGRESS should be the one currently running. You can filter by environment in the API call, but I'm afraid that it is not possible to filter by state at the moment, so you could save the API call output to a file and then do the filtering in the file.

Once you get the current deployment, you can find info about the last_successful_deployment in the output and get the commit hash of the last successful deployment.

Then, in your build, you can do a git reset to that commit. If you are deploying only the source code of your repo and not any files you generate during the build, you can deploy that code. Otherwise, if you generate files during the build that need to be deployed, you would need to add to your script code that generates these files from the source code.

Please keep in mind that Pipelines running on branches definitions have a default depth of 50, so only the last 50 commits are cloned. If there is a chance that the last deployment was done more than 50 commits before, you can specify a larger depth number or full depth:

* <https://support.atlassian.com/bitbucket-cloud/docs/git-clone-behavior/#Depth>

It may be a simpler solution to run all the tests in the step before deploying any code.

Kind regards,  
Theodora


Tags: bitbucket-cloud

bitbucket-pipelines

cloud

deployment