Skip to content

Instantly share code, notes, and snippets.

@mojowen
Last active August 26, 2021 17:34
Show Gist options
  • Save mojowen/0a868385088942974e647fd6d8924cfe to your computer and use it in GitHub Desktop.
Save mojowen/0a868385088942974e647fd6d8924cfe to your computer and use it in GitHub Desktop.
Analyze DORA metrics for gitlab deploys https://gitlab.com/groups/gitlab-org/-/epics/4358
import json
import os
from datetime import datetime, timedelta, timezone
from dateutil import parser
from urllib.parse import quote
import time
import requests
APIKEY = os.getenv("GITLAB_APIKEY", "")
DOMAIN = os.getenv("GITLAB_DOMAIN", "https://gitlab.com")
PROJECT = os.getenv("GITLAB_PROJECT", "")
if not PROJECT:
raise "Missing gitlab project, e.g. zapier/explore"
if not APIKEY:
raise "Missing gitlab api key, visit {}/{}/-/settings/access_tokens".format(
DOMAIN, PROJECT
)
def get_more(since):
return json.loads(
requests.get(
"{}/api/v4/projects/{}/deployments".format(DOMAIN, quote(PROJECT, safe="")),
params={
"environment": "production",
"status": "success",
"sort": "desc",
"updated_before": since,
},
headers={
"Private-Token": APIKEY,
"Accept": "application/json",
"Content-Type": "application/json",
},
).text
)
def get_data(starting, ending):
data = get_more(ending)
last = data[-1]["updated_at"]
while parser.parse(last) > starting:
data += get_more(last)
last = data[-1]["updated_at"]
return [deploy for deploy in data if parser.parse(deploy["created_at"]) > starting]
def workdays_between(starting, ending):
return sum(
1
for day in (
starting + timedelta(x + 1) for x in range((ending - starting).days)
)
if day.weekday() < 5
)
def main():
ending = datetime.today().replace(tzinfo=timezone.utc)
starting = ending - timedelta(days=30)
deploys = get_data(starting, ending)
times_to_deploy = [
(
parser.parse(deploy["deployable"]["finished_at"])
- parser.parse(deploy["deployable"]["commit"]["committed_date"])
).seconds
for deploy in deploys
]
reverts = set(
[
deploy["deployable"]["commit"]["id"]
for deploy in deploys
if "Revert" in deploy["deployable"]["commit"]["message"]
]
)
commits = set([deploy["deployable"]["commit"]["id"] for deploy in deploys])
print("From {} till {}".format(starting.date(), ending.date()))
print("Total deploys: {}".format(len(commits)))
print(
"Deploys per workday: {}".format(
round(len(commits) / workdays_between(starting, ending), 2)
)
)
print(
"Time from merge to deployed: {}".format(
time.strftime("%H:%M:%S", time.gmtime(sum(times_to_deploy) / len(deploys)))
)
)
print(
"Deploys reverted: {}% ({} out of {})".format(
round(len(reverts) / len(commits) * 100.0, 1), len(reverts), len(commits)
)
)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment