Skip to content

Instantly share code, notes, and snippets.

@juergenpointinger
Created May 15, 2020 10:46
Show Gist options
  • Save juergenpointinger/6017a655b46ef11f98da8b8933353b77 to your computer and use it in GitHub Desktop.
Save juergenpointinger/6017a655b46ef11f98da8b8933353b77 to your computer and use it in GitHub Desktop.
Statistics for GitLab (Milestone)
# gitlab_statistics.py
import requests
from requests.auth import HTTPBasicAuth
import re
import uuid
import json
import datetime
##############################################################################
## General
# *False* if Jira / GitLab is using self-signed certificates, otherwhise *True*
VERIFY_SSL_CERTIFICATE = True
##############################################################################
## GitLab specifics
# GitLab URL
GITLAB_URL = 'https://gitlab.com/api/v4'
# GitLab token will be used whenever the API is invoked
GITLAB_TOKEN = 'your-private-gitlab-token'
# GitLab group
GITLAB_GROUP = 'your-group-name'
# GitLab group id
GITLAB_GROUP_ID = 'your-group-id'
##############################################################################
# GET request
def gl_get_request(endpoint):
response = requests.get(
GITLAB_URL + endpoint,
headers={'PRIVATE-TOKEN': GITLAB_TOKEN},
verify=VERIFY_SSL_CERTIFICATE
)
if response.status_code != 200:
raise Exception("Unable to read data from '%s'!" % endpoint)
return response.json()
##############################################################################
## Milestone statistics
print("""############################################
### Milestone statistics
############################################""")
milestones = gl_get_request('/groups/%s/milestones?state=active&search=Sprint&per_page=100' % GITLAB_GROUP_ID)
started_milestone = milestones[0]
milestone_title = started_milestone['title']
milestone_description = started_milestone['description']
milestone_start_date = datetime.datetime.strptime(started_milestone['start_date'], '%Y-%m-%d')
milestone_due_date = datetime.datetime.strptime(started_milestone['due_date'], '%Y-%m-%d')
print("Active Milestone: %s (Start: %s, Due: %s)" % (
milestone_title,
milestone_start_date.date(),
milestone_due_date.date()
))
issues = gl_get_request('/groups/%s/issues?milestone=%s&scope=all&per_page=100' % (GITLAB_GROUP_ID, milestone_title))
total_issue_weight = 0
closed_issue_weight = 0
created_issues = 0
updated_issues = 0
for issue in issues:
issue_id = issue['id']
issue_state = issue['state']
# Weights
issue_weight = (issue['weight'] if issue['weight'] is not None else 0)
total_issue_weight += issue_weight
if issue_state == 'closed' and issue_weight > 0:
closed_issue_weight += issue_weight
print("Velocity:\n Total (%s) Closed (%s) Created (%s) Updated (%s)" % (total_issue_weight, closed_issue_weight, created_issues, updated_issues))
## Bugs
bugs_high = gl_get_request('/groups/%s/issues?milestone=%s&labels=Bug::high&scope=all&per_page=100' % (GITLAB_GROUP_ID, milestone_title))
bugs_medium = gl_get_request('/groups/%s/issues?milestone=%s&labels=Bug::medium&scope=all&per_page=100' % (GITLAB_GROUP_ID, milestone_title))
bugs_low = gl_get_request('/groups/%s/issues?milestone=%s&labels=Bug::low&scope=all&per_page=100' % (GITLAB_GROUP_ID, milestone_title))
print("Number of defects found in this sprint:\n High (%s), Medium (%s), Low (%s)" % (len(bugs_high), len(bugs_medium), len(bugs_low)))
## Changed scope
issues_created_after = gl_get_request('/groups/%s/issues?milestone=%s&created_after=%s&scope=all&per_page=100' % (GITLAB_GROUP_ID, milestone_title, milestone_start_date))
issues_updated_after = gl_get_request('/groups/%s/issues?milestone=%s&updated_after=%s&scope=all&per_page=100' % (GITLAB_GROUP_ID, milestone_title, milestone_start_date))
print("Changed scope:\n Created (%s) Updated (%s)" % (len(issues_created_after), len(issues_updated_after)))
##############################################################################
## Pipelines
def pipeline_statistics(project_id, since):
pipelines = gl_get_request('/projects/%s/pipelines?ref=master&per_page=1' % project_id)
if len(pipelines) == 0:
print("No pipeline data avaiable")
return
success_pipelines = gl_get_request('/projects/%s/pipelines?ref=master&status=success&updated_after=%s' % (project_id, since))
failed_pipelines = gl_get_request('/projects/%s/pipelines?ref=master&status=failed&updated_after=%s' % (project_id, since))
print("Pipeline statistics:\n Success (%s) Failed (%s)" % (len(success_pipelines), len(failed_pipelines)))
pipeline_id = pipelines[0]['id']
pipeline = gl_get_request('/projects/%s/pipelines/%s' % (project_id, pipeline_id))
overall_coverage = pipeline['coverage'] if pipeline['coverage'] is not None else 0
print("Code quality:\n Overall Coverage (%s %%)" % overall_coverage)
test_report = gl_get_request('/projects/%s/pipelines/%s/test_report' % (project_id, pipeline_id))
total_count = test_report['total_count']
success_count = test_report['success_count']
failed_count = test_report['failed_count']
skipped_count = test_report['skipped_count']
error_count = test_report['error_count']
print("Tests:\n Total (%s) Success (%s) Failed (%s) Skipped (%s) Error (%s)" % (
total_count,
success_count,
failed_count,
skipped_count,
error_count))
for test_suite in test_report['test_suites']:
test_suite_name = test_suite['name']
test_suite_total_count = test_suite['total_count']
test_suite_success_count = test_suite['success_count']
test_suite_failed_count = test_suite['failed_count']
test_suite_skipped_count = test_suite['skipped_count']
test_suite_error_count = test_suite['error_count']
print(" Test Suite: %s\n Total (%s) Success (%s) Failed (%s) Skipped (%s) Error (%s)" % (
test_suite_name,
test_suite_total_count,
test_suite_success_count,
test_suite_failed_count,
test_suite_skipped_count,
test_suite_error_count))
def get_project_name(project_id):
return gl_get_request('/projects/%s' % project_id)['name']
def project_statistics(project_id, since):
project_name = get_project_name(project_id)
print("Project: %s\n" % project_name)
commits = gl_get_request('/projects/%s/repository/commits?ref_name=master&since=%s&per_page=2000' % (project_id, since))
print("Number of commits: %s" % len(commits))
print("Number of deployments:")
deployments_staging_success = gl_get_request('/projects/%s/deployments?updated_after=%s&status=success&environment=staging' % (project_id, since))
deployments_staging_failed = gl_get_request('/projects/%s/deployments?updated_after=%s&status=failed&environment=staging' % (project_id, since))
print(" Staging: Success (%s), Failed (%s)" % (len(deployments_staging_success), len(deployments_staging_failed)))
deployments_production_success = gl_get_request('/projects/%s/deployments?updated_after=%s&status=success&environment=production' % (project_id, since))
deployments_production_failed = gl_get_request('/projects/%s/deployments?updated_after=%s&status=failed&environment=production' % (project_id, since))
print(" Production: Success (%s), Failed (%s)" % (len(deployments_production_success), len(deployments_production_failed)))
pipeline_statistics(project_id, since)
print("""\n############################################
### Project statistics
############################################""")
project_statistics(your-project-id, milestone_start_date)
@juergenpointinger
Copy link
Author

juergenpointinger commented May 15, 2020

Sample output:

############################################
### Milestone statistics
############################################
Active Milestone: Sprint 1 (Start: 2020-01-01, Due: 2020-01-14)
Velocity:
  Total (68) Closed (4) Created (0) Updated (0)
Number of defects found in this sprint:
  High (2), Medium (2), Low (3)        
Changed scope:
  Created (0) Updated (0)

############################################
### Project statistics
############################################
Project: your-project-name

Number of commits: 18
Number of deployments:
  Staging: Success (8), Failed (1)
  Production: Success (0), Failed (0)
Pipeline statistics:
  Success (8) Failed (0)
Code quality:
  Overall Coverage (25.39 %)
Tests:
  Total (3532) Success (3419) Failed (0) Skipped (113) Error (0)
  Test Suite: commit:test:l0-backend
    Total (2133) Success (2121) Failed (0) Skipped (12) Error (0)
  Test Suite: commit:test:l1-backend
    Total (109) Success (99) Failed (0) Skipped (10) Error (0)
  Test Suite: commit:test:l0-frontend
    Total (1290) Success (1199) Failed (0) Skipped (91) Error (0)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment