Bitbucket Analytics: Why, What and How to Use

October 4, 2022
#Bitbucket#Reporting#Analytics
7 min

It’s no secret that the business world has adapted to making decisions based on data. We analyze conversion and churn rates, track the number of active users and average revenue. We know how much we spend on advertising and how it correlates with web traffic growth.

But what about software development? In contrast to sales and marketing, the world of software engineering is less familiar with the same approaches, and all project development data remains hidden within repository management tools like Github, Gitlab, Bitbucket. It is widespread for software development decisions to be based on theory, instincts, experiments, or gut feelings. Sometimes they are backed up by a few numbers on commits or pull requests, but it is always tedious and time-consuming. Besides, it sometimes causes data errors due to manual work.

A combination of all of these factors can negatively impact the development of any product, leading to:

  • Hidden inefficiencies and costs as invisible bottlenecks hamper team performance and productivity
  • Inability to determine if everyone is on the right track due to lack of transparency and visibility in projects and teams
  • Investing time in manual work instead of new ideas, core tasks, or favorite activities
  • Slow development velocity, missed deadlines, and disappointed stakeholders

And it is up to everyone to decide how long this list should continue.

To simplify work and make processes of software development more transparent many organizations rely on a data-driven approach and comprehensive analytics of commits and pull requests.


64% of companies mark that improved efficiency and productivity as the top benefit of data analytics, while 56% say about faster, more effective decision-making

Source: Finance Online


What is a data-driven approach in software engineering?

Data-driven development means using and analyzing commits and pull request data as a primary source of information for decision-making. In this approach, engineering processes are viewed from a transparent, accurate, and unbiased perspective by defining and using metrics such as KPIs or OKRs. It lets everyone know where the business is moving and how personal work contributes to its success.

However, despite focusing on raw numbers and statistics, data-driven development also relies on people. It is not enough to count lines of code, the number of commits and pull requests, or to determine how long it takes to resolve pull requests. To be successful, metrics-based approaches need individuals and teams to understand the data, analyze it, and use it for continuous learning and improvement.

What are the pros of using data in software development management?

1) Processes transparency and optimization

Collecting and analyzing commits and pull request data on an ongoing basis gives engineering managers a clear view of what is going on in projects and within their teams. It helps to explore similar patterns and find ways to improve them.

2) Predictability of development and time-to-market

Graphs and reports empower teams to find hidden inefficiencies, resolve everyday challenges, and speed up the development process without affecting code quality. It helps reduce time-to-market and deliver on promises.

3) Informed decision-making based on well-rounded insights

Analyzing real-time data with past patterns and getting deeper insights across project development can confirm a new strategy’s success or force you to revisit your choices.

4) Keeping everyone on the same page

Providing greater visibility into in-progress work and enabling developers to see the impact of their efforts on overall project success ensures the commitment of team members as well as keeps them motivated and moving in the right direction.

How to implement a data-driven approach in Bitbucket?

Bitbucket is a real storehouse of information on everything happening inside engineering processes. Unlocking it is all that is required to identify bottlenecks, understand why things go wrong, and find solutions. Unfortunately, Bitbucket does not provide any functionality that allows getting a quick overview of what is happening on projects and within teams.

Here come data-driven apps like Awesome Graphs for Bitbucket that automatically pull data from Git repositories and empower data-driven software management.

Awesome Graphs for Bitbucket helps engineering managers to monitor and measure the activity of the projects and developers from the whole Bitbucket by transforming invisible development activities into easy-to-understand insights and reports. Apart from this, the app:

  • seamlessly integrates into Bitbucket and displays data on the client’s side. No need to expose your source code outside Bitbucket or worry about security issues
  • gives a lot of out-of-the-box reports without requiring complex configuration and additional analytics knowledge
  • exports data to a CSV file or via REST API to create custom graphs or dashboards and merge them with the data from other apps

When using Awesome Graphs for Bitbucket, project planning becomes more accurate since it provides an overview of the project’s dynamics and helps to identify bottlenecks that hold teams back. Apart from this, it is possible to track how your team’s productivity increases compared to the previous period, view the engineering contribution for each repository and project, or recognize hidden talents.

