def get_activity(self, params): """ Takes time entries in format and reports them into destinatin set in config. Entries are in following format: >>> (Record(date=datatime, comment="activity comment", task="TaskID"), ... ...) """ jira = JIRA( params['server'], basic_auth=(params['uname'], params['pswd'])) # check issues assigned on user and is in targeted statuses, or status was chened in given period # TODO: dates seems to be random... statuses = ("Code Review", "In Progress") subquery_item = '(status CHANGED during ("{after}", "{before}") TO "{status}" and assignee = "{user}")' subquery = " or ".join(subquery_item.format(status=s, **params) for s in statuses) query = ''' project={project} and (assignee = "{user}" and status in {statuses}) or {subquery}'''.format(subquery=subquery, statuses=statuses, **params) issues = jira.search_issues(query, expand='changelog') # import pdb; pdb.set_trace() work_records = [ WorkRecord( date=issue.fields.updated, comment=issue.fields.summary, task=issue.key, type=issue.fields.status.name) for issue in issues] return work_records
class JiraHelper(object): def __init__(self, host, user="", password=""): self.host = host self.user = user self.password = password try: if user != "" and password != "": self.jira = JIRA(host, basic_auth=(user, password)) else: self.jira = JIRA(host) except JIRAError as e: printErrorMsg('Error connecting to %s. Check if username and password are correct.' % (self.host)) printJiraErrorAndExit(e) def getSummary(self, issue): """ Gets the summary for the given ticket. """ issueData = self.jira.issue(issue) return issueData.fields.summary def getIssues(self, issues): """ Gets the issues from Jira with the given issue numbers. """ result = [] for issue in issues: result.append(self.jira.issue(issue)) return result
def update_jira(username, password): """Update time logs in Jira Current implementation uses basic authentication, future version will have better auth. For simplicity the toggl log should have issue number as timelog description. *username* to use to connect to Jira *password* for Jira authentication """ url = CONFIG.get('jira')['url'] jira = JIRA( options={'server': url}, basic_auth=(username, password)) time_logs = toggl.Connect('jira') get_logs = time_logs.get_time_logs() for each_log in get_logs: issue_id = each_log.get('description') try: issue = jira.issue(issue_id) except JIRAError: logging.warning('Failed to find issue-id {0}'.format(issue_id)) continue # Compute time in hours and round to two decimal places time_in_hours = round(each_log['duration']/(60*60), 2) jira.add_worklog(issue, time_in_hours, comment='Updated using Jira API')
def main(): try: get_ipython except NameError: pass else: exit("Running ipython inside ipython isn't supported. :(") options, basic_auth, oauth = get_config() if basic_auth: basic_auth = (basic_auth['username'], basic_auth['password']) if oauth.get('oauth_dance') is True: oauth = oauth_dance( options['server'], oauth['consumer_key'], oauth['key_cert'], oauth['print_tokens'], options['verify']) elif not all((oauth.get('access_token'), oauth.get('access_token_secret'), oauth.get('consumer_key'), oauth.get('key_cert'))): oauth = None jira = JIRA(options=options, basic_auth=basic_auth, oauth=oauth) import IPython # The top-level `frontend` package has been deprecated since IPython 1.0. if IPython.version_info[0] >= 1: from IPython.terminal.embed import InteractiveShellEmbed else: from IPython.frontend.terminal.embed import InteractiveShellEmbed ip_shell = InteractiveShellEmbed( banner1='<JIRA Shell ' + __version__ + ' (' + jira.client_info() + ')>') ip_shell("*** JIRA shell active; client is in 'jira'." ' Press Ctrl-D to exit.')
def GET(self): gl.GL_WEBINPUT = web.input() projectname = gl.GL_WEBINPUT.product_name productline_list = gl.GL_DB.query("select distinct version from crashinfo where appName='" + projectname + "'") # select *, count(distinct name) from table group by name result = [] result_g_version = [] result_jira_version = [] #jira = JIRA(server='http://127.0.0.1:1194', basic_auth=('wangyang', 'qwerty123456')) jira = JIRA(server=jira_server, basic_auth=(user_accout, user_pass)) for name in project: if name in projectname: jira_name = project[name]["projectname"] versions = jira.project_versions(jira.project(jira_name)) for item in productline_list: item_dict = {"game_version": item.version} result_g_version.append(item_dict) [result_jira_version.append({"jira_version": v.name}) for v in reversed(versions)] result.append(result_g_version) result.append(result_jira_version) encodedjson = json.dumps(result) return encodedjson
def main(repo, project): jira = JIRA(JIRA_URL, basic_auth=[JIRA_USERNAME, JIRA_PASSWORD]) print("Connection to JIRA successfully established.") print("Fetching list of matching issues...") # Get issue list for all the issues that match given project issue_list = [] for year in range(JIRA_YEAR_START, JIRA_YEAR_END + 1): jira_filter = JIRA_FILTER_TEMP.format(project=project, start=year, end=year+1) issue_list += jira.search_issues(jira_filter, maxResults=5000) # Sort issue list sorted_issue_list = list(sorted( issue_list, key=lambda i: int(i.key.split('-')[1]) )) print(f"Fetching milestones...") milestone_map = generate_milestone_map(repo, sorted_issue_list) print(f"The script will process {len(sorted_issue_list)} matching issues now.") issue = jira.issue(sorted_issue_list[0].key) for issue_key in [i.key for i in sorted_issue_list]: issue = jira.issue(issue_key) data, comments = generate_issue_data(issue, milestone_map) comments.insert(0, generate_meta_comment(issue)) download_attachments(issue) create_issue(repo, data, comments) time.sleep(REQUEST_SLEEP)
class Jira(object): def __init__(self, url, user, password): self.jira = JIRA(url, auth=(user, password)) def book_jira(self, bookings): for entry in bookings: if not ticket_pattern_jira.match(entry['issue_id']): continue rm_entry = entry.copy() rm_entry['hours'] = rm_entry['time'] / 60. del rm_entry['time'] if 'description' in rm_entry: del rm_entry['description'] if 'activity' in rm_entry: del rm_entry['activity'] try: self.jira.add_worklog( issue=entry['issue_id'], timeSpent=entry['time'], started=datetime.strptime(entry['spent_on'], '%Y-%m-%d'), comment=entry['comments'], ) except JIRAError as je: print(u'{0}: {1} ({2})'.format( je.status_code, je.text, rm_entry['comments']))
def create_jira(self, username): options = { 'server': '%s' % settings.JIRA_OPTS['URL'], 'verify': settings.JIRA_OPTS.get('VERIFY_SSL', False) } project = self.cleaned_data.get('project') summary = self.cleaned_data.get('summary') issue_type = self.cleaned_data.get('issue_type') component = self.cleaned_data.get('component') description = self.cleaned_data.get('description') description += '*JIRA Created by:* %s' % username try: jconn = JIRA(options, basic_auth=(settings.JIRA_OPTS['USER'], settings.JIRA_OPTS['PASSWORD'])) except Exception as e: logger.error('Error creating JIRA ticket :%s' % e) raise forms.ValidationError(u"Error connecting to JIRA ticket, please check the server logs") try: jira_ticket = jconn.create_issue(project=project, summary=summary, description=description, issuetype={'name': issue_type}, components=[{'name': component}]) except Exception as e: logger.error('Error creating JIRA ticket project=%s, summary=%s, issue_type=%s, description=%s,' % (project, summary, issue_type, description)) logger.error('Server message %s' % e) msg = u"Error creating JIRA ticket, please check the project name and issue type. If that doesn't work then check the server logs" raise forms.ValidationError(msg) if isinstance(jira_ticket, jira.resources.Issue): return jira_ticket.key else: raise forms.ValidationError(u"Error creating JIRA ticket, JIRA server did not return a ticket key.")
class JiraIntegration(object): def signIn(self, jiraurl, username, password): try: self.__authed_jira = JIRA(server=jiraurl, basic_auth=(username, password), logging=True, max_retries=3) return True except Exception: return False def signOut(self): try: self.__authed_jira.kill_session() return True except Exception: return False def getOpenIssues(self): issues = self.__authed_jira.search_issues("""assignee = currentUser() and sprint in openSprints () order by priority desc""", maxResults=5) return issues def getTitlesForMany(self, issue_id_list): issues = self.__authed_jira.search_issues(' key in (%s)' % issue_id_list.join(',')) return issues def getTitleFor(self, issue_id): issues = self.__authed_jira.search_issues(' key in (%s)' % issue_id) return issues
def show(self, message, bug): """show lp ____: Show details of bug ___ on Launchpad""" launchpad = Launchpad.login_anonymously('just testing', 'production') self.say( self.render_lp(launchpad.bugs[bug]), message=message, html=True ) jira = JIRA( basic_auth=(settings.JIRA_USER, settings.JIRA_PASS), server=settings.JIRA_HOST, validate=False, options={'verify': False} ) issues = jira.search_issues(self.SEARCH_PATTERN % ( settings.JIRA_PROJ, bug, bug)) if len(issues) > 0: self.say("I also found a jira ticket for that", message=message) for issue in issues: self.say( self.render_jira(issue), message=message, html=True )
def main(): try: get_ipython except NameError: pass else: exit("Running ipython inside ipython isn't supported. :(") options, basic_auth, oauth = get_config() if basic_auth: basic_auth = (basic_auth['username'], basic_auth['password']) if oauth['oauth_dance']: oauth = oauth_dance( options['server'], oauth['consumer_key'], oauth['key_cert'], oauth['print_tokens'], options['verify']) else: oauth = None jira = JIRA(options=options, basic_auth=basic_auth, oauth=oauth) from IPython.frontend.terminal.embed import InteractiveShellEmbed ipshell = InteractiveShellEmbed( banner1='<JIRA Shell ' + __version__ + ' (' + jira.client_info() + ')>') ipshell("*** JIRA shell active; client is in 'jira'." ' Press Ctrl-D to exit.')
def delete_issue(request, find): j_issue = JIRA_Issue.objects.get(finding=find) jira_conf = find.jira_conf() jira = JIRA(server=jira_conf.url, basic_auth=(jira_conf.username, jira_conf.password)) issue = jira.issue(j_issue.jira_id) issue.delete()
def comments(task): repo = Repo(os.getcwd()) jr = JIRA({'server': JIRA_URL}, basic_auth=(JIRA_USER, JIRA_PASS)) issue = jr.issue(task or repo.head.ref.name) for comment in issue.fields.comment.comments: click.echo('-----------------------------------------------------------') click.echo(click.style(comment.author.displayName + ': \n', fg='green')) click.echo('\r' + comment.body)
def add_comment(find, note, force_push=False): prod = Product.objects.get(engagement=Engagement.objects.get(test=find.test)) jpkey = JIRA_PKey.objects.get(product=prod) jira_conf = jpkey.conf if jpkey.push_notes or force_push == True: jira = JIRA(server=jira_conf.url, basic_auth=(jira_conf.username, jira_conf.password)) j_issue = JIRA_Issue.objects.get(finding=find) jira.add_comment(j_issue.jira_id, '(%s): %s' % (note.author.get_full_name(), note.entry))
def index(request): if request.method == "POST": application_url = request.POST.get('application_url') username = request.POST.get('username') password = request.POST.get('password') if not username or not password: try: dirty_data = request.POST.keys()[0] data = json.loads(dirty_data) username = data['username'] password = data['password'] application_url = data.get('application_url') except: raise Http404 else: raise Http404 is_setting_up = False if all([application_url, username, password]): is_setting_up = True elif all([username, password]): try: application_url = ApplicationURL.get_url(username) except ApplicationURL.DoesNotExist: raise Http404 jira = JIRA(server=application_url, basic_auth=(username, password), max_retries=1) cache_time_to_live = 1000 # Seconds cache.set(username, jira, cache_time_to_live) available_projects = jira.projects() if is_setting_up: application_url_obj, created = ApplicationURL.objects.get_or_create(username=username) # if created: application_url_obj.url = application_url application_url_obj.save() data = [] for project in available_projects: project_data = { 'id': project.id, 'name': project.name, } data.append(project_data) data = { 'projects': data, 'token': username } data = json.dumps([data]) # import ipdb # ipdb.set_trace() response = HttpResponse(data) response["Access-Control-Allow-Origin"] = "*" response["Access-Control-Allow-Methods"] = "POST, GET, OPTIONS" response["Access-Control-Max-Age"] = "1000" response["Access-Control-Allow-Headers"] = "*" return response
def get_jira_summary(server, username, password, ticketId): try: jira = JIRA(server=server, basic_auth=(username, password), options={'verify':False}) issue = jira.issue(ticketId, fields='summary') return issue.fields.summary except JIRAError, e: return "JIRA error: " + e.text
def get_jira_details(repo_history_list): output_file = open(repo_info['filename'] + '_' + since + '_' + until + '.csv', 'w') headings = ['Issue', 'Project', 'Summary', 'Status', 'Type', 'Components', 'Reporter', 'Created', 'Updated', 'Resolved', 'Epic', 'Fix Versions', 'PM Notes Internal', 'PM Notes External'] output_file.write(','.join(headings)) output_file.write('\n') print('Getting JIRA details for issues...') jira = JIRA(options, basic_auth=('noninteractive', 'etopup123')) for jira_from_repo in repo_history_list: if jira_from_repo == 'REVERT': continue try: issue = jira.issue(jira_from_repo, fields='summary,status,issuetype,components,created,updated,' 'resolutiondate,reporter,fixVersions,customfield_10008,' 'customfield_10600,customfield_11200,project') except Exception as e: print('Problem obtaining info about issue=' + jira_from_repo, str(e)) output_file.write(jira_from_repo + ',Unknown,Unknown JIRA!,,,,,,,,,,,') output_file.write('\n') continue summary = issue.fields.summary.replace(',', ' ') status = issue.fields.status.name issuetype = issue.fields.issuetype.name components = [] for component in issue.fields.components: components.append(component.name) all_components = ';'.join(components) created = parse(issue.fields.created).date().strftime("%Y-%m-%d") updated = parse(issue.fields.updated).date().strftime("%Y-%m-%d") resolved = '' if issue.fields.resolutiondate: resolved = parse(issue.fields.resolutiondate).date().strftime("%Y-%m-%d") reporter = issue.fields.reporter.displayName versions = [] for version in issue.fields.fixVersions: versions.append(version.name) all_versions = ';'.join(versions) epic = '' if issue.fields.customfield_10008: epic = issue.fields.customfield_10008 pm_internal = '' if issue.fields.customfield_10600: pm_internal = issue.fields.customfield_10600.replace(',', ' ') pm_internal = pm_internal.replace('\r\n', '|') pm_external = '' if issue.fields.customfield_11200: pm_external = issue.fields.customfield_11200.replace(',', ' ') pm_external = pm_external.replace('\r\n', '|') project_name = issue.fields.project.name try: issue_items = [jira_from_repo, project_name, summary, status, issuetype, all_components, reporter, created, updated, resolved, epic, all_versions, pm_internal, pm_external] output_file.write(','.join(issue_items)) output_file.write('\n') except Exception as e: print('JIRA field problem for issue=' + jira_from_repo, str(e))
def update_epic(eng, push_to_jira): engagement = eng prod = Product.objects.get(engagement=engagement) jpkey = JIRA_PKey.objects.get(product=prod) jira_conf = jpkey.conf if jpkey.enable_engagement_epic_mapping and push_to_jira: jira = JIRA(server=jira_conf.url, basic_auth=(jira_conf.username, jira_conf.password)) j_issue = JIRA_Issue.objects.get(engagement=eng) issue = jira.issue(j_issue.jira_id) issue.update(summary=eng.name, description=eng.name)
def get_project(params): api_server = params['api_url'] api_username = params['api_username'] api_password = params['api_password'] auth = (api_username, api_password) jira = JIRA( {'server': api_server}, basic_auth=auth) key = params['project_key'] try: return jira.project(key) except: return None
def create_user(user_config, service_config): user_config = \ utils.convert_config_file(user_config)['jira'] service_config = \ utils.convert_config_file(service_config)['jira'] jira = JIRA(options=service_config['jira_options'], basic_auth=( service_config['username'], service_config['password'] )) return jira.add_user(**user_config)
def test_connection(self): from jira import JIRA from burlap.common import print_success, print_fail try: print('Connecting to %s with user %s...' % (self.env.server, self.env.basic_auth_username)) jira = JIRA({ 'server': self.env.server }, basic_auth=(self.env.basic_auth_username, self.env.basic_auth_password)) result = jira.search_issues('status=resolved') #print('result:', result) print_success('OK') except Exception as exc: print_fail('ERROR: %s' % exc)
def POST(self): issue_list = self.init_bugs() # print issue_list #jira = JIRA(server='http://127.0.0.1:1194', basic_auth=('wangyang', 'qwerty123456')) jira = JIRA(server=jira_server, basic_auth=(user_accout, user_pass)) issues = jira.create_issues(field_list=issue_list) # issue = jira.issue(issues[0]['issue']) # issue.update(versions=[{"Affects Version/s": 'V18'}]) print issues if(issues[0]['error']): return issues[0]['error'] else: return 0
def __init__(self, host, user="", password=""): self.host = host self.user = user self.password = password try: if user != "" and password != "": self.jira = JIRA(host, basic_auth=(user, password)) else: self.jira = JIRA(host) except JIRAError as e: printErrorMsg('Error connecting to %s. Check if username and password are correct.' % (self.host)) printJiraErrorAndExit(e)
def retrieve_counts(): jira = JIRA({"server": "https://issues.citrite.net"}) counts = {} try: for (name, jira_filter) in queries.iteritems(): jql = "filter='%s'" % jira_filter response = jira.search_issues(jql, maxResults=1, fields='key', json_result=True) counts[name] = response['total'] except JIRAError as e: sys.stderr.write("error: Could not retrieve_counts from JIRA: %s" % e) exit(3) return counts
class TestUsers(unittest.TestCase): def setUp(self): self.jira = JIRA(options=dict(server=TEST_URL, verify=False), basic_auth=(TEST_USERNAME, TEST_PASSWORD)) self.purge_test_users() def tearDown(self): self.purge_test_users() def get_user(self, username): users = [_ for _ in self.jira.search_users(user=username) if _.name == username] return users[0] if len(users) == 1 else None def purge_test_users(self): users = [_ for _ in self.jira.search_users(user='******') if _.name.startswith('test-')] for _ in users: _.delete() def test_create_user(self): self.assertIsNone(self.get_user('test-1')) result = CliRunner().invoke(topcli, ['user', 'create', 'test-1', 'test-1' + '@gmail.com']) self.assertEqual(result.exit_code, 0) self.assertIsNotNone(self.get_user('test-1')) def test_delete_user(self): result = CliRunner().invoke(topcli, ['user', 'create', 'test-1', 'test-1' + '@gmail.com']) self.assertEqual(result.exit_code, 0) self.assertIsNotNone(self.get_user('test-1')) result = CliRunner().invoke(topcli, ['user', 'delete', 'test-1']) self.assertEqual(result.exit_code, 0) self.assertIsNone(self.get_user('test-1')) def test_update_user(self): result = CliRunner().invoke(topcli, ['user', 'create', 'test-1', '*****@*****.**']) before = self.get_user('test-1') self.assertEqual(before.emailAddress, '*****@*****.**') result = CliRunner().invoke(topcli, ['user', 'update', 'test-1', '-e', '*****@*****.**']) self.assertEqual(result.exit_code, 0) after = self.get_user('test-1') self.assertEqual(after.emailAddress, '*****@*****.**') def test_search_user(self): result = CliRunner().invoke(topcli, ['user', 'create', 'test-1', 'test-1' + '@gmail.com']) result = CliRunner().invoke(topcli, ['user', 'search']) self.assertEqual(result.exit_code, 0) before = len(result.output.strip().split('\n')) self.assertGreater(before, 1) result = CliRunner().invoke(topcli, ['user', 'search', '-f', 'test-1']) self.assertEqual(result.exit_code, 0) after = len(result.output.strip().split('\n')) self.assertEqual(after, 1)
def add_jira_comment(jira_id, comment): if not settings.CASELINK_JIRA['ENABLE']: return False user = settings.CASELINK_JIRA['USER'] password = settings.CASELINK_JIRA['PASSWORD'] server = settings.CASELINK_JIRA['SERVER'] basic_auth = (user, password) options = { 'server': server, 'verify': False, } jira = JIRA(options, basic_auth=basic_auth) jira.add_comment(jira.issue(id=jira_id), comment) return True
def build_message(self, link): msg = self.quip(link) try: jira = JIRA(self._conf['JIRA_HOST'], basic_auth=(self._conf['JIRA_LOGIN'], self._conf['JIRA_PASSWORD'])) issue = jira.issue(ticket) msg += '>>> %s' % self._escape(issue.fields.summary) except Exception as ex: if self._log: self._log.error('JIRA: %s' % (ex)) pass return msg
def main(): options = { 'server': config['JIRA'] } jira = JIRA(options, basic_auth=(config['USERNAME'], config['PASSWORD'])) months = [ ('2015-03', '2015-04'), ('2015-04', '2015-05'), ('2015-05', '2015-06'), ('2015-06', '2015-07'), ('2015-07', '2015-08'), ('2015-08', '2015-09'), ('2015-09', '2015-10'), ('2015-10', '2015-11'), ('2015-11', '2015-12'), ('2015-12', '2016-01'), ('2016-01', '2016-02'), ('2016-02', '2016-03'), ('2016-03', '2016-04') ] total_issues = 0 bulk_add = [] for month in months: print("Downloading issues for interval %s/%s" % month) jql = "created >= '%s-01' AND created < '%s-01'" % month issues_in_month = jira.search_issues(jql, maxResults=1000, json_result=True) issues = issues_in_month['issues'] filtered_issues = filter_issues(issues) issues_count = len(issues) filtered_count = len(filtered_issues) assert filtered_count == issues_count total_issues = total_issues + issues_count bulk_add.extend(filtered_issues) print("Successfully downloaded %d issues" % total_issues) print("Loading %d issues into RethinkDB" % len(bulk_add)) r.connect(config['RETHINKDB'], 28015, db='jira').repl() r.table_drop('issues').run() r.table_create('issues').run() r.table('issues').insert(bulk_add).run() print("OK! Bye")
class JiraApi(): def __init__(self, instance=None): self.instance = instance @staticmethod def get_datetime_now(): return datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S.0+0000") def connect(self): options = {'server': app.config['JIRA_HOSTNAME'],'verify':False} self.instance = JIRA(options, basic_auth=(app.config['JIRA_USERNAME'], app.config['JIRA_PASSWORD'])) @staticmethod def ticket_link(issue): return '<a href="{}/browse/{}">{}</a>'.format(app.config['JIRA_HOSTNAME'], issue.key, issue.key) def resolve(self, issue): self.instance.transition_issue( issue, app.config['JIRA_RESOLVE_TRANSITION_ID'], assignee={'name': app.config['JIRA_USERNAME']}, resolution={'id': app.config['JIRA_RESOLVE_STATE_ID']}) def defect_for_exception(self, summary_title, e): return self.instance.create_issue( project='IPGBD', summary='[auto-{}] Problem: {}'.format(current_user.username, summary_title), description="Exception: {}".format(e), customfield_13842=JiraApi.get_datetime_now(), customfield_13838= { "self": "https://jira.rim.net/rest/api/2/customFieldOption/16680", "value": "No", "id": "16680" }, customfield_13831 = [ { "self": "https://jira.rim.net/rest/api/2/customFieldOption/16592", "value": "Quality", "id": "16592" }, { "self": "https://jira.rim.net/rest/api/2/customFieldOption/16594", "value": "Risk Avoidance", "id": "16594" }], issuetype={'name': 'Defect'})
def jira_command(args): channel = args['channel_name'] if channel == 'directmessage': # Channel name is "directmessage" for all direct messages, so we have # to use the channel ID to keep them separate. channel = 'dm:%s' % args['channel_id'] issue_keys = jira_key_re.findall(args['text']) if not issue_keys: return Response() log.info('Message from %s in #%s contained JIRA issue key(s): %s', args['user_name'], channel, ', '.join(issue_keys)) # Login to JIRA authinfo = ( current_app.config['JIRA_USERNAME'], current_app.config['JIRA_PASSWORD'], ) jira_url = current_app.config['JIRA_URL'] options = {'check_update': False} jira = JIRA(jira_url, basic_auth=authinfo, options=options) # Retrieve issue(s) attachments = [] for issue_key in issue_keys: try: last_mention = get_last_mention(channel, issue_key) if last_mention: log.debug('%s last mentioned in #%s at %s', issue_key, channel, last_mention) blackout = current_app.config['JIRA_ID_BLACKOUT_PERIOD'] if datetime.now() <= last_mention + blackout: continue issue = jira.issue(issue_key) attachments.append(format_attachment(issue)) except JIRAError as e: if e.status_code == 404: log.warning('%s does not exist', issue_key) else: log.error('Error looking up %s: %s', issue_key, e.text) if not attachments: return Response() return jsonify({ 'response_type': 'in_channel', 'attachments': attachments, })
from jira import JIRA import getpass pw = getpass.getpass() jira = JIRA(auth=('chakrk03', pw), options={'server': 'https://jira.kfplc.com'}) # Linking a remote jira issue (needs applinks to be configured to work) issue = jira.issue("DRRR-437") issue2 = jira.issue("DRRR-484") jira.add_remote_link(issue, issue2)
only_states = only_states or [] <<<<<<< HEAD if any(isinstance(new_state, ignored) for ignored in ignore_states): ======= if any([isinstance(new_state, ignored) for ignored in ignore_states]): >>>>>>> prefect clone return new_state if only_states and not any( [isinstance(new_state, included) for included in only_states] ): return new_state summary_text = str(jira_message_formatter(tracked_obj, new_state)) options["summary"] = summary_text jira = JIRA(basic_auth=(username, password), options={"server": server_URL}) created = jira.create_issue(options) if not created: raise ValueError("Creating Jira Issue for {} failed".format(tracked_obj)) if assignee: assigned = jira.assign_issue(created, assignee) if not assigned: raise ValueError("Assigning Jira issue for {} failed".format(tracked_obj)) return new_state
import os import configparser import lxml.html config = configparser.ConfigParser() config.read("happy.config") serverName = config.get('JIRA', 'serverName') password = config.get('JIRA', 'password') username = config.get('JIRA', 'username') projectName = config.get('JIRA', 'project') options = { 'server': serverName, 'verify': False, } jira = JIRA(options, basic_auth=(username, password)) files = [] for file in os.listdir(sys.argv[1]): if '.html' in file: files.append(sys.argv[1] + '\\' + file) for f in files: tree = lxml.html.parse(f) scanName = tree.xpath( '//td[contains(text(),"Task:")]/following-sibling::td/text()')[0] summaryValue = "Security Scan using OpenVAS for " + scanName startTime = tree.xpath( '//td[contains(text(),"Scan started:")]/following-sibling::td/b/text()' )[0] endTime = tree.xpath(
#!/bin/python3 from jira import JIRA import re import requests import datetime requests.packages.urllib3.disable_warnings( requests.packages.urllib3.exceptions.InsecureRequestWarning) jira = JIRA( server="https://jira.domain.local", basic_auth=('login', 'password'), validate=False, ) project_key = "ITOSA" today = datetime.datetime.now() - datetime.timedelta(days=3) jql = f"project = {project_key} AND worklogDate >= \"{today.year}/{today.month}/{today.day}\" AND status = \"Новый\"" issues_list = jira.search_issues(jql) for issue in issues_list: # print (issue.fields.project.key) # 'JRA' print(issue.fields.customfield_10006) # number of task print(issue.fields.issuetype.name) # type of task print(issue.fields.reporter.displayName) # author print(issue.fields.status) yy = int(issue.fields.customfield_10202[0:4] ) #my custom fields - see in Python IDE
def check_stale_branches(event: dict, context) -> dict: """ Create a report about stale branches for a list of repositories. """ ssm_parameters = load_params('dev_tools', 'dev') if 'jira_statuses_for_task_completion' in ssm_parameters and ssm_parameters['jira_statuses_for_task_completion']: jira_statuses_for_task_completion = ssm_parameters['jira_statuses_for_task_completion'] else: jira_statuses_for_task_completion = ('Resolved', 'Closed') repository_names = ssm_parameters['github_repository_names'] github_repository_names = repository_names.split(',') jira_oauth_dict = { 'access_token': ssm_parameters['jira_access_token'], 'access_token_secret': ssm_parameters['jira_access_token_secret'], 'consumer_key': ssm_parameters['jira_consumer_key'], 'key_cert': ssm_parameters['jira_private_key'] } auth_jira = JIRA(ssm_parameters['jira_url'], oauth=jira_oauth_dict) # Github authentication setup g = Github(ssm_parameters['github_access_token']) # Look for stale branches for all the specified repos total_stale_branches = 0 general_report = '' author_count = defaultdict(int) for repo_name in github_repository_names: logger.debug(f'\nChecking repo: {repo_name}') try: repo = g.get_repo(f"{ssm_parameters['github_account']}/{repo_name}") except GithubException: logger.error(f"Github repository '{ssm_parameters['github_account']}/{repo_name}' not found!") continue repo_report = '' # confirm the name for the main develop branch main_develop_branch = 'develop' try: _ = repo.get_branch('develop') except GithubException: main_develop_branch = 'master' logger.debug('Develop branch not found, using master as the main develop branch.') continue branches = repo.get_branches() for branch in branches: # only check feature and hotfix branches if not branch.name.startswith('feature/') and not branch.name.startswith('hotfix/'): continue # compare the branch against the main develop branch try: comparison = repo.compare(main_develop_branch, branch.name) except GithubException as error: logger.error(f'GithubException: Error while trying to compare {main_develop_branch} and {branch.name}.') logger.error(f'GithubException: {error}.') if comparison.behind_by == 0: # the branch is up to date, nothing to do continue # try to get the jira ticket number from the branch name ticket = None result = re.search(r'feature/(?P<ticket>[a-zA-Z]+-[0-9]+).*', branch.name) if result: ticket = result.groupdict()['ticket'].upper() try: issue = auth_jira.issue(ticket) except jira_exceptions.JIRAError: logger.debug(f"The ticket {ticket} specified in the branch name doesn't exist in Jira.") if issue and issue.fields.status.name not in jira_statuses_for_task_completion: # the issue hasn't been marked as resolved in jira, so the branch may still be needed continue author = branch.commit.author.login if branch.commit.author else 'unknown' author_count[author] += 1 repo_report += f'Branch: {branch.name}\nComparison status: {comparison.status}\nAuthor: {author}\n' if ticket: repo_report += f'Ticket status: "{issue.fields.status.name}\n' repo_report += '\n' total_stale_branches += 1 if repo_report: general_report += f'Repo: {repo_name}, develop branch name: {main_develop_branch}\n{repo_report}' if total_stale_branches: count_by_author = '' for author, count in sorted(author_count.items(), key=operator.itemgetter(1), reverse=True): count_by_author += f'{author}: {count}\n' report_overview = f'Current number of stale branches: {total_stale_branches}\n\n'\ f'Count by author:\n{count_by_author}\n' report_details = f'Details:\n\n{general_report}' _ = slack_request(url=ssm_parameters['slack_webhook_url'], headers={'Content-type': 'application/json', 'Authorization': f"Bearer {ssm_parameters['slack_access_token']}"}, data=json.dumps({'text': report_overview}) ) _ = slack_request(url='https://slack.com/api/files.upload', headers={'Content-type': 'application/x-www-form-urlencoded'}, data={'token': ssm_parameters['slack_access_token'], 'channels': 'GE8NS0FT5', 'content': report_details, 'title': 'Stale branches details'} )
def main(): global _logger config_file = "config.ini" try: opts, args = getopt.getopt(sys.argv, "c", ["configuration"]) except getopt.GetoptError: print("processTimeTrackingEntries.py -c <configurationfile>") sys.exit(2) for opt, arg in opts: if opt in ("-c", "--configuration"): config_file = arg configuration = read_configuration(config_file) logging.basicConfig(filename=configuration['logFile'], level=configuration['logLevel']) all_toggl_projects = {} toggl_end_time = datetime.datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S+00:00") toggl = Toggl(configuration['myTogglApiToken']) if toggl.Workspaces.get_projects(configuration['myWorkspace']) is not None: all_toggl_projects = extract_jira_issue_numbers(toggl.Workspaces.get_projects(configuration['myWorkspace']), configuration['issue_number_regex_expression']) new_time_tracking_entries = toggl.TimeEntries.get(start_date=configuration['togglStartTime'], end_date=toggl_end_time) jira = JIRA(configuration['jiraUrl'], basic_auth=(configuration['jiraUser'], configuration['jiraPassword'])) grouped_time_entries = {} for time_entry in new_time_tracking_entries: tags = time_entry.get('tags') if (tags is None) or ("jiraprocessed" not in tags): pid = time_entry.get('pid') description = time_entry['description'] if 'description' in time_entry else '' group_key = str(pid) + "_" + description start_time = dateutil.parser.parse(time_entry['start']) if configuration['groupTimeEntriesBy'] == 'day': group_key = group_key + '_' + str(start_time.timetuple().tm_yday) elif configuration['groupTimeEntriesBy'] == 'week': group_key = group_key + '_' + str(start_time.isocalendar()[1]) else: group_key = group_key + '_' + str(start_time.isocalendar()[1]) if group_key not in grouped_time_entries: grouped_time_entries[group_key] = { "pid": pid, "description": description, "time_entries": [] } grouped_time_entries[group_key]["time_entries"].append({ "start_time": start_time, "duration": time_entry['duration'], "id": time_entry['id'], "description": time_entry['description'] }) else: _logger.info( 'The time entry with the id "{0}" and the description "{1}" has already been ' 'created as worklog in JIRA and subsequently tagged in Toggl'.format( str(time_entry['id']), time_entry['description'])) for key, grouped_time_entry in grouped_time_entries.items(): start_time = min(time_entry["start_time"] for time_entry in grouped_time_entry["time_entries"]) # when Toggl is running (duration is negative), the entry should be skipped. if (time_entry["duration"] < 0): continue duration = sum(time_entry["duration"] for time_entry in grouped_time_entry["time_entries"]) duration = str(math.ceil(duration / (float(60) * 15)) * 15) + "m" if (grouped_time_entry["pid"] is not None) and (all_toggl_projects.get(grouped_time_entry["pid"]) is not None): issue = jira.issue(all_toggl_projects[grouped_time_entry['pid']]) elif extract_jira_issue_number(grouped_time_entry['description'], configuration['issue_number_regex_expression']) is not None: issue_number = extract_jira_issue_number(grouped_time_entry['description'], configuration['issue_number_regex_expression']) try: issue = jira.issue(issue_number) except JIRAError: _logger.error("The issue {0} could not be found in JIRA.".format(str(issue_number))) tag_grouped_timeentry_as_error(grouped_time_entry["time_entries"], toggl) continue elif (grouped_time_entry["pid"] is not None) and (all_toggl_projects.get(grouped_time_entry["pid"]) is None): _logger.error( "The project with the id {0} is not in the list of active projects.".format( str(grouped_time_entry["pid"]))) tag_grouped_timeentry_as_error(grouped_time_entry["time_entries"], toggl) continue else: _logger.error("No JIRA issue number could be extracted from time entry project or work description. " "Therefore no worklog will be inserted in JIRA.") # taggingResponse = _toggl.put( # uri="https://www.toggl.com/api/v8/time_entries/{0}".format(str(timeEntry['id'])), # data=_payloadForTogglErrorTag) # if taggingResponse.status_code == 200: # _logger.info( # "The time entry with the id \"{0}\" has been tagged as error in Toggl".format(str(timeEntry['id']))) continue if issue is not None: jira_response = insert_jira_worklog(issue, start_time, duration, grouped_time_entry['description'], configuration['jiraRePolicy'], jira) if isinstance(jira_response, Worklog): for timeEntry in grouped_time_entry["time_entries"]: _logger.info( "A worklog for the time entry with the id \"{0}\" and the description \"{1}\" has been " "created successfully".format( str(timeEntry['id']), timeEntry['description'])) tag_timeentry_as_processed(timeEntry['id'], timeEntry['description'], toggl) else: _logger.error('No JIRA worklog could be created.') tag_grouped_timeentry_as_error(grouped_time_entry["time_entries"], toggl) continue else: _logger.error('No JIRA issue could be created with the given information.') tag_grouped_timeentry_as_error(grouped_time_entry["time_entries"], toggl) continue
from jira import JIRA import clases as c import plotly.express as px #from plotly.subplots import make_subplots #import plotly.graph_objects as go import pandas as pd jira = JIRA(basic_auth=("u623442", "!!Fluxit2021"), options={'server': "https://gestioncio.telecom.com.ar/"}) issues = jira.search_issues( 'Sprint = 2810 AND component = Celula1 AND type = Story') list = [] for issue in issues: h = c.history( issue.fields.summary, issue.fields.assignee.displayName, issue.fields.customfield_10106, #StoryPoints issue.fields.customfield_10377, #Epica issue.fields.status) list.append(h) #df = pd.DataFrame(list) df = pd.DataFrame([x.as_dict() for x in list]) fig = px.pie(df, values='storypoints', names='epiclink', title='Puntos por epica')
def get_issue(pull): # title to jira jira_id = re.search('[0-9A-Z]+-[0-9]+', pull.title).group(0) jira = JIRA('http://issues.apache.org/jira') return jira.issue(jira_id)
def client(self): if self._client is None: self._client = JIRA(**self.credentials) return self._client
def __init__(self, server): self.jira = JIRA(server=server) self._users = set()
def load_issue_via_api(issues, persons, url): """For each issue in the list the history is added via the api :param issues: list of issues :param persons: list of persons from JIRA (incl. e-mail addresses) :param url: the project url """ log.info("Load issue information via api...") jira_project = JIRA(url) for issue in issues: last_checked = issue[ 'creationDate'] # needed to update state and resolution on creation for comments api_issue = jira_project.issue(issue['externalId'], expand='changelog') changelog = api_issue.changelog histories = list() # history changes get visited in time order from oldest to newest for change in changelog.histories: old_state, new_state, old_resolution, new_resolution = None, None, None, None for item in change.items: if item.field == 'status': old_state = item.fromString new_state = item.toString elif item.field == 'resolution': old_resolution = item.fromString new_resolution = item.toString # only history entries that change the state or the resolution are interesting if (old_state != new_state) | (old_resolution != new_resolution): if (old_resolution is None) & (new_resolution is not None ): # adjust to xml information old_resolution = "Unresolved" history = dict() history['new_state'] = new_state history['new_resolution'] = new_resolution user = dict() user["username"] = change.author.name user["name"] = change.author.name user["email"] = "" history["author"] = merge_user_with_user_from_csv( user, persons) date = change.created d = datetime.strptime(date, "%Y-%m-%dT%H:%M:%S.%f+0000") history['date'] = d.strftime('%Y-%m-%d %H:%M:%S') # updates state and resolution on creation for comments for comment in issue['comments']: # if-block checks between which history entries the comment was created to update the state and # the resolution on creation if (last_checked <= comment['changeDate']) & ( comment['changeDate'] < history['date']): comment['state_on_creation'] = old_state comment['resolution_on_creation'] = old_resolution last_checked = history['date'] histories.append(history) issue['history'] = histories
$0 [-d] -u <user> Options: -u --user JIRA username -d Dry run, do not change anything """ from docopt import docopt import getpass from jira import JIRA import requests if __name__ == "__main__": args = docopt(__doc__) print(args) passwd = getpass.getpass("Password for {}: ".format(args["--user"])) jira = JIRA('https://issues.redhat.com', basic_auth=(args["--user"], passwd)) no_qe_owner = jira.search_issues( """project=cnf and "QA Contact" is not empty and "QE Assignee" is empty""" ) for issue in no_qe_owner: print(issue, issue.fields.customfield_12315948.name) if not args.get("-d", False): issue.update( fields={ "customfield_12316243": { "name": issue.fields.customfield_12315948.name } })
def load_issue_via_api(issues, persons, url): """ For each issue in the list the history is added via the api. :param issues: list of issues :param persons: list of persons from JIRA (incl. e-mail addresses), see function "load_csv" :param url: the project url """ log.info("Load issue information via api...") jira_project = JIRA(url) global jira_request_counter for issue in issues: # if the number of JIRA requests has reached the request limit, wait 24 hours if jira_request_counter > max_requests: log.info( "More than " + str(max_requests) + " JIRA requests have already been sent. Wait for 24 hours...") sleep(86500) # 60 * 60 * 24 = 86400 log.info("Reset JIRA request counter and proceed...") jira_request_counter = 0 try: # send JIRA request for current issues and increase request counter jira_request_counter += 1 log.info("JIRA request counter: " + str(jira_request_counter)) api_issue = jira_project.issue(issue["externalId"], expand="changelog") changelog = api_issue.changelog except JIRAError: log.warn("JIRA Error: Changelog cannot be extracted for issue " + issue["externalId"] + ". History omitted!") changelog = None histories = list() # adds the issue creation time with the default state to a list # list is needed to find out the state the issue had when a comment was written state_changes = [[issue["creationDate"], "open"]] # adds the issue creation time with the default resolution to a list # list is needed to find out the resolution the issue had when a comment was written resolution_changes = [[issue["creationDate"], "unresolved"]] # only consider history changes if we were able to extract the changelog for the current issue if changelog is not None: # history changes get visited in time order from oldest to newest for change in changelog.histories: # default values for state and resolution old_state, new_state, old_resolution, new_resolution = "open", "open", "unresolved", "unresolved" # all changes in the issue changelog are checked if they contain a useful information for item in change.items: # state_updated event gets created and added to the issue history if item.field == "status": if item.fromString is not None: old_state = item.fromString.lower() if item.toString is not None: new_state = item.toString.lower() history = dict() history["event"] = "state_updated" history["event_info_1"] = new_state history["event_info_2"] = old_state if hasattr(change, "author"): user = create_user(change.author.displayName, change.author.name, "") else: log.warn("No author for history: " + str(change.id) + " created at " + str(change.created)) user = create_user("", "", "") history["author"] = merge_user_with_user_from_csv( user, persons) history["date"] = format_time(change.created) histories.append(history) state_changes.append([history["date"], new_state]) # resolution_updated event gets created and added to the issue history elif item.field == "resolution": if item.fromString is not None: old_resolution = item.fromString.lower() if item.toString is not None: new_resolution = item.toString.lower() history = dict() history["event"] = "resolution_updated" history["event_info_1"] = new_resolution history["event_info_2"] = old_resolution if hasattr(change, "author"): user = create_user(change.author.displayName, change.author.name, "") else: log.warn("No author for history: " + str(change.id) + " created at " + str(change.created)) user = create_user("", "", "") history["author"] = merge_user_with_user_from_csv( user, persons) history["date"] = format_time(change.created) histories.append(history) resolution_changes.append( [history["date"], new_resolution]) # assigned event gets created and added to the issue history elif item.field == "assignee": history = dict() history["event"] = "assigned" user = create_user(change.author.displayName, change.author.name, "") history["author"] = merge_user_with_user_from_csv( user, persons) assignee = create_user(item.toString, item.to, "") assigned_user = merge_user_with_user_from_csv( assignee, persons) history["event_info_1"] = assigned_user["name"] history["event_info_2"] = assigned_user["email"] history["date"] = format_time(change.created) histories.append(history) elif item.field == "Link": # add_link event gets created and added to the issue history if item.toString is not None: history = dict() history["event"] = "add_link" user = create_user(change.author.displayName, change.author.name, "") history["author"] = merge_user_with_user_from_csv( user, persons) # api returns a text. The issueId is at the end of the text and gets extracted history["event_info_1"] = item.toString.split()[-1] history["event_info_2"] = "issue" history["date"] = format_time(change.created) histories.append(history) # remove_link event gets created and added to the issue history if item.fromString is not None: history = dict() history["event"] = "remove_link" user = create_user(change.author.displayName, change.author.name, "") history["author"] = merge_user_with_user_from_csv( user, persons) # api returns a text. Th issue id is at the end of the text and gets extracted history["event_info_1"] = item.fromString.split( )[-1] history["event_info_2"] = "issue" history["date"] = format_time(change.created) histories.append(history) # state and resolution change lists get sorted by time state_changes.sort(key=lambda x: x[0]) resolution_changes.sort(key=lambda x: x[0]) for comment in issue["comments"]: # the state the issue had when the comment was written is searched out for state in state_changes: if comment["changeDate"] > state[0]: comment["state_on_creation"] = state[1] # the resolution the issue had when the comment was written is searched out for resolution in resolution_changes: if comment["changeDate"] > resolution[0]: comment["resolution_on_creation"] = [str(resolution[1])] issue["history"] = histories
from jira import JIRA from config import _ jira = JIRA({"server": _["server"]}, basic_auth=(_["email"], _["apiKey"])) issue_keys = ["XYZ-123", "XYZ-127"] for issue_key in issue_keys: jira.add_comment(issue_key, "new comment")
def run( self, username: str = None, access_token: str = None, server_url: str = None, service_desk_id: str = None, issue_type: int = None, summary: str = None, description: str = None, ) -> None: """ Run method for this Task. Invoked by calling this Task after initialization within a Flow context, or by using `Task.bind`. Args: - username(str): the jira username, provided with a Prefect secret (defaults to JIRAUSER in JIRASECRETS) - access_token (str): a Jira access token, provided with a Prefect secret (defaults to JIRATOKEN in JIRASECRETS) - server_url (str): the URL of your atlassian account e.g. "https://test.atlassian.net". Can also be set as a Prefect Secret. Defaults to the one provided at initialization - service_desk_id(str): the key for your jira project; defaults to the one provided at initialization - issue_type (str, optional): the type of issue you want to create; - summary (str, optional): summary or title for your issue; defaults to the one provided at initialization - description (str, optional): description or additional information for the issue; defaults to the one provided at initialization Raises: - ValueError: if a `service_desk_id`, `request_type`, or `summary` are not provided Returns: - None """ jira_credentials = cast(dict, Secret("JIRASECRETS").get()) if username is None: username = jira_credentials["JIRAUSER"] if access_token is None: access_token = jira_credentials["JIRATOKEN"] if server_url is None: server_url = jira_credentials["JIRASERVER"] if issue_type is None: raise ValueError("An issue_type must be provided") if service_desk_id is None: raise ValueError("A service desk id must be provided") if summary is None: raise ValueError("A summary must be provided") jira = JIRA(basic_auth=(username, access_token), options={"server": server_url}) options = { "serviceDeskId": service_desk_id, "requestTypeId": issue_type, "requestFieldValues": { "summary": summary, "description": description }, } created = jira.create_customer_request(options) if not created: raise ValueError("Creating Jira Issue failed")
jira.transition_issue(issue, BAD_AUTO_CREATE_TRANSITION_ID) # Auto-withdraw issue # if crashdumpinfo.autowithdraw: # jira.transition_issue(issue, WITHDRAW_TRANSITION_ID) if __name__ == '__main__': try: logfile = open(LOG_FILE, "a") logfile.write("=========== START: {} ==========\n".format( datetime.now())) jira = JIRA('https://2gig-technologies.atlassian.net', basic_auth=('jirabot', 'n0rt3ksc')) logfile.write("=========== END : {} ==========\n".format( datetime.now())) except JIRAError as e: logfile.write("Error connecting to JIRA: {}\n".format(e)) except IOError as e: syslog.syslog( "jirabot: I/O error trying to open logfile ({0}): {1}".format( e.errno, e.strerror)) sys.exit(1) except: logfile.write("Error:\n{}".format(traceback.format_exc()))
def __init__(self, server, account, password): self.server = server self.account = account self.password = password self.jira_session = JIRA(server=self.server, basic_auth=(self.account, self.password))
def handleQuery(query): results = [] if query.isTriggered: try: query.disableSort() results_setup = setup(query) if results_setup: return results_setup user = load_data("user") server = load_data("server") api_key = load_api_key() # connect to JIRA jira = JIRA(server=server, basic_auth=(user, api_key)) issues = jira.search_issues( "assignee = currentUser() AND status != 'Done'", maxResults=max_results_to_request, fields=",".join(fields_to_include), ) issues.sort(key=lambda issue: issue.fields.priority.id, reverse=False) results.append( v0.Item( id=__title__, icon=icon_path, text="Create new issue", actions=[ v0.UrlAction(f"Create new issue", get_create_issue_page(server)) ], )) if len(query.string.strip()) <= 2: for issue in issues[:max_results_to_show]: results.append(get_as_item(issue, jira)) else: desc_to_issue = { issue.fields.summary: issue for issue in issues } # do fuzzy search - show relevant issues matched = process.extract(query.string.strip(), list(desc_to_issue.keys()), limit=5) for m in [elem[0] for elem in matched]: results.append(get_as_item(desc_to_issue[m], jira)) except Exception: # user to report error results.insert( 0, v0.Item( id=__title__, icon=icon_path, text= "Something went wrong! Press [ENTER] to copy error and report it", actions=[ v0.ClipAction( f"Copy error - report it to {__homepage__[8:]}", f"{traceback.format_exc()}", ) ], ), ) return results
def cli(user, password, jira_instance, debug): click.get_current_context().obj = \ JIRA(jira_instance, basic_auth=(user, password)) if debug: LOGGER.setLevel(logging.DEBUG)
def main(): global conf conf = read_config() token = conf.token if conf.token is not None else None if token: gh = Github(token) else: gh = Github() jira = JIRA('https://issues.apache.org/jira') result = {} repo = gh.get_repo('apache/lucene-solr') open_prs = repo.get_pulls(state='open') out("Lucene/Solr Github PR report") out("============================") out("Number of open Pull Requests: %s" % open_prs.totalCount) result['open_count'] = open_prs.totalCount lack_jira = list( filter(lambda x: not re.match(r'.*\b(LUCENE|SOLR)-\d{3,6}\b', x.title), open_prs)) result['no_jira_count'] = len(lack_jira) lack_jira_list = [] for pr in lack_jira: lack_jira_list.append({ 'title': pr.title, 'number': pr.number, 'user': pr.user.login, 'created': pr.created_at.strftime("%Y-%m-%d") }) result['no_jira'] = lack_jira_list out("\nPRs lacking JIRA reference in title") for pr in lack_jira_list: out(" #%s: %s %s (%s)" % (pr['number'], pr['created'], pr['title'], pr['user'])) out("\nOpen PRs with a resolved JIRA") has_jira = list( filter(lambda x: re.match(r'.*\b(LUCENE|SOLR)-\d{3,6}\b', x.title), open_prs)) issue_ids = [] issue_to_pr = {} for pr in has_jira: jira_issue_str = re.match(r'.*\b((LUCENE|SOLR)-\d{3,6})\b', pr.title).group(1) issue_ids.append(jira_issue_str) issue_to_pr[jira_issue_str] = pr resolved_jiras = jira.search_issues( jql_str="key in (%s) AND status in ('Closed', 'Resolved')" % ", ".join(issue_ids)) closed_jiras = [] for issue in resolved_jiras: pr_title = issue_to_pr[issue.key].title pr_number = issue_to_pr[issue.key].number assignee = issue.fields.assignee.name if issue.fields.assignee else None closed_jiras.append({ 'issue_key': issue.key, 'status': issue.fields.status.name, 'resolution': issue.fields.resolution.name, 'resolution_date': issue.fields.resolutiondate[:10], 'pr_number': pr_number, 'pr_title': pr_title, 'issue_summary': issue.fields.summary, 'assignee': assignee }) closed_jiras.sort(key=lambda r: r['pr_number'], reverse=True) for issue in closed_jiras: out(" #%s: %s %s %s: %s (%s)" % (issue['pr_number'], issue['status'], issue['resolution_date'], issue['issue_key'], issue['issue_summary'], issue['assignee'])) result['closed_jira_count'] = len(resolved_jiras) result['closed_jira'] = closed_jiras if conf.json: print(json.dumps(result, indent=4)) if conf.html: print(make_html(result))
from jira import JIRA from jira.client import JIRA from email.mime.multipart import MIMEMultipart from email.mime.base import MIMEBase from email.mime.text import MIMEText from email.utils import formatdate from email import encoders from config import config import pandas as pd from datetime import date print("This script queries for the issues which are in PENDING STATE!") try: print("Trying to Login into JIRA") jira = JIRA(basic_auth=(config['jira_username'], config['jira_password']), options={'server': 'https://jira.move.com'}) print("Logged into JIRA succesfully") except Exception as e: print( "Not able to login into JIRA. Please check the connection and try again!" ) print(e) if config['start_date'] != '' and config['end_date'] != '': print( "Taking the Specified Date Range from config File and forming the query" ) query = 'project = DE AND issuetype = "Data Quality" AND status in (Blocked, "To Do", Deferred, "Waiting on Others", "In Progress", Open, "In Review", Reopened, "In Review / Validation", "Waiting for Others", "User Misunderstanding") AND created >= {0} AND updated <= {1} ORDER BY key ASC, status ASC, cf[10500] ASC, created DESC, due DESC'.format( config['start_date'], config['end_date']) print('Query Date Period - from {0} to {1}'.format(config['start_date'], config['end_date']))
from __future__ import division import json import sys import ConfigParser import os from jira import JIRA import datetime config = ConfigParser.ConfigParser() config.read("jira-metrics.ini") jira = JIRA(server='https://jira.tools.tax.service.gov.uk/', basic_auth=(config.get("credentials", "username"), config.get("credentials", "password"))) statuses = { 'Queue': 1, 'Waiting to be Triaged': 1, 'Open': 1, 'To Do': 1, 'Reopened': 1, 'Dev Ready': 2, 'Ready for Dev': 2, 'Ready to Review TxM Assessment': 2, 'In Dev': 3, 'Fix in Progress': 3, 'TxM Assessment In Progress': 3, 'In Progress': 3,
class JIRAPI(): gitlab_url = 'https://git.server.url' srv = '' regexRelId = re.compile(r"\d+", re.DOTALL) regexPlatform = re.compile(r"u'(\w*)'", re.DOTALL) # # # def __init__(self, project_name="DEFECT", credentials=None): self.__project_name = project_name if (credentials is None): self.credentials = myCredentials() else: self.credentials = credentials self.cred = self.credentials.getCredentials('dre') self.connect() self.mappingRelease = self.readReleaseMapping() def connection_info(self): if self.srv: return self.srv.client_info() def handleAuthError(self): print("Invalid Password") self.cred = self.credentials.getCredentials('dre', newPass=True) # # until now no crt is supported only HTTP possible, insecure ... do not use with internet, secure solution possible see: JIRA-get-Tickets.py # #@classmethod def connect(self, jira_server_url='https://jira.server.url'): self.__jira_options = {'server': jira_server_url, 'verify': False} urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) passCount = 0 while (True): try: self.srv = JIRA(self.__jira_options, basic_auth=(self.cred['user'], self.cred['pass'])) break except Exception as e: if (e.status_code == 401) or (e.status_code == 403): if (passCount >= 1): print "ERROR Invalid Password\n%s" % (e.message) break self.handleAuthError() else: print(e) break return self.srv # # get information from Relevant to Platform alias customfield_15300 # def getRelevantToPlatform(self, issue_object): platform = [] if self.srv: if issue_object: defect = issue_object.key if ('DEFECT' in defect) or ('BUG' in defect) or ('FEATURE' in defect): tmp = "{}".format(issue_object.fields.customfield_15300) for line in re.findall(self.regexPlatform, tmp): platform.append(line) return platform # # get SOP Date customfield # def getSOPDate(self, issue_object): sopdate = "" if issue_object: if ('FEATURE' not in issue_object.key) and ('REQ' not in issue_object.key): if ('DEFECT' in issue_object.key): sopdate = issue_object.fields.customfield_10316 # get the ID of Value behind URL = "https://jira.server.url" + issue_object.key + "/customfield_10316" data = self.manualcall(URL) data = data.decode() sopdate = json.loads(data) sopdate = sopdate['displays'][0] elif ('FEATURE' in issue_object.key): sopdate = issue_object.fields.customfield_13701 else: print("Ticket Type not supported. Only FEATURE or DEFECT") return sopdate # def readReleaseMapping(self): mapping = {} regexMap = re.compile(r"'|\s+") with open('SW-Versionen+IDs.txt', 'r') as infile: for line in infile: line = re.sub(regexMap, '', line).split(',') key = line[0] value = line[1] mapping[key] = value return mapping # # return a List of JIRA Issues, querryd from JIRA JQL Filter, no JQL valid check # def getDEFECTS(self, jira_filter='project=DEFECT and status = Processed'): issues_in_project = None if self.srv: issues_in_project = self.srv.search_issues(jira_filter, maxResults=500) return issues_in_project # # return a String List of DEFECTS from a giving JIRA Filter # def getDEFECTSFromFilter( self, jira_filter='project=DEFECT and status = Processed'): jira_objects = self.getDEFECTS(jira_filter) list_of_defects = [] output_string = "" for obj in jira_objects: output_string += obj.key + '\n' list_of_defects.append(obj.key) with open('ListOfDefectsFromFilter.txt', 'w') as the_file: # 'a' for appending the_file.write(output_string) return list_of_defects # # return a JIRA DEFECT # def getJIssue(self, defect=''): issue_object = None if (isinstance(defect, str)) and (defect != '') and (self.srv): try: issue_object = self.srv.issue(defect) except Exception as e: print(e.text) return issue_object # # return a JIRA DEFECT # def getResolution(self, issue='DEFECT-8435'): issue = None resolution = None if self.srv: issue = self.srv.issue(issue, fields='resolution,status') resolution = issue.fields.resolution return "{}".format(resolution) # # return a JIRA DEFECT, returns Tuple (Status, QSapproval) # def getDEFECTstatusAndQS(self, issue='DEFECT-8000'): s1 = "" s2 = "" if self.srv: issue_object = self.srv.issue(issue) if issue_object: ticket_status = issue_object.fields.status s1 = "{}".format(ticket_status) if ('FEATURE' in issue): s2 = "" elif ('REQ' in issue): s2 = "" else: qsapproval = issue_object.fields.customfield_10126 #ticket_status = issue_object.fields.status #print("QS: ", qsapproval, " status: ", ticket_status) #s1 = "{}".format(ticket_status) s2 = "{}".format(qsapproval) return (s1, s2) # # get QS approval : Approval of QA-SW # def getStatus(self, issue_object): status = issue_object.fields.status return "{}".format(status) # # get QS approval : Approval of QA-SW # def getQSapproval(self, issue_object): ret = '' defect = issue_object.key if ('FEATURE' not in defect) and ('REQ' not in defect): qsapproval = issue_object.fields.customfield_10126 ret = "{}".format(qsapproval) return ret # # get Verifiable in SW Field, no access without admin permission to that values in jira # def getVerifiableInSW(self, issue_object): verifyInSW = None if self.srv: if issue_object: defect = issue_object.key if ('FEATURE' not in defect) and ('REQ' not in defect): verifyInSW = issue_object.fields.customfield_14002 return "{}".format(verifyInSW) # # get the Approval for integration in SW Field, ID Fields Values are stored in pentaho system # def getApprovalForIntegrationSW(self, issue_object): approval = [] if self.srv: if issue_object: defect = issue_object.key if ('DEFECT' in defect) or ('BUG' in defect) or ('FEATURE' in defect): list = "{}".format(issue_object.fields.customfield_10400) else: list = 'None' if (list != 'None'): tmpIds = re.findall(self.regexRelId, list) for id in tmpIds: if (id in self.mappingRelease): rel = self.mappingRelease[id] else: rel = '[%s]' % (id) approval.append(rel) pass return approval # # get duedate Field # def getDueDate(self, issue_object): duedate = None if self.srv: if issue_object: defect = issue_object.key if ('FEATURE' not in defect) and ('REQ' not in defect): duedate = issue_object.fields.duedate return "{}".format(duedate) # # get updated Field # def getupdatedDate(self, issue='DEFECT-8435'): updated = None if self.srv: issue_object = self.srv.issue(issue) if issue_object: updated = issue_object.fields.updated return "{}".format(updated) # # get summary Field, ist die Ueberschrift des Tickets # def getSummary(self, issue='DEFECT-8435'): summary = None if self.srv: issue_object = self.srv.issue(issue) if issue_object: summary = issue_object.fields.summary return "{}".format(summary) # # get description Field, ist die Beschreibung des Tickets # def getDescription(self, issue='DEFECT-8435'): description = None if self.srv: issue_object = self.srv.issue(issue) if issue_object: description = issue_object.fields.description return "{}".format(description) # # get priorty Field, ist die Prioritaet des Tickets # def getPrioritaet(self, issue='DEFECT-8435'): prio = None if self.srv: issue_object = self.srv.issue(issue) if issue_object: prio = issue_object.fields.priority.name return "{}".format(prio) # # get Label Field from JIRA Tickets # def getLabel(self, issue_object): label = [] defect = issue_object.key if ('FEATURE' not in defect) and ('REQ' not in defect): label = issue_object.fields.labels return label # # get IntegratedIntoSW Field from JIRA Tickets # def getSuggestedForIntegrationInSW(self, issue_object): suggestedSW = [] defect = issue_object.key if ('FEATURE' in defect) and ('REQ' not in defect) and ('DEFECT' not in defect): suggestedForIntegrationInSW = issue_object.fields.customfield_14402 suggestedSW = "{}".format(suggestedForIntegrationInSW) return suggestedSW # # get Team-develop Field # def getTeamDevelopment(self, issue='DEFECT-8435'): issue = None teamdevel = None if self.srv: if issue: teamdevel = issue.fields.customfield_10305 teamdevel = self.TeamDevelopMapping(teamdevel) return teamdevel # # misc mapping Method from literal in customfield to String, no access without admin permission to that values in jira # def TeamDevelopMapping(self, list_str): if list_str[0] == '35': return 'System-System' elif list_str[0] == '36': return 'System-Basisfunktion' elif list_str[0] == '37': return 'System-Vernetzung' else: return '' # # get all Git Information from a JIRA DEFECT # def getGitInformationFromComments(self, issue='DEFECT-8000'): if self.srv: issue = self.srv.issue(issue, fields='comment') #print(issue.fields.status) for comment in issue.fields.comment.comments: if comment.updateAuthor.displayName == "gitlab" or comment.updateAuthor.displayName == "my_special_user": git_info = comment.body[( comment.body.find("a commit of ") + len("a commit of ")):] return git_info # # get a List of Modules from JIRA DEFECT where gitlab changes (which Modules participate on that DEFECT) # def getModules(self, issue_with_key): liste = [] if self.srv: issue = self.srv.issue(issue_with_key, fields='comment') #print(issue.fields.status) for comment in issue.fields.comment.comments: if comment.updateAuthor.displayName == "gitlab" or comment.updateAuthor.displayName == "my_special_user": git_info = comment.body[( comment.body.find("a commit of ") + len("a commit of ")):] module = git_info[(git_info.find("/") + 1):git_info.rfind("|")] liste.append(module) # unique the list liste = list(set(liste)) return liste # # get a List of Commit ID from JIRA ISSUE / DEFECT # def getCommitIDs(self, issue_with_key): liste = [] if self.srv: issue = self.srv.issue(issue_with_key, fields='comment') #print(issue.fields.status) for comment in issue.fields.comment.comments: if comment.updateAuthor.displayName == "gitlab" or comment.updateAuthor.displayName == "my_special_user": git_info = comment.body[( comment.body.find("a commit of ") + len("a commit of ")):] commit_url = git_info[git_info.index(self.gitlab_url ):git_info.index("]")] commit_id = commit_url[(commit_url.rfind("/") + 1):] liste.append(commit_id) # unique the list liste = list(set(liste)) return liste # # get a List of Modules with CommitIDs from JIRA DEFECT where gitlab changes (which Modules participate on that DEFECT) # def getModulesWithCommitIDs(self, issue_with_key): liste = [] pair_module_commit = () if self.srv: issue = self.srv.issue(issue_with_key, fields='comment') for comment in issue.fields.comment.comments: if comment.updateAuthor.displayName == "gitlab" or comment.updateAuthor.displayName == "my_special_user": git_info = comment.body[( comment.body.find("a commit of ") + len("a commit of ")):] module = git_info[(git_info.find("/") + 1):git_info.rfind("|")] commit_url = git_info[git_info.index(self.gitlab_url ):git_info.index("]")] commit_id = commit_url[(commit_url.rfind("/") + 1):] pair_module_commit = (module, commit_id) liste.append(pair_module_commit) # unique the list liste = list(set(liste)) return liste # # set a ISSUE / DEFECT customfield_14002 = "Verifiable in SW" to a value (is hashed, no acces to JIRA DB possible ... plugin Problem) # dirty solution get hash onetime from a ticket # search for customfield_14002 value and give it this function, customfield_14002=["144601"] means: ... # def setTransistionForDefect(self, issue_with_key, value="144601"): if self.srv: self.srv.transition_issue(issue_with_key, '91', customfield_14002=[value]) # # setStatus to integrated for a list of DEFECT, ['DEFECT-1234', 'DEFECT-1253', ...] # RC_VERSION_HASH TODO: do mapping or query function # def setStatus(self, listOfDEFECTS, RC_VERSION_HASH): for defect in listOfDEFECTS: self.srv.setTransistionForDefect(defect, RC_VERSION_HASH) print(defect, " is set to Integrated") # update Verifiable in SW Field of an Issue # def updateVerifiableInSW(self, issue_object, newVersion={}): isTransistion = False transistion_id = 0 if issue_object: if 'text' in newVersion and 'id' in newVersion: print( "please use: newVersion={'id':'148201'} or newVersion={'text':'Release-123'} not both!" ) # wrong Ticket Status, do transistion issue status = str(issue_object.fields.status) if status == "Closed" or status == "Integration finished": #print("{} is {}".format(issue_object.key, issue_object.fields.status)) #return #TODO: call transistion issue function transistions = self.srv.transitions(issue_object) for transition in transistions: if transition['name'] == "correct issue": transition_id = transition['id'] break isTransistion = True # get old Verfiable in SW Data and convert newVersion Data to JIRA intern ID old_data = issue_object.fields.customfield_14002 new_data = [] fieldId = [] try: if 'text' in newVersion: tmp = newVersion['text'] for key, value in self.mappingRelease.items(): if tmp == value: #print("match") #print(key) #print(value) new_data = key break else: print("not found in mapping Table") elif 'id' in newVersion: new_data = newVersion['id'] if type(new_data) is not list: new_data = [new_data] def to_string(x): return str(x) if type(new_data) is list: map(to_string, new_data) except ValueError as e: print(e) # update the jira_issue if self.srv: #print("old: ",old_data) #print("new: ",new_data) for element in new_data: if element not in old_data: fieldId = old_data + new_data try: if isTransistion == False: issue_object.update( fields={"customfield_14002": fieldId}) elif isTransistion == True: self.srv.transition_issue( issue_object, transition_id, fields={"customfield_14002": fieldId}) print("{} is set now for {}".format( new_data, issue_object.key)) except Exception as e: print( "Konnte die Version nicht in das Ticket {} schreiben. Ursache: {}" .format(issue_object.key, e)) else: pass #print("{} is in {} already set".format(element, issue_object.key)) # # check Ticket for QSStatus # def checkTicket(self, defect="DEFECT-11192"): if isinstance(defect, str): ret = self.getDEFECTstatusAndQS(defect) return ret else: # this is not a string maybe jira object raise Exception # # get getMergeRequests # def getMergeRequests(self, issue_object): links = [] defect = issue_object.key if self.srv: link_objects = self.srv.remote_links(issue_object.key) for link in link_objects: if hasattr(link, "object"): if hasattr(link.object, "url"): if ("merge_requests" in link.object.url): links.append(link.object.url) return links # # get Deteils for Jira Item # def getJiraItemDetails2(self, issue='DEFECT-15531'): item = { 'status': '', 'QS': '', 'label': [], 'integrateInSW': '', 'duedate': '' } if isinstance(issue, str): if self.srv: issue_object = self.srv.issue(issue) if issue_object: ticket_status = issue_object.fields.status item['status'] = "{}".format(ticket_status) if ('FEATURE' in issue): suggestedForIntegrationInSW = issue_object.fields.customfield_14402 item['integrateInSW'] = "{}".format( suggestedForIntegrationInSW) elif ('REQ' in issue): pass # DEFECT, BUG, ... else: qsapproval = issue_object.fields.customfield_10126 suggestedForIntegrationInSW = issue_object.fields.customfield_10400 duedate = issue_object.fields.duedate ticket_label = issue_object.fields.labels item['QS'] = "{}".format(qsapproval) item['integrateInSW'] = "{}".format( suggestedForIntegrationInSW) item['duedate'] = "{}".format(duedate) item['label'] = ticket_label return item # # get Deteils for Jira Item # def getJiraItemDetails(self, defect): details = { 'status': '', 'QS': '', 'label': [], 'duedate': '', 'MR': [], 'approval': [], 'relevantToPlatform': [], 'SOP Date': '' } issue_object = self.getJIssue(defect) if (issue_object is not None): details['status'] = self.getStatus(issue_object) details['QS'] = self.getQSapproval(issue_object) details['label'] = self.getLabel(issue_object) details['duedate'] = self.getDueDate(issue_object) details['MR'] = self.getMergeRequests(issue_object) details['approval'] = self.getApprovalForIntegrationSW( issue_object) details['relevantToPlatform'] = self.getRelevantToPlatform( issue_object) details['SOP Date'] = self.getSOPDate(issue_object) return details # # set for a jira filter the VerifiableInSW # def setJIssues(self, jira_filter, newVerifiableInSW={'text': 'Release-123'}): issue_objects = self.getDEFECTS(jira_filter=jira_filter) if issue_objects: if 'text' in newVerifiableInSW: for issue_object in issue_objects: self.updateVerifiableInSW(issue_object, newVersion=newVerifiableInSW) else: print("no valid Version for a Jira Issue set.") else: print("no valid jira objects received.") # # manually calling jira rest api # def manualcall(self, calldata): output = "" try: cmd = [ 'curl', '-u', self.cred['user'] + ':' + self.cred['pass'], '-k', '-X', 'GET', '-H', "Content-Type: application/json", calldata ] p_gitlog = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) output, err = p_gitlog.communicate() #print(output) except subprocess.CalledProcessError as err: print(err.output, err.returncode, err.message) except Exception as err: print err if (p_gitlog.returncode != 0): print err return output
# 问题的类型 issue.fields.issuetype #问题报告者 issue.fields.reporter ''' import sys import argparse from commonfun import * from jira import JIRA from signalxls import * # from AnalyzeCan.projectInI import * jira = JIRA("http://jira.i-tetris.com/", basic_auth=("chengxiong.zhu", "@Huan2870244352")) useCases = [] def getBugId(bugId): bugId = str(bugId) if '-' not in bugId: bugId = Jira_Project + '-' + bugId return bugId def appendUseCases(case): if case.isVaild(): case.index = len(useCases) useCases.append(case)
# TODO: add simple error checking/exception handling for blank/invalid values for the above cnxn = pyodbc.connect(connstring) # now first start iterating through list of servers (contain 'ACTIVE' in jira_server_status column) # TODO: add error checking for blank/missing values, or servers that do not exist, etc. servercursor = cnxn.cursor() servercursor.execute( "SELECT * from jira_servers where (jira_server_status in ('ACTIVE'))") serverrows = servercursor.fetchall() for serverrow in serverrows: # for each Jira target server, create a connection object options = {"server": serverrow.jira_server_url} jira = JIRA( options, basic_auth=( serverrow.jira_server_username, serverrow.jira_server_apitoken)) # a username/password tupl # for Jira Cloud, it's a user email plus an API token generated under that user (for Jira Cloud you can't use login names) # for Jira Server, it's a login name plus the password for that login (Jira Server does not support API tokens) print("connecting to server " + serverrow.jira_server_url + " as " + serverrow.jira_server_username) # then get the list of the (identified) projects on that server, and iterate through each project projectcursor = cnxn.cursor() projectcursor.execute( "SELECT * from jira_projects where (jira_server_id = " + str(serverrow.jira_server_id) + ")") projectrows = projectcursor.fetchall() for projectrow in projectrows:
#!/usr/bin/env python # -*- coding: utf-8 -*- # # This script will cleanup your jira instance by removing all projects and # it is used to clean the CI/CD Jira server used for testing. # from __future__ import unicode_literals import os from jira import Role, Issue, JIRA, JIRAError, Project # noqa CI_JIRA_URL = os.environ['CI_JIRA_URL'] CI_JIRA_ADMIN = os.environ['CI_JIRA_ADMIN'] CI_JIRA_ADMIN_PASSWORD = os.environ['CI_JIRA_ADMIN_PASSWORD'] j = JIRA(CI_JIRA_URL, basic_auth=(CI_JIRA_ADMIN, CI_JIRA_ADMIN_PASSWORD), logging=True, validate=True, async_=True, async_workers=20) for p in j.projects(): print(p) try: j.delete_project(p) except Exception as e: print(e)
reports[key][1][x.key] = x.key else: if x.key not in reports[key][2]: reports[key][2][x.key] = x.key def dump(reports): # print 'Status for ' + name + ' ' + sprint.name format=u'{:<20}{:<10}{:<10}{:<10}' print format.format('Name', 'Completed', 'Todo', 'Status') for x in reports: done = len(reports[x][1].keys()) todo = len(reports[x][2].keys()) ratio = (float(done) / (done + todo)) * 100 print format.format(reports[x][0].encode('ascii', 'ignore'), done, todo, str(int(ratio)) + '%') usage = 'Usage: %prog -u <user> -p <pass> [-s <JIRA server>]' parser = OptionParser(usage) parser.add_option("-u", "--user", dest="usernameJIRA", help="JIRA Username") parser.add_option("-p", "--pwd", dest="passwordJIRA", help="JIRA Password") parser.add_option("-s", "--server", dest="jiraserver", default="https://issues.jboss.org", help="JIRA server, eg., https://issues.stage.jboss.org or https://issues.jboss.org") (options, args) = parser.parse_args() if not options.usernameJIRA or not options.passwordJIRA or not options.jiraserver: parser.error("Must specify ALL commandline flags") jira = JIRA(options={'server':options.jiraserver,'agile_rest_path':'agile'},basic_auth=(options.usernameJIRA,options.passwordJIRA)) reports = {} report(jira,'ASSparta',reports) report(jira,'devstudio everything',reports) report(jira,'devstudio everything else',reports) report(jira,'Build.next',reports) dump(reports)
def jira_notifier( tracked_obj: "Union[Flow, Task]", old_state: "prefect.engine.state.State", new_state: "prefect.engine.state.State", ignore_states: list = None, only_states: list = None, server_URL: str = None, options: Optional[dict] = None, assignee: str = "-1", ) -> "prefect.engine.state.State": """ Jira Notifier requires a Jira account and API token. The API token can be created at: https://id.atlassian.com/manage/api-tokens The Jira account username ('JIRAUSER'), API token ('JIRATOKEN') should be set as part of a 'JIRASECRETS' object in Prefect Secrets. An example 'JIRASECRETS' secret configuration looks like: ```toml [secrets] JIRASECRETS.JIRATOKEN = "XXXXXXXXX" JIRASECRETS.JIRAUSER = "******" JIRASECRETS.JIRASERVER = "https://???.atlassian.net" ``` The server URL can be set as part of the 'JIRASECRETS' object ('JIRASERVER') or passed to the jira notifier state handler as the "server_URL" argument. Jira Notifier works as a standalone state handler, or can be called from within a custom state handler. This function is curried meaning that it can be called multiple times to partially bind any keyword arguments (see example below). Jira Notifier creates a new ticket with the information about the task or flow it is bound to when that task or flow is in a specific state. (For example it will create a ticket to tell you that the flow you set it on is in a failed state.) You should use the options dictionary to set the project name and issue type. You can use the "assignee" argument to assign that ticket to a specific member of your team. Args: - tracked_obj (Task or Flow): Task or Flow object the handler is registered with - old_state (State): previous state of tracked object - new_state (State): new state of tracked object - options (Dictionary): Must inlucde a 'project' key and an 'issuetype' key (e.g. options = {'project': 'TEST', 'issuetype': {'name': 'task'}}). For jira service desk tickets, the issue type should use the request type id e.g. 'issuetype': {'id': '10010'}. A description can be added using the key 'description'. Custom fields can also be added e.g. 'customfield_10017': 'SDTS/flowdown' - ignore_states ([State], optional): list of `State` classes to ignore, e.g., `[Running, Scheduled]`. If `new_state` is an instance of one of the passed states, no notification will occur. - only_states ([State], optional): similar to `ignore_states`, but instead _only_ notifies you if the Task / Flow is in a state from the provided list of `State` classes - server_URL (String): The URL of your atlassian account e.g. "https://test.atlassian.net". Can also be set as a Prefect Secret. - assignee: the atlassian username of the person you want to assign the ticket to. Defaults to "automatic" if this is not set. Returns: - State: the `new_state` object that was provided Raises: - ValueError: if the jira ticket creation or assignment fails for any reason Example: ```python from prefect import task from prefect.utilities.jira_notification import jira_notifier @task(state_handlers=[ jira_notifier( only_states=[Failed], options={'project': 'TEST', 'issuetype': {'name': 'Task'}}, assignee='tester' ) ]) def add(x, y): return x + y ``` """ try: from jira import JIRA except ImportError as exc: raise ImportError( 'Using `jira_notifier` requires Prefect to be installed with the "jira" extra.' ) from exc options = options or dict() jira_credentials = cast(dict, prefect.client.Secret("JIRASECRETS").get()) username = jira_credentials["JIRAUSER"] password = jira_credentials["JIRATOKEN"] if not server_URL: server_URL = jira_credentials["JIRASERVER"] ignore_states = ignore_states or [] only_states = only_states or [] if any(isinstance(new_state, ignored) for ignored in ignore_states): return new_state if only_states and not any( [isinstance(new_state, included) for included in only_states]): return new_state summary_text = str(jira_message_formatter(tracked_obj, new_state)) options["summary"] = summary_text jira = JIRA(basic_auth=(username, password), options={"server": server_URL}) created = jira.create_issue(options) if not created: raise ValueError( "Creating Jira Issue for {} failed".format(tracked_obj)) if assignee: assigned = jira.assign_issue(created, assignee) if not assigned: raise ValueError( "Assigning Jira issue for {} failed".format(tracked_obj)) return new_state
from jira import JIRA from credentials import username, password debug = 0 jiraAttributes = 1 jira = JIRA(options={'server':'https://jira-stg.corp.linkedin.com:8443', 'verify':'/etc/ssl/certs/ca-bundle.crt'}, auth=(username, password) ) composedQuery = "" project = "project=LLSTC" summary = "" if summary: summary = ' AND summary ~ "'+summary+'"' assignee = "" if assignee: assignee = ' AND asignee ~ "'+assignee+'"' type = "task" if type: type = ' AND type = "'+type+'"' status = "" if status: status = ' AND status = "'+status+'"' composedQuery = project + summary + assignee + type + status print(composedQuery) issues_in_project = jira.search_issues(composedQuery, maxResults=1)
def delete_issue(request, find): j_issue = JIRA_Issue.objects.get(finding=find) jira = JIRA(server=Tool_config.url, basic_auth=(Tool_config.username, Tool_config.password)) issue = jira.issue(j_issue.jira_id) issue.delete()