Skip to main content

Back-End Development

Automate Release Notes to Confluence with Bitbucket Pipelines

Team Of Young Coworkers Work Together At Night Office.young Woman Using Smartphone At The Table.horizontal.blurred Background.

In this blog post, I will share my journey of implementing an automated solution to publish release notes for service deployments to Confluence using Bitbucket Pipelines. This aimed to streamline our release process and ensure all relevant information was easily accessible to our team. By leveraging tools like Bitbucket and Confluence, we achieved a seamless integration that enhanced our workflow.

Step 1: Setting Up the Pipeline

We configured our Bitbucket pipeline to include a new step for publishing release notes. This involved writing a script in the bitbucket-pipelines.yml file to gather the necessary information (SHA, build number, and summary of updates).

Step 2: Generating Release Notes

We pulled the summary of updates from our commit messages and release notes. To ensure the quality of the summaries, we emphasized the importance of writing detailed and informative commit messages.

Step 3: Publishing to Confluence

Using the Confluence Cloud REST API, we automated the creation of Confluence pages. We made a parent page titled “Releases” and configured the script to publish a new page.

Repository Variables

We used several repository variables to keep sensitive information secure and make the script more maintainable:

  • REPO_TOKEN: The token used to authenticate with the Bitbucket API.
  • CONFLUENCE_USERNAME: The username for Confluence authentication.
  • CONFLUENCE_TOKEN: The token for Confluence authentication.
  • CONFLUENCE_SPACE_KEY: The key to the Confluence space where the release notes are published.
  • CONFLUENCE_ANCESTOR_ID: The ID of the parent page under which new release notes pages are created.
  • CONFLUENCE_API_URL: The URL of the Confluence API endpoint.

Repovariables

Script Details

Here is the script we used in our bitbucket-pipelines.yml file, along with an explanation of each part:

Step 1: Define the Pipeline Step

- step: &release-notes
      name: Publish Release Notes
      image: atlassian/default-image:3
  • Step Name: The step is named “Publish Release Notes”.
  • Docker Image: Uses the atlassian/default-image:3 Docker image for the environment.

Step 2: List Files

script:
  - ls -la /src/main/resources/
  • List Files: The ls -la command lists the files in the specified directory to ensure the necessary files are present.

Step 3: Extract Release Number

- RELEASE_NUMBER=$(grep '{application_name}.version' /src/main/resources/application.properties | cut -d'=' -f2)
  • Extract Release Number: The grep command extracts the release number from the application.properties file where the property {application_name}.version should be present.

Step 4: Create Release Title

- RELEASE_TITLE="Release - $RELEASE_NUMBER Build- $BITBUCKET_BUILD_NUMBER Commit- $BITBUCKET_COMMIT"
  • Create Release Title: Construct the release title using the release number, Bitbucket build number, and commit SHA.

Step 5: Get Commit Message

- COMMIT_MESSAGE=$(git log --format=%B -n 1 ${BITBUCKET_COMMIT})
  • Get Commit Message: The git log command retrieves the commit message for the current commit.

Step 6: Check for Pull Request