Start a 30-day free trial to discover analytics’s benefits to your projects and teams.

 

Get Even Awesomer Graphs for Your Bitbucket Cloud

September 6, 2022
#News#Bitbucket
4 min

In Bitbucket Cloud, behavior of apps is defined by the app context. There are two app contexts: personal and workspace.

  • With the personal context, you can use the app in all repositories to which you have access, but other users can’t use the app installed by you.
  • With the workspace context, you can use the app only in repositories in a specific workspace the app was installed in, so all users who have access to the workspace can use the app without installing it.

It’s time to move to something new

At the moment, the Awesome Graphs for Bitbucket Cloud has separate versions of the app for each of the contexts.

We’ve been working hard on the development of both versions, but have decided to focus solely on the workspace context version, as it provides us with more opportunities to make an overall better app for the users.

It’s a bit different, but much better

The new version is installed to a particular workspace and available to everyone who’s got access to it.

The transition of the app context allowed us to extend the app’s capabilities and add new features, improve security and an overall experience.

Just to name a few, here’s what’s already in the new version:

  • Graphs and Reports are available for whole workspaces as well as individual repos
  • Lines of code statistics in addition to commits stats
  • New approach to the rate limits resulting in better app stability
  • Bug fixes and minor improvements here and there

Should you do anything at all?

If you’re not sure, which version of the app you’ve been using and if you need to do anything at all, you can check it the Workspace settings → Manage Installed apps:

  • The old one has the old three-color logo and the installation context is personal. If that’s what you have, then read further, and we’ll show you what to do.
  • If you have an orange and white logo app with workspace context, then you are using “the right” version already — good for you!

manage installed apps in Bitbucket

How to get the “right one”?

Rather than going through a complex migration scheme, you just need to install the new app to your workspace — one click, and you’re all set.

P.S. Don’t forget to uninstall the old one. (smile)

What’ll happen to the old version?

The personal context version of the app will be deprecated and no longer maintained after November 1, 2022, so hurry up and install the new app to your workspace now!

In case you need assistance or have any questions, please feel free to contact us.

Analyze How Code Review is Going in Bitbucket Data Center

September 27, 2021
#How To#Bitbucket#Analytics
9 min

Awesome Graphs is one of our most popular apps. It’s a solution that extends Bitbucket, a platform that teams use to host Git repositories and collaborate on code.

Awesome Graphs helps engineering leaders and software teams improve their own processes and deliver products faster by transforming invisible development activities into easy-to-understand insights and reports.

One of the keys focuses of the app is the code review processes analytics. We would like to tell you which features support this use case and how you can benefit from the app. Keep reading if you are interested in:

  • Seeing how actively your team members review code
  • Analyzing what developers may need to improve their work patterns and who’s doing a great job
  • Learning what reviewers are most active and diligent
  • Knowing the average time taken to resolve pull requests.

Code review analysis

code review analysis in bitbucket

The Contributions Report analyzes activity in pull requests (tasks, comments, needs work/approved/declined statuses). It helps you understand:

  • What developers create high-quality code and who might need to improve their approach to work. E.g. when an engineer has fewer taskscomments, and needs work flags in their pull requests, it suggests his work is approved as it is or with minor changes and he creates code of high quality.
  • What reviewers are thorough when they review the work of developers. E.g. diligent reviewers come up with suggestions and improvements, so they have more tasks and comments than others.
  • How the dynamics of code review changes over time. E.g. you can see if the number of pull requests with Needs work flags is getting bigger or smaller if the number of tasks in pull requests is increasing or decreasing over time.

Learn more

The average time taken to resolve pull requests

pull requests resolution time report in bitbucket

Another report, Resolution Time Report, shows the average time taken to resolve pull requests. This is helpful to capture trends in resolution time. It displays resolution times of merged and declined pull requests separately. With this report you can:

  • Notice spikes in resolution time and then dive in to see what went wrong
  • See if an average resolution time is high for a long period of time – it can be a signal to look into your code review process and determine what causes delays
  • Monitor how changes in your processes affect the speed of code review.

