def test_create_feature(self): client = VstsClient(self.instance, self.personal_access_token) doc = JsonPatchDocument() doc.add(JsonPatchOperation('add', SystemFields.TITLE, 'Flying car')) doc.add( JsonPatchOperation('add', SystemFields.DESCRIPTION, 'A flying car')) doc.add( JsonPatchOperation( 'add', SystemFields.CREATED_BY, 'Robbie Coenmans <*****@*****.**>')) doc.add( JsonPatchOperation( 'add', SystemFields.ASSIGNED_TO, 'Robbie Coenmans <*****@*****.**>')) doc.add(JsonPatchOperation('add', SystemFields.TAGS, 'migrated')) doc.add( JsonPatchOperation('add', MicrosoftFields.VALUE_AREA, 'Business')) feature = client.create_workitem('Contoso', 'Feature', doc) self.assertIsNotNone(feature)
def test_create_epic(self): client = VstsClient(self.instance, self.personal_access_token) doc = JsonPatchDocument() doc.add(JsonPatchOperation('add', SystemFields.TITLE, 'Epic B')) doc.add( JsonPatchOperation('add', SystemFields.DESCRIPTION, 'This is *epic*')) doc.add( JsonPatchOperation( 'add', SystemFields.CREATED_BY, 'Robbie Coenmans <*****@*****.**>')) doc.add( JsonPatchOperation( 'add', SystemFields.ASSIGNED_TO, 'Robbie Coenmans <*****@*****.**>')) doc.add(JsonPatchOperation('add', SystemFields.TAGS, 'migrated')) doc.add( JsonPatchOperation('add', MicrosoftFields.VALUE_AREA, 'Architectural')) epic = client.create_workitem('Contoso', 'Epic', doc) self.assertIsNotNone(epic)
JsonPatchOperation('add', SystemFields.TITLE, file_n['fields']['System.Title'])) doc.add( JsonPatchOperation('add', SystemFields.AREA_PATH, r'<PROJECT>\<AREA PATH>')) doc.add( JsonPatchOperation('add', SystemFields.ITERATION_PATH, r'<PROJECT>\<ITERATION PATH>')) doc.add( JsonPatchOperation('add', SystemFields.ASSIGNED_TO, file_n['fields']['Assigned To'])) doc.add( JsonPatchOperation('add', SystemFields.DESCRIPTION, file_n['fields']['System.Description'])) #Creating the WIs with above 5 fields workitem = client.create_workitem('<PROJECT>', 'WI TYPE', doc) logging.info("<PROJECT> WI ID: " + workitem.id + "WI ID: " + file_n['fields']['System.Id']) try: doc.add( JsonPatchOperation('add', SystemFields.TAGS, file_n['fields']['System.Tags'])) # client.update_workitem(workitem.id,doc) except: pass try: doc.add( JsonPatchOperation('add', REF_NO, file_n['fields']['System.Id'])) # client.update_workitem(workitem.id, doc) except: pass
def lambda_handler(event, context): # Establish connection to mail server, login to account, and select INBOX to be working mailbox mail = email_Connection(emailHostNameEnvVar, emailUserNameEnvVar, emailPasswordEnvVar, "INBOX") # Initialize the VSTS client using the VSTS instance and personal access token # *******THIS TOKEN NEEDS TO BE REPLACED/RENEWED/UPDATED YEARLY******* client_GTS = VstsClient( vstsWIAccountEnvVar, vstsWIAcTokenEnvVar) # account instance + account token print(client_GTS) # Search the INBOX for emails from SC from the current day's date and previous day's date UID_List = Email_Search(mail, scEmailSearchEnvVar, 3) # Iterates through list of qualifying UIDs, extracts message data, moves message from Inbox to Archive, # creates Work ID Cards, reads/writes VSTS Work Item ID Number from/to S3 bucket, creates parent/child # connection between respective Work ID Cards for UIDNum in UID_List: emailInboxNumAsBytes, Subject, filtered_body = messageData( mail, UIDNum) # Checks to make sure the message is an Intake Request if Subject[:4] == "TASK": # Steps to Move a copy of SC Email to 'Archive/ServiceCafe' Folder - copy, store, expunge # creates a copy of the current SC Email in the 'Archive/ServiceCafe' Folder mail.copy(emailInboxNumAsBytes, 'Archive/ServiceCafe') print('copied') # Sets a flag for the original message to be deleted mail.store(emailInboxNumAsBytes, '+FLAGS', '\\Deleted') print('flagged') # Deletes all messages with the 'Delete' flag mail.expunge() print('deleted') # Generate data for VSTS Work Item Card as a Tuple WICardDataTuple = WICardData(filtered_body, Subject) # Creates JSON Patch Document for VSTS Work ID Card Creation WIJsonPatchDoc = createJsonWIDoc(WICardDataTuple) print("JSON Patch Document Created") print('\n') print(WIJsonPatchDoc) print('\n') # Create a new work item - REQUEST Card - by specifying the project and work item type new_WorkitemREQUEST = client_GTS.create_workitem( Project_GTS, # Working Team project name REQUEST, # Work item type (e.g. Epic, Feature, User Story etc.) WIJsonPatchDoc) # JsonPatchDocument with operations # Create a new work item - PBI (Product Backlog Item) Card - by specifying the project and work item type new_WorkitemPBI = client_GTS.create_workitem( Project_GTS, # Working Team project name PBI, # Work item type (e.g. Epic, Feature, User Story etc.) WIJsonPatchDoc) # JsonPatchDocument with operations # read file contents from AWS S3 Bucket to determine what ID Number to begin the iteratation process on workIDNumber = int( s3_Read_Str_from_TXT_File(bucket_name, s3_path_idNum)) print(workIDNumber) # iterates through the work items and creates a parent/child connection between the 2 that were just created parentToChildConnection(client_GTS, workIDNumber, WICardDataTuple) # Closes the active mailbox (INBOX) and shuts down connection to the server (logs out) email_Disconnect(mail) # this block of code checks the 'TOKEN_CHANGE_DATE' Environment Variable to see if an alert email needs to be sent out, then, # if an alert does need to be sent, it checks to see the most recent time one was sent. If it was sent more than two days ago # another email is sent. This occurs until the 'TOKEN_CHANGE_DATE' and the 'vstsWIAcToken' Environment Variables are updated. tokenChangedDays = dateDifCalculator(TokChangeDateEnvVar) if tokenChangeAlarm(tokenChangedDays): dateLastEmailAlertSent = s3_Read_Str_from_TXT_File( bucket_name, s3_path_emailSendDate) print(dateLastEmailAlertSent) if dateDifCalculator(dateLastEmailAlertSent) > 2: # VSTS Token Replacement Alert Email Creation: # - subject and body for alert email emailAlertSubject = "VSTS Account Token Change Alert!" emailAlertBody = "The Login Token for the Visual Studio Team Services (VSTS) Work Item Generator will be expiring soon. It is PERTINENT that the token be regenerated and updated in the Environment Variables section of the AWS (US East (Ohio) region) Lambda Function, \"VSTSWorkItemGenerator\".\n\n Environment Variables requiring an update:\n\n - vstsWIAcToken : contains the VSTS account token \n - TOKEN_CHANGE_DATE : contains the date on which the VSTS account token was updated\n\nSee VSTS_Work_Item_Generator Documentation for instructions on how to perform this update." # sends email alert to the respective recipient(s) sendEmail(emailHostNameEnvVar, smtpEmailUserNameEnvVar, emailPasswordEnvVar, senderEmailEnvVar, recipientEmailEnvVar, emailAlertSubject, emailAlertBody) print( "Email sent. It has been more than 3 days since the last email was sent." ) # generates a string that contains the date the email alert was just sent on emailSendDate = "Year: " + str( datetime.now().year) + " Month: " + str( datetime.now().month) + " Day: " + str(datetime.now().day) # writes the email send date string to the S3 contained .txt file s3_Write_Str_To_TXT_File(bucket_name, s3_path_emailSendDate, emailSendDate) else: print( "Email not sent. It has not been more than 3 days since the last email was sent." )
issue.assignee.email))) # Migrate any labels/tags if len(issue.labels) > 0: doc.add( JsonPatchOperation('add', SystemFields.TAGS, '; '.join(issue.labels))) # Make a note that the work item has been migrated doc.add(JsonPatchOperation('add', SystemFields.TAGS, 'migrated')) doc.add( JsonPatchOperation('add', SystemFields.HISTORY, 'Migrated from Jira to Azure DevOps')) # Create the work item in Azure DevOps workitem = vsts_client.create_workitem('Contoso', issue.type, doc, True) # Link to a feature (epic in Jira is mapped to Feature in DevOps but you can link it to an Epic as well) if issue.epic is not None: # Determine if the feature exists already feature = fetch_workitem(vsts_client, issue.epic.name) if feature is None: doc = JsonPatchDocument() doc.add( JsonPatchOperation('add', SystemFields.TITLE, issue.epic.name)) doc.add( JsonPatchOperation('add', SystemFields.DESCRIPTION, issue.epic.summary))