npm package: @itentialopensource/prebuilt-promotion-bitbucket-server
Description: Default artifact description
Author: Itential Artifacts
Latest version: 0.0.10-2023.1.6

# Prebuilt Promotion Bitbucket Server

## Table of Contents

- [Prebuilt Promotion Bitbucket Server](#prebuilt-promotion-bitbucket-server)
  - [Table of Contents](#table-of-contents)
  - [Overview](#overview)
  - [Supported IAP Versions](#supported-iap-versions)
  - [Getting Started](#getting-started)
    - [Prerequisites](#prerequisites)
    - [Capabilities](#capabilities)
    - [How to Install](#how-to-install)
    - [Testing](#testing)
  - [Using this Pre-Built](#using-this-pre-built)
    - [Input Schema](#input-schema)
    - [Output Schema](#output-schema)
  - [Additional Information](#additional-information)

## Overview

The **Prebuilt Promotion Bitbucket Server** pre-built is used to push a pre-built to a target Bitbucket Server project preloaded with CI/CD scripts used for promoting and testing the pre-built. It is also used to update an existing pre-built in Bitbucket Server by creating a merge request and promotes the new pre-built directly towards a specified instance of IAP (staging/prod/etc.). This approach assumes one pre-built will be stored in one repository.

**Note**:
This approach will not work for storing multiple pre-builts in one repository. Additionally, the versioning scheme used for this CI/CD process follows versioning documented at [Pre-Built Automation Versioning](https://docs.itential.com/docs/pre-built-repository-setup#prebuilt-automation-versioning-requirements).

- _Estimated Run Time_: ~5 minutes, depending on pre-built complexity

## Supported IAP Versions

Itential pre-builts are built and tested on particular versions of IAP. Please make sure to run on the following version:

- Itential Automation Platform
  - `^2023.1`

## Getting Started

These instructions will help you get a copy of the pre-built in your IAP instance for testing in your environment. Reading this section is also helpful for deployments as it provides you with pertinent information on prerequisites and capabilities.

### Prerequisites

This pre-built requires the following:

- Itential Automation Platform
  - `^2023.1`
- App-Artifacts
  - `^6.5.1-2023.1.0`
- Bitbucket Server
  - `^8.7.0`
- Adapters
  - [Bitbucket Server](https://gitlab.com/itentialopensource/adapters/devops-netops/adapter-bitbucket_server)
  - [Git](https://gitlab.com/itentialopensource/adapters/devops-netops/adapter-git)

Bitbucket_server adapter should be installed into your dev IAP with sample service config shown below:
_Note the delay_between_requests value should be set to atleast 2000 for all IAP instances_

- Under properties.properties:
  - `"host" : "<bitbucket_server_host>"`
  - `"port" : <bitbucket_server_port>`
  - `"version" : ""`
  - `"base_path" : "rest"`
  - `"protocol" : "http"`
  - `"encode_pathvars": false`
- Under properties.properties.authentication:
  - `"auth_method": "basic user_password"`
  - `"username": "***your-email***"`
  - `"password": "***your-password***"`
  - `"token": ""`
  - `"token_timeout": 1800000`
  - `"token_cache": "local"`
  - `"invalid_token_error": 401`
  - `"auth_field": "header.headers.Authorization"`
  - `"auth_field_format": "Basic {b64}{username}:{password}{/b64}"`
- Under properties.properties.request:
  - `"delay_between_requests" : 2000`
  - `"attempt_timeout" : 5000`

Git Adapter should also be installed in your dev IAP with sample service config shown below:
_Note the username and password must match with Bitbucket server's credentials_

- Under properties.properties.authentication:
  - `"auth_method": "basic user_password"`
  - `"username": "***your-Bitbucket-server-email***"`
  - `"password": "***your-Bitbucket-server-password***"`
  - `"token": ""`
  - `"token_timeout": 1800000`
  - `"token_cache": "local"`
  - `"invalid_token_error": 401`
  - `"auth_field": "header.headers.Authorization"`
  - `"auth_field_format": "Basic {b64}{username}:{password}{/b64}"`

In order to connect Jenkins to Bitbucket Server, Bitbucket Server Integration plugin has to be installed. The steps to install and configure this plugin can be found on their documentation page
  https://plugins.jenkins.io/atlassian-bitbucket-server-integration/

A set of Environmental variables should be created before running the Jenkins pipelines. The pipeline uses them to promote the pre-built.

- In Jenkins, click on `Configure System`.
- Under `Global properties` section, check `Environment variables` option.
- When you click on `Add` button, a form with `Name` and `Value` fields appears.
- Define the below Environment variables
  - IAP_HOSTNAME - Host name for the target IAP instance
  - IAP_PUSH_TO_LOCAL - Flag to check if the pre-built should have local repository configuration
  - IAP_SSL_CERT - The SSL certificate if SSL verification is required
  - IAP_USERNAME - Username of the target IAP instance
  - IAP_PW - Password of the target IAP instance
  - PROMOTE - Flag to control promotion of the pre-built. If set to `True` it will promote the pre-built.
- Click `Save`.

### Capabilities

- Commits a pre-built from IAP Admin Essentials to Bitbucket Server.
- In the case of no existing repository:
  - Creates a project if it does not exist
  - Creates a new repository with provided name
  - Adds pipeline scripts and test files to repository
  - Adds bundles folder and manifest.json to repository
  - Starts a new Jenkins pipeline for the repository
- In the case of a repository already existing:
  - Performs rediscover on the pre-built if components are deleted or additional components are added
  - Creates a new branch with name `{MR Type}/{Date&Time}`
  - Deletes bundles folder and manifest.json from new branch
  - Commites new bundles and manifest.json from updated pre-built to new branch
  - Creates a Pull Request with title: `Merge Request created by '{username}'` with new branch targeting branch provided by the operator.
- In the Jenkins environment:
  - A Jenkins pipeline is kicked off when a pull request is raised. The pipeline consists of the below stages:
    - Schema Validation - Validates manifest and manifestTester files against a schema
    - SchemaLink Validation - Validates manifestLinkTester file against a schema
    - Generate - Generates a new artifact.json file with the files present under bundles folder
    - Promote to IAP - Promotes pre-built to a target IAP environment
    - Commit Generated files - Commits generated files to the source branch
  - When a pull request is approved and merged into main or release branches, the same stages are ran as depicted above except for the addition of a Version Bump stage prior to the Generate stage. The Version Bump stage bumps the pre-built's version and appends release note information to CHANGELOG.md file.

### How to Install

To install this pre-built:

- Verify that you are running the documented [prerequisites](#prerequisites) in order to install the pre-built.

- Follow the instructions on the Itential Documentation site for [importing a pre-built](https://docs.itential.com/docs/importing-a-prebuilt-2).

### Testing

While Itential tests this pre-built and its capabilities, it is often the case the customer environments offer their own unique circumstances. Therefore, it is our recommendation that you deploy this pre-built into a development/testing environment in which you can test the pre-built.

## Using this Pre-Built

This pre-built should be run in an [automation](https://docs.itential.com/docs/operations-manager-ui-1).

**Note**: The entry automation to this pre-built is called `Prebuilt Promotion Bitbucket Server`.

When running this pre-built from Operations Manager, refer to the following list of JSON Form inputs. Also the possible outputs from this pre-built are described below.

**Note**: Once a new project is created after running `Prebuilt Promotion Bitbucket Server`, one must manually set up two Jenkins pipelines. Follow the below steps for setting up the two Jenkins pipelines:
   A pipeline job should be created to build for every push to Main and Release branches. The setup steps are as below :

- In Jenkins, click on `New Item` and provide a name and select the type of build as `Pipeline` and then click `OK` to confirm.
- In next screen, under `Build Triggers`, select `Bitbucket webhook trigger`, and select `Push event`.
- In the same screen, under `Pipeline`, select `Pipeline Script from SCM` for `Definition` and `Bitbucket Server` for `SCM`.
- In the same screen, select appropriate `Credentials` for authentication.
- Select the `Bibucket Server instance`, `Project name`, and `Repository name` options.
- Under `Branches to build`, provide `Branch Specifier` as `*/main, /^release/`.
- Under `Script Path`, enter `Jenkinsfile`.
- Click `Save`.
- Another pipeline should be configured to build whenever a pull request is opened, or a push is made to an open pull request. The setup steps are as below:
- In Jenkins, click on `New Item` and provide a name and select the type of build as `Pipeline` and then click `OK` to confirm.
- In next screen, under `Build Triggers`, select `Bitbucket webhook trigger`, and select `Pull request event`.
- In the same screen, under `Pipeline`, select `Pipeline Script from SCM` for `Definition` and `Bitbucket Server` for `SCM`.
- In the same screen, select appropriate `Credentials` for authentication.
- Select the `Bibucket Server instance`, `Project name`, and `Repository name` options.
- Under `Branches to build`, provide `Branch Specifier` as `**`.
- Under `Script Path`, enter `Jenkinsfile_MR`.
- Click `Save`.

### Input Schema

Example input to the trigger form:

```json
{
  "formData": {
    "reDiscoverPrebuilt": false,
    "commitDetails": {
      "commitMessage": "Initial Commit",
      "mrType" : "patch",
      "targetBranch": "main"
    },
    "options": {
      "verbose": true
    },
    "projectKey": "{project_key}",
    "repositoryName": "{repository_name}",
    "repositorySlug": "{repository_slug}",
    "bitbucketServerAdapterInstance": "bitbucket_server",
    "prebuilt": "@local/pre-built-name"
  }
}
```

The following table details the property keys of the input object.
| key                                | type    | required | description                                                  |
|------------------------------------|---------|----------|--------------------------------------------------------------|
| reDiscoverPrebuilt                 | bool    | no       | Grabs new or deleted components from pre-built               |
| commitDetails                      | object  | yes      | Add specific Commit Details                                  |
| commitDetails.commitMessage        | string  | yes      | Commit Message to use for commits to Bitbucket Server        |
| commitDetails.mrType               | string  | no       | Merge Request Type (patch, minor, or major)                  |
| commitDetails.targetBranch         | string  | no       | The branch to target Pre-built changes to (default: main)    |
| options.verbose                    | bool    | no       | Makes the Workflow run in Verbose mode (extra details)       |
| projectKey                         | string  | yes      | Name of Project in Bitbucket Server                          |
| repositoryName                     | string  | yes      | Name of Repository in Bitbucket Server                       |
| repositorySlug                     | string  | yes      | Unique identifier for a repository in Bitbucket Server       |
| bitbucketServerAdapterInstance     | string  | yes      | Name of the Bitbucket Server adapter instance for API calls  |
| prebuilt                           | string  | yes      | Name of pre-built to promote to Bitbucket Sever and Target IAP|

### Output Schema

The `ReturnStatus` job variable returned from the run pre-built workflow `Prebuilt Promotion Bitbucket Server` reports the success or failure of promoting the pre-built to Bitbucket Server.

_Example output for creating repo (SUCCESS):_

```json
{
  "ReturnStatus": {
    "formData": {
      "reDiscoverPrebuilt": false,
      "commitDetails": {
        "commitMessage": "Initial Commit",
        "mrType": "patch",
        "targetBranch": "main"
      },
      "options": {
        "verbose": true
      },
      "projectKey": "{project_key}",
      "repositoryName": "{repository_name}",
      "repositorySlug": "{repository_slug}",
      "bitbucketServerAdapterInstance": "bitbucket_server",
      "prebuilt": "@local/pre-built-name"
    },
    "message": "Repository does not exist. New repository should be created. and Project does not exist. New Project should be created. and Successfully created the project and Successfully created the repository and Successfully retrieved the files from Common-utils and Successfully committed files to the repository",
    "errors": null,
    "status": "SUCCESS",
    "response": {
      "get_repository": {},
      "get_project": {},
      "create_project": {},
      "create_repository": {},
      "gitlab_files": {},
      "edit_files": {}
    }
  }
}
```

_Example output for updating repo (SUCCESS):_

```json
{
  "ReturnStatus": {
    "formData": {
      "reDiscoverPrebuilt": true,
      "commitDetails": {
        "commitMessage": "Delete JST",
        "mrType": "patch",
        "targetBranch": "main"
      },
      "options": {
        "verbose": true
      },
      "projectKey": "{project_key}",
      "repositoryName": "{repository_name}",
      "repositorySlug": "{repository_slug}",
      "bitbucketServerAdapterInstance": "bitbucket_server",
      "prebuilt": "@local/pre-built-name"
    },
    "message": "Successfully retrieved the repository and Successfully retrieved the branch and Successfully created the branch and Successfully retrieved the files and Successfully deleted the files and Successfully committed files to the repository and Successfully retrieved the branch and Successfully created the pull request",
    "errors": null,
    "status": "SUCCESS",
    "response": {
      "get_repository": {},
      "get_branches": {},
      "create_branch": {},
      "stream_files": {},
      "delete_files": {},
      "edit_files": {},
      "create_pull_request": {}
    }
  }
}
```

_Example output for FAILED:_

```json
{
  "ReturnStatus": {
    "formData": {
      "reDiscoverPrebuilt": false,
      "commitDetails": {
        "commitMessage": "Delete JST",
        "mrType": "patch",
        "targetBranch": "main"
      },
      "options": {
        "verbose": true
      },
      "projectKey": "{project_key}",
      "repositoryName": "{repository_name}",
      "repositorySlug": "{repository_slug}",
      "bitbucketServerAdapterInstance": "bitbucket_server",
      "prebuilt": "@local/pre-built-name"
    },
    "status": "FAILED",
    "message": "Failed to retrieve the repository",
    "response": {
      "get_repository": "Cannot forward message to corral:bitbucket_server"
    },
    "errors": [
      {
        "message": "Failed to retrieve the repository",
        "error_details": "Cannot forward message to corral:bitbucket_server"
      }
    ]
  }
}
```

The following table details the property keys of the output ReturnStatus object.
| key                                 |     type        | description                                                        |
|-------------------------------------|-----------------|--------------------------------------------------------------------|
| formData                            |     object      | The input to the workflow                                          |
| message                             |     string      | A message saying which tasks completed and their status            |
| errors                              |     array       | An array of errors that occured during the pre-built promotion run  |
| status                              |     enum        | The status of the over-all workflow (SUCCESS or FAILED)            |
| response                            |     array       | An array consisting of objects which correspond to child workflows |
| response.get_repository             |  object,string  | Response from Get Repository Adapter call                          |
| response.get_project                |  object,string  | Response from Get Project Adapter call                             |
| response.create_project             |  object,string  | Response from Create Project Adapter call                          |
| response.create_repository          |  object,string  | Response from Create Repository Adapter call                       |
| response.gitlab_files               |  object,string  | Response from REST calls to fetch Gitlab files                     |
| response.edit_files                 |  object,string  | Response from Edit Files Adapter call                              |
| response.get_branches               |  object,string  | Response from Get Branches Adapter call                            |
| response.create_branch              |  object,string  | Response from Create Branch Adapter call                           |
| response.stream_files               |  object,string  | Response from Get Stream Files Adapter call                        |
| response.delete_files               |  object,string  | Response from Remove And Push File Adapter call                    |
| response.create_pull_request        |  object,string  | Response from Create Pull Request Adapter call                     |

## Additional Information

Please use your Itential Customer Success account if you need support when using this pre-built.