Learn more

Knowledge sharing indicators

reviewers of pull requests report in bitbucket

The Pie Chart Report is a handy way to check if all developers in your team are involved in the code review. This report shows the breakdown of pull requests by different statistics types.

Grouped by reviewer, the Pie Chart Report shows the following:

  • How many pull requests each person reviewed. These metrics help understand how much everyone contributes to the project.
  • Whether all people review code or there are one or two who are doing all job. This is an indicator of poor knowledge sharing.
  • Who is too busy reviewing all pull requests of their team. These people can become a bottleneck that slows the delivery time, because they’re not available for immediate review.

Learn more

Pull requests with a too long or too short resolution time

pull requests resolution time report in bitbucket

The Resolution Time Distribution Report visualizes pull requests grouped by the time taken to merge or decline them and gives an idea of the most frequent resolution times on your project. Using this report. you can easily:

  • find pull requests with the longest resolution time to check the reasons for the delay
  • see pull requests with the shortest time to resolve them to investigate whether they were checked as appropriate
  • predict the resolution time for the future pull requests.

Learn more

Exporting pull requests for the future processing

With Awesome Graphs, the historical data can be exported to a CSV file right on the People page.

exporting pull requests from bitbucket

As a result of the exporting, you receive the CSV file with the list of pull requests (alternatively, the list of commits) with their details about the author, reviewers, state, the date they were created and last updated. The files can be processed in Excel or integrated with analytics tools like Tableau, Power BI, etc. to create custom graphs and dashboards and merge with the data from other apps.

Learn more

What other reports do you need?

Awesome Graphs already has a wide range of graphs and reports that help you answer various questions about project development and the work of your team in Bitbucket. We are open to your feedback and appreciate hearing about what you need. So if you have a problem that you think Awesome Graphs can help you with, contact us – we actually listen.

Try Awesome Graphs for free

 

Pull Request Analytics: How to Visualize Cycle Time / Lead Time and Get Insights for Improvement

March 30, 2021
#How To#Bitbucket#Reporting
12 min

Cycle Time / Lead Time is one of the most important metrics for software development. It can tell a lot about the efficiency of the development process and the teams’ speed and capacity. In the previous article, we showed you how to get a detailed report with the pull request statistics and Cycle Time / Lead Time calculated on the repository level. 

Today we’ll tell you how to use this report:

  • How to visualize the pull request data.
  • What things to pay attention to.
  • What insights you can get to improve performance.

Please note that we define Cycle Time / Lead Time as the time between the developer’s first commit and the time it’s merged and will refer to it as Cycle Time throughout the article.

Analyzing your codebase

First, you need to understand the current state of affairs and how it compares to the industry standards. According to the Code Climate’s research, the industry-wide median for Cycle Time is 3.4 days, with only the top 25% managing to keep it as low as 1.8 days and the bottom 25% having a Cycle Time of 6.2 days.

© Code Climate

To get a better understanding of the development process, it might be helpful to look at the teams’ dynamics and monitor the changes over time. The following chart shows how the average Cycle Time changes month after month with a trend line, so you can see objectively whether the development process is getting faster or slower and check how your rates compare to the industry average. Follow the instructions to build this chart.

For a more precise analysis and evaluation of the current code base, you can also use the Cycle Time distribution chart that provides pull request statistics aggregated by their Cycle time value, making it easy to spot the outliers for further investigation. Learn how to build this chart.

In addition to the Cycle Time, Awesome Graphs for Bitbucket lets you analyze the pull request resolution time out-of-the-box. Using the Resolution Time Distribution report, you can see how long it takes pull requests to merge or decline, find the shortest and longest pull requests, and predict the resolution time of future pull requests with the historical data.

While Cycle Time serves as a great indicator of success and, keeping it low, you can increase the output and efficiency of your teams, it’s not diagnostic by itself and can’t really tell what you are doing right or wrong. To understand why it is high or low, you’ll need to dig deeper into the metrics it consists of. The chart below gives you a general overview of the pull requests on the repository level and shows the Cycle Time with the percentage of the stages it’s comprised of (which we’ll discuss in detail in the following paragraphs). You can build a chart like this using the Chart from Table macro, available in the Table Filter and Charts app.

Breaking down the Cycle Time

We break down Cycle Time into four stages:

  • Time to open (from the first commit to open)
  • Time waiting for review (from open to the first comment)
  • Time to approve (from the first comment to approved)
  • Time to merge (from approved to merge)

Now we’ll go through each of these stages, discussing the things to pay attention to.

Time to Open

This metric is arguably the most important of all, as it influences all the later stages and, according to the research, pull requests that open faster tend to merge faster.

Long Time to Open might indicate that the developer had to switch tasks and/or that code was rewritten, which might also result in large batch sizes. In one of the previous articles, we described how you can check the size of your pull requests in Bitbucket, so you can also use it for a deeper analysis.

One of the things you can do to improve your Time to Open is to decrease the pull request size to be no more than 200 to 400 lines of code. Thus you’ll influence each stage of the cycle, as the smaller pull requests are more likely to be reviewed more thoroughly and be approved sooner.

Time to Review

Time to Review is a great metric to understand if your teams adopted Code Review as part of the daily routine. If it’s high, then it might not be part of their habit, and you’ll need to foster this culture. Another reason might be that the pull requests are not review-friendly and the reviewers procrastinate dealing with them. You can change this, once again, by keeping the pull request size small and by writing a reasonable description so it’s easier to get started with them. If the long Time to Review rate is caused by organizational issues, then it might require reprioritization.

Time to Approve

This is the stage you don’t really want to minimize but rather make it consistent by reducing inefficiencies in the code review process. While there are many strategies for Code Review, there is hardly any industry standard for Code Review metrics, so you’ll need to focus on the organization of the process and try to find a way to get constructive feedback.

Time to Merge

Long Time to Merge might be an indicator that there are obstacles in the delivery workflow. To improve it, you need to find out if there are any blockers in the process, including manual deployment, and check if your tooling satisfies your current needs.

Wrapping up

Cycle Time’s importance is difficult to overestimate, as this metric can tell a lot about the way you work, and controlling it, you can optimize the development process and deliver faster.

Once again, we built the initial pull request report with the help of the Awesome Graphs for Bitbucket app as a data provider and used the Table Filter and Charts for Confluence app to aggregate and visualize the data.

These are just a few examples, but you can get much more even from this one report. Check out the other guides for charts based on data from Bitbucket. Share your feedback and ideas in the comments, and we’ll try to cover them in future posts.

Pull Request Analytics: How to Get Pull Request Cycle Time / Lead Time for Bitbucket

March 23, 2021
#Reporting#How To#Bitbucket
13 min

What Cycle Time is and why it is important

Pull Request Cycle Time / Lead Time is a powerful metric to look at while evaluating the engineering teams’ productivity. It helps track the development process from the first moment the code was written in a developer’s IDE and up to the time it’s deployed to production.

Please note that we define Cycle Time / Lead Time as the time between the developer’s first commit and the time it’s merged and will refer to it as Cycle Time throughout the article.

Having this information, you can get an unbiased view of the engineering department’s speed and capacity and find the points to drive improvement. It can also be an indicator of business success as, by controlling the Cycle Time, you can increase the output and efficiency to deliver products faster.

This article will show you how to get a detailed pull request report with the Cycle Time and the related metrics calculated on the repository level. The metrics include:

  • Time to open (from the first commit to open)
  • Time waiting for review (from open to the first comment)
  • Time to approve (from the first comment to approved)
  • Time to merge (from approved to merge)

How to get Time to Open, Time to Review, Time to Approve, and Time to Merge metrics

We can get all the necessary pull request data from Awesome Graphs for Bitbucket and its REST API combined with Bitbucket’s REST API resources. We’ll use Python to make requests into the APIs, calculate and aggregate this data and then save it as a CSV file, like this:

The following script will do all this work for us:

</p>
import sys
import requests
import csv
from dateutil import parser
from datetime import datetime
 
bitbucket_url = sys.argv[1]
login = sys.argv[2]
password = sys.argv[3]
project = sys.argv[4]
repository = sys.argv[5]
since = sys.argv[6]
until = sys.argv[7]
 
s = requests.Session()
s.auth = (login, password)
 
 
class PullRequest:
 
    def __init__(self, pr_id, title, author, state, created, closed):
        self.pr_id = pr_id
        self.title = title
        self.author = author
        self.state = state
        self.created = created
        self.closed = closed
 
 
def parse_date_ag_rest(date):
    return parser.isoparse(date).replace(tzinfo=None, microsecond=0)
 
 
def get_date_from_timestamp(timestamp):
    return datetime.fromtimestamp(timestamp / 1000).replace(microsecond=0)
 
 
def subtract_dates(minuend, subtrahend):
    if minuend is None or subtrahend is None:
        return None
    else:
        return round(((minuend - subtrahend).total_seconds() / 86400), 2)
 
 
def get_pull_requests():
 
    pull_request_list = []
 
    get_prs_url = bitbucket_url + '/rest/awesome-graphs-api/latest/projects/' + project + '/repos/' + repository \
        + '/pull-requests'
 
    is_last_page = False
 
    while not is_last_page:
 
        response = s.get(get_prs_url, params={'start': len(pull_request_list), 'limit': 1000,
                                              'sinceDate': since, 'untilDate': until}).json()
 
        for pr_details in response['values']:
 
            pd_id = pr_details['id']
            title = pr_details['title']
            author = pr_details['author']['user']['emailAddress']
            state = pr_details['state']
            created = parse_date_ag_rest(pr_details['createdDate'])
 
            if pr_details['closed'] is True:
                closed = parse_date_ag_rest(pr_details['closedDate'])
            else:
                closed = None
 
            pull_request_list.append(PullRequest(pd_id, title, author, state, created, closed))
 
        is_last_page = response['isLastPage']
 
    return pull_request_list
 
 
def get_first_commit_time(pull_request):
 
    commit_dates = []
 
    commits_url = bitbucket_url + '/rest/api/latest/projects/' + project + '/repos/' + repository + '/pull-requests/' \
        + str(pull_request.pr_id) + '/commits'
 
    is_last_page = False
 
    while not is_last_page:
 
        commits_response = s.get(commits_url, params={'start': len(commit_dates), 'limit': 500}).json()
 
        for commit in commits_response['values']:
            commit_timestamp = commit['authorTimestamp']
            commit_dates.append(get_date_from_timestamp(commit_timestamp))
 
        is_last_page = commits_response['isLastPage']
 
    if not commit_dates:
        first_commit = None
    else:
        first_commit = commit_dates[-1]
 
    return first_commit
 
 
def get_pr_activities(pull_request):
 
    counter = 0
    comment_dates = []
    approval_dates = []
 
    pr_url = bitbucket_url + '/rest/api/latest/projects/' + project + '/repos/' + repository + '/pull-requests/' \
        + str(pull_request.pr_id) + '/activities'
 
    is_last_page = False
 
    while not is_last_page:
 
        pr_response = s.get(pr_url, params={'start': counter, 'limit': 500}).json()
 
        for pr_activity in pr_response['values']:
 
            counter += 1
 
            if pr_activity['action'] == 'COMMENTED':
                comment_timestamp = pr_activity['comment']['createdDate']
                comment_dates.append(get_date_from_timestamp(comment_timestamp))
            elif pr_activity['action'] == 'APPROVED':
                approval_timestamp = pr_activity['createdDate']
                approval_dates.append(get_date_from_timestamp(approval_timestamp))
 
            is_last_page = pr_response['isLastPage']
 
    if not comment_dates:
        first_comment_date = None
    else:
        first_comment_date = comment_dates[-1]
 
    if not approval_dates:
        approval_time = None
    else:
        approval_time = approval_dates[0]
 
    return first_comment_date, approval_time
 
 
print('Collecting a list of pull requests from the repository', repository)
 
