Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Trello release status subcommand #6628

Merged
merged 10 commits into from
May 14, 2020
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
from .make import make
from .show import show
from .tag import tag
from .testable import testable
from .trello import trello
from .upload import upload

ALL_COMMANDS = [build, changelog, make, show, tag, testable, upload]
ALL_COMMANDS = [build, changelog, make, show, tag, trello, upload]


@click.group(context_settings=CONTEXT_SETTINGS, short_help='Manage the release of checks')
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# (C) Datadog, Inc. 2020-present
# All rights reserved
# Licensed under a 3-clause BSD style license (see LICENSE)

import click

from ...console import CONTEXT_SETTINGS
from .status import status
from .testable import testable

ALL_COMMANDS = [status, testable]


@click.group(context_settings=CONTEXT_SETTINGS, short_help='Tools for interacting with Trello')
def trello():
"""
Subcommands for interacting with Trello Release boards.

\b
To use Trello:
1. Go to `https://trello.com/app-key` and copy your API key.
2. Run `ddev config set trello.key` and paste your API key.
3. Go to `https://trello.com/1/authorize?key=key&name=name&scope=read,write&expiration=never&response_type=token`,
where `key` is your API key and `name` is the name to give your token, e.g. ReleaseTestingYourName.
Authorize access and copy your token.
4. Run `ddev config set trello.token` and paste your token.
"""
pass


for command in ALL_COMMANDS:
trello.add_command(command)
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# (C) Datadog, Inc. 2018-present
# All rights reserved
# Licensed under a 3-clause BSD style license (see LICENSE)

import json

import click
import pyperclip

from ....trello import TrelloClient
from ...console import CONTEXT_SETTINGS, echo_info, echo_success


@click.command(context_settings=CONTEXT_SETTINGS, short_help='Gather statistics from the Trello release board')
@click.option('--json', '-j', 'as_json', is_flag=True, help='Return as raw JSON instead')
@click.option('--clipboard', '-c', is_flag=True, help='Copy output to clipboard')
@click.pass_context
def status(ctx: click.Context, as_json: bool, clipboard: bool) -> None:
"""Print tabular status of Agent Release based on Trello columns.

See trello subcommand for details on how to setup access:

`ddev release trello -h`.
"""

user_config = ctx.obj
trello = TrelloClient(user_config)

counts = trello.count_by_columns()

row_format = '{:30} | {:<15} | {:<15} | {:<15} | {:<15} | {}'
headers = ('Total', 'In Progress', 'Issues Found', 'Awaiting Build', 'Done')

if as_json:
print(json.dumps(counts, indent=2))
return

totals = dict(zip(headers, [0] * len(headers)))

output = []
output.append(row_format.format('Team', *headers))
output.append(row_format.format('--', *['--' for _ in headers]))

for team, data in counts.items():
for header in headers:
totals[header] += data[header]
row = row_format.format(team, *[data[header] for header in headers])
output.append(row)

output.append(row_format.format('--', *['--' for _ in headers]))
row = row_format.format('TOTALS', *[totals[header] for header in headers])
output.append(row)

out = '\n'.join(output)

msg = '\nTrello Status Report:\n'
if clipboard:
try:
pyperclip.copy(out)
msg = '\nTrello Status Report (copied to your clipboard):\n'
except Exception:
pass

echo_success(msg)
echo_info(out)
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@

import click

from ....subprocess import SubprocessError, run_command
from ....utils import basepath, chdir, get_next
from ...constants import CHANGELOG_LABEL_PREFIX, CHANGELOG_TYPE_NONE, get_root
from ...github import get_pr, get_pr_from_hash, get_pr_labels, get_pr_milestone, parse_pr_number
from ...trello import TrelloClient
from ...utils import format_commit_id
from ..console import CONTEXT_SETTINGS, abort, echo_failure, echo_info, echo_success, echo_waiting, echo_warning
from .....subprocess import SubprocessError, run_command
from .....utils import basepath, chdir, get_next
from ....constants import CHANGELOG_LABEL_PREFIX, CHANGELOG_TYPE_NONE, get_root
from ....github import get_pr, get_pr_from_hash, get_pr_labels, get_pr_milestone, parse_pr_number
from ....trello import TrelloClient
from ....utils import format_commit_id
from ...console import CONTEXT_SETTINGS, abort, echo_failure, echo_info, echo_success, echo_waiting, echo_warning