- |
  if [[ $COMMIT_MESSAGE =~ pull\ request\ #([0-9]+) ]]; then
    PR_NUMBER=$(echo "$COMMIT_MESSAGE" | grep -o -E 'pull\ request\ \#([0-9]+)' | sed 's/[^0-9]*//g')
  • Check for Pull Request: The script checks if the commit message contains a pull request number.
  • Extract PR Number: If a pull request number is found, it is extracted using grep and sed.

Step 7: Fetch Pull Request Description

RAW_RESPONSE=$(wget --no-hsts -qO- --header="Authorization: Bearer $REPO_TOKEN" "https://api.bitbucket.org/2.0/repositories/$BITBUCKET_WORKSPACE/$BITBUCKET_REPO_SLUG/pullrequests/${PR_NUMBER}")
PR_DESCRIPTION=$(echo "$RAW_RESPONSE" | jq -r '.description')
echo "$PR_DESCRIPTION" > description.txt
  • Fetch PR Description: Uses wget to fetch the pull request description from the Bitbucket API.
  • Parse Description: Parses the description using jq and saves it to description.txt.

Step 8: Prepare JSON Data

 AUTH_HEADER=$(echo -n "$CONFLUENCE_USERNAME:$CONFLUENCE_TOKEN" | base64 | tr -d '\n')
 JSON_DATA=$(jq -n --arg title "$RELEASE_TITLE" \
                    --arg type "page" \
                    --arg space_key "$CONFLUENCE_SPACE_KEY" \
                    --arg ancestor_id "$CONFLUENCE_ANCESTOR_ID" \
                    --rawfile pr_description description.txt \
                    '{
                      title: $title,
                      type: $type,
                      space: {
                        key: $space_key
                      },
                      ancestors: [{
                        id: ($ancestor_id | tonumber)
                      }],
                      body: {
                        storage: {
                          value: $pr_description,
                          representation: "storage"
                        }
                      }
                    }')
  echo "$JSON_DATA" > json_data.txt
  • Prepare Auth Header: Encodes the Confluence username and token for authentication.
  • Construct JSON Payload: Uses jq to construct the JSON payload for the Confluence API request.
  • Save JSON Data: Saves the JSON payload to json_data.txt.

Step 9: Publish to Confluence

  wget --no-hsts --method=POST --header="Content-Type: application/json" \
      --header="Authorization: Basic $AUTH_HEADER" \
      --body-file="json_data.txt" \
      "$CONFLUENCE_API_URL" -q -O -
  if [[ $? -ne 0 ]]; then
    echo "HTTP request failed"
    exit 1
  fi
  • Send POST Request: This method uses wget to send a POST request to the Confluence API to create or update the release notes page.
  • Error Handling: Checks if the HTTP request failed and exits with an error message if it did.

Script

# Service for publishing release notes
- step: &release-notes
      name: Publish Release Notes
      image: atlassian/default-image:3
      script:
        - ls -la /src/main/resources/
        - RELEASE_NUMBER=$(grep '{application_name}.version' /src/main/resources/application.properties | cut -d'=' -f2)
        - RELEASE_TITLE="Release - $RELEASE_NUMBER Build- $BITBUCKET_BUILD_NUMBER Commit- $BITBUCKET_COMMIT"
        - COMMIT_MESSAGE=$(git log --format=%B -n 1 ${BITBUCKET_COMMIT})
        - |
          if [[ $COMMIT_MESSAGE =~ pull\ request\ #([0-9]+) ]]; then
            PR_NUMBER=$(echo "$COMMIT_MESSAGE" | grep -o -E 'pull\ request\ \#([0-9]+)' | sed 's/[^0-9]*//g')
            RAW_RESPONSE=$(wget --no-hsts -qO- --header="Authorization: Bearer $REPO_TOKEN" "https://api.bitbucket.org/2.0/repositories/$BITBUCKET_WORKSPACE/$BITBUCKET_REPO_SLUG/pullrequests/${PR_NUMBER}")
            PR_DESCRIPTION=$(echo "$RAW_RESPONSE" | jq -r '.description')
            echo "$PR_DESCRIPTION" > description.txt
            AUTH_HEADER=$(echo -n "$CONFLUENCE_USERNAME:$CONFLUENCE_TOKEN" | base64 | tr -d '\n')
            JSON_DATA=$(jq -n --arg title "$RELEASE_TITLE" \
                              --arg type "page" \
                              --arg space_key "$CONFLUENCE_SPACE_KEY" \
                              --arg ancestor_id "$CONFLUENCE_ANCESTOR_ID" \
                              --rawfile pr_description description.txt \
                              '{
                                title: $title,
                                type: $type,
                                space: {
                                  key: $space_key
                                },
                                ancestors: [{
                                  id: ($ancestor_id | tonumber)
                                }],
                                body: {
                                  storage: {
                                    value: $pr_description,
                                    representation: "storage"
                                  }
                                }
                              }')
            echo "$JSON_DATA" > json_data.txt
            wget --no-hsts --method=POST --header="Content-Type: application/json" \
              --header="Authorization: Basic $AUTH_HEADER" \
              --body-file="json_data.txt" \
              "$CONFLUENCE_API_URL" -q -O -
            if [[ $? -ne 0 ]]; then
              echo "HTTP request failed"
              exit 1
            fi
          fi

Confluence_page
Outcomes and Benefits

  • The automation significantly reduced the manual effort required to publish release notes.
  • The project improved our overall release process efficiency and documentation quality.

Conclusion

Automating the publication of release notes to Confluence using Bitbucket Pipelines has been a game-changer for our team. It has streamlined our release process and ensured all relevant information is readily available. I hope this blog post provides insights and inspiration for others looking to implement similar solutions.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Punam Khond

Punam Khond is a Technical Consultant at Perficient with diverse experience in software development. She excels at solving complex problems and delivering high-quality solutions. Punam is passionate about technology and enjoys collaborating with teams and continuously exploring new innovations.

More from this Author

Follow Us