with open(f'{project}_{repository}_prs_cycle_time_{since}_{until}.csv', mode='a', newline='') as report_file:
    report_writer = csv.writer(report_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
    report_writer.writerow(['id',
                            'title',
                            'author',
                            'state',
                            'first_commit',
                            'created',
                            'first_comment',
                            'approved',
                            'closed',
                            'cycle_time_d',
                            'time_to_open_d',
                            'time_to_review_d',
                            'time_to_approve_d',
                            'time_to_merge_d'])
 
    for pull_request in get_pull_requests():
 
        print('Processing pull request', pull_request.pr_id)
 
        first_commit_time = get_first_commit_time(pull_request)
 
        first_comment, approval = get_pr_activities(pull_request)
 
        cycle_time = subtract_dates(pull_request.closed, first_commit_time)
 
        time_to_open = subtract_dates(pull_request.created, first_commit_time)
 
        time_to_review = subtract_dates(first_comment, pull_request.created)
 
        time_to_approve = subtract_dates(approval, first_comment)
 
        time_to_merge = subtract_dates(pull_request.closed, approval)
 
        report_writer.writerow([pull_request.pr_id,
                                pull_request.title,
                                pull_request.author,
                                pull_request.state,
                                first_commit_time,
                                pull_request.created,
                                first_comment,
                                approval,
                                pull_request.closed,
                                cycle_time,
                                time_to_open,
                                time_to_review,
                                time_to_approve,
                                time_to_merge])
 
print('The resulting CSV file is saved to the current folder.')
<p>

To make this script work, you’ll need to pre-install the requests and dateutil modules. The csvsys, and datetime modules are available in Python out of the box. You need to pass the following arguments to the script when executed:

  • the URL of your Bitbucket, 
  • login, 
  • password, 
  • project key, 
  • repository slug, 
  • since date (to include PRs created after), 
  • until date (to include PRs created before).

Here’s an example:

py script.py https://bitbucket.your-company-name.com login password PRKEY repo-slug 2020-11-30 2021-02-01

Once the script’s executed, the resulting file will be saved to the same folder as the script.

What to do with the report

After you generated a CSV file, you can process it in analytics tools such as Tableau, PowerBI, Qlik, Looker, visualize this data on your Confluence pages with the Table Filter and Charts for Confluence app, or integrate it in any custom solution of your choice for further analysis. 

An example of the data visualized with Table Filter and Charts for Confluence.

By measuring Cycle Time, you can:

  • See objectively whether the development process is getting faster or slower.
  • Analyze the correlation of the specific metrics with the overall cycle time (e.g., pull requests that open faster, merge faster).
  • Compare the results of the particular teams and users within the organization or across the industry.

What’s next?

The report described in this article is built with the help of the Awesome Graphs for Bitbucket app as a data provider, available for Bitbucket Server and Data Center. Using it, you can gain more visibility into the development process to analyze patterns and find bottlenecks.

If you want to learn more about how to use Cycle Time and the related metrics, write in the comments below and upvote this post, and we’ll show you how to visualize the data, what to look at and how to get insights from it in the future posts!

Announcing New Stiltsoft Partner Program

March 22, 2021
#News
2 min

At Stiltsoft, we recognize how important both our partners and customers are, so we decided to launch our new Partner Program that will affect only the Awesome Graphs for Bitbucket app.

We are building a new Partner Program to provide you with comprehensive training materials and resources, free app licenses, promo codes, and more. If you apply, you save time and effort of your sales team with the help of our training course and demos on demand.

We want to inform you that Awesome Graphs for Bitbucket has Standard Atlassian Partner Discount until March 21st, 2021. From March 22nd, a 20% discount will only be available for Stiltsoft Partners.

Other Stiltsoft apps participate in the Standard Discount scheme for Atlassian Marketplace Products.

To get a 20% discount, you will need to become our partner. Moreover, you will get other partnership perks:

  • Free licenses
  • Demo on demand
  • Promo codes
  • Enablement materials
  • App training
  • Co-marketing activities

To join, simply drop an email at partner@stiltsoft.com, and we will get you set up as soon as possible. For more details, please visit our website.

We look forward to continued collaboration!