def create_trello_card(
Expand Down Expand Up @@ -179,15 +179,12 @@ def testable(ctx: click.Context, base_ref: str, target_ref: str, milestone: str,
`github.user`/`github.token` in your config file or use the
`DD_GITHUB_USER`/`DD_GITHUB_TOKEN` environment variables.

\b
To use Trello:
1. Go to `https://trello.com/app-key` and copy your API key.
2. Run `ddev config set trello.key` and paste your API key.
3. Go to `https://trello.com/1/authorize?key=key&name=name&scope=read,write&expiration=never&response_type=token`,
where `key` is your API key and `name` is the name to give your token, e.g. ReleaseTestingYourName.
Authorize access and copy your token.
4. Run `ddev config set trello.token` and paste your token.
"""

See trello subcommand for details on how to setup access:

`ddev release trello -h`.

"""
root = get_root()
repo = basepath(root)
if repo not in ('integrations-core', 'datadog-agent'):
Expand Down
40 changes: 40 additions & 0 deletions datadog_checks_dev/datadog_checks/dev/tooling/trello.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
# (C) Datadog, Inc. 2018-present
# All rights reserved
# Licensed under a 3-clause BSD style license (see LICENSE)

import requests


class TrelloClient:
API_URL = 'https://api.trello.com'
CREATE_ENDPOINT = API_URL + '/1/cards'
BOARD_ENDPOINT = API_URL + '/1/boards/ICjijxr4/cards'
LISTS_ENDPOINT = API_URL + '/1/boards/ICjijxr4/lists'
LABELS_ENDPOINT = API_URL + '/1/boards/ICjijxr4/labels'

def __init__(self, config):
self.auth = {'key': config['trello']['key'] or None, 'token': config['trello']['token'] or None}
Expand Down Expand Up @@ -43,6 +47,12 @@ def __init__(self, config):
'Processes': '5e7910789f92a918152b700d',
'Trace': '5c050640ecb34f0915ec589a',
}
self.progress_columns = {
'55d1fe4cd3192ab85fa0f7ea': 'In Progress', # INPROGRESS
'58f0c271cbf2d534bd626916': 'Issues Found', # HAVE BUGS
'5d5a8a50ca7a0189ae8ac5ac': 'Awaiting Build', # WAITING
'5dfb4eef503607473af708ab': 'Done',
}

def create_card(self, team, name, body, member=None):
rate_limited = False
Expand Down Expand Up @@ -77,3 +87,33 @@ def create_card(self, team, name, body, member=None):
rate_limited = response.status_code == 429

return rate_limited, error, response

def count_by_columns(self):
"""
Gather statistics for each category in the Trello board.

"""
map_label = {v: k for k, v in self.label_map.items()}
map_team_list = {v: k for k, v in self.team_list_map.items()}

counts = {
k: {'Total': 0, 'In Progress': 0, 'Issues Found': 0, 'Awaiting Build': 0, 'Done': 0}
for k in map_label.values()
}

cards = requests.get(self.BOARD_ENDPOINT, params=self.auth)
for card in cards.json():
labels = card.get('labels', [])
for label in labels:
if label['name'] in self.label_map:
team = label['name']
counts[team]['Total'] += 1
id_list = card['idList']
if id_list in map_team_list:
# Team's Inbox
# NOTE: This is "In Progress" but not technically started, yet
counts[team]['In Progress'] += 1
elif id_list == self.progress_columns:
counts[team][id_list] += 1

return counts