1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
|
import datetime
import logging
import os
import re
from typing import List, Any
from bs4 import BeautifulSoup
from github.Issue import Issue
from github.Repository import Repository
import requests
from azure.devops.v6_0.pipelines.pipelines_client import PipelinesClient
from azure.devops.v6_0.pipelines import models
from msrest.authentication import BasicAuthentication
REQUEST_REPO = 'Azure/sdk-release-request'
REST_REPO = 'Azure/azure-rest-api-specs'
AUTO_ASSIGN_LABEL = 'assigned'
AUTO_PARSE_LABEL = 'auto-link'
AUTO_CLOSE_LABEL = 'auto-close'
MULTI_LINK_LABEL = 'MultiLink'
INCONSISTENT_TAG = 'Inconsistent tag'
_LOG = logging.getLogger(__name__)
def get_origin_link_and_tag(issue_body_list: List[str]) -> (str, str):
link, readme_tag = '', ''
for row in issue_body_list:
if 'link' in row.lower() and 'release request' not in row.lower() and link == '':
link = row.split(":", 1)[-1].strip()
if 'readme tag' in row.lower() and readme_tag == '':
readme_tag = row.split(":", 1)[-1].strip()
if link and readme_tag:
break
if link.count('https') > 1:
link = link.split(']')[0]
link = link.replace('[', "").replace(']', "").replace('(', "").replace(')', "")
return link, readme_tag
def get_last_released_date(package_name: str) -> (str, str):
pypi_link = f'https://pypi.org/project/{package_name}/#history'
res = requests.get(pypi_link)
soup = BeautifulSoup(res.text, 'html.parser')
# find top div from <div class="release-timeline">
try:
package_info = soup.select('div[class="release-timeline"]')[0].find_all('div')[0]
last_version_mix = package_info.find_all('p', class_="release__version")[0].contents[0]
except IndexError as e:
return '', ''
last_version = last_version_mix.replace(' ', '').replace('\n', '')
last_version_date_str = package_info.time.attrs['datetime'].split('+')[0]
last_version_date = datetime.datetime.strptime(last_version_date_str, '%Y-%m-%dT%H:%M:%S')
return last_version, last_version_date
# get python release pipeline link from web
def get_python_release_pipeline(output_folder):
pipeline_client = PipelinesClient(base_url='https://dev.azure.com/azure-sdk',
creds=BasicAuthentication(os.getenv('PIPELINE_TOKEN'), ''))
pipelines = pipeline_client.list_pipelines(project='internal')
for pipeline in pipelines:
if re.findall('^python - \w*$', pipeline.name):
key = pipeline.name.replace('python - ', '')
if key == output_folder:
pipeline_url = 'https://dev.azure.com/azure-sdk/internal/_build?definitionId={}'.format(pipeline.id)
return pipeline_url
else:
_LOG.info('Cannot find definitionId, Do not display pipeline_url')
return ''
# Run sdk-auto-release(main) to generate SDK
def run_pipeline(issue_link, pipeline_url, spec_readme, python_tag="", rest_repo_hash=""):
paramaters = {
"stages_to_skip": [],
"resources": {
"repositories": {
"self": {
"refName": "refs/heads/main"
}
}
},
"variables": {
"BASE_BRANCH": {
"value": "",
"isSecret": False
},
"ISSUE_LINK": {
"value": issue_link,
"isSecret": False
},
"PIPELINE_LINK": {
"value": pipeline_url,
"isSecret": False
},
"SPEC_README": {
"value": spec_readme,
"isSecret": False
},
"PYTHON_TAG": {
"value": python_tag,
"isSecret": False
},
"REST_REPO_HASH": {
"value": rest_repo_hash,
"isSecret": False
}
}
}
# Fill in with your personal access token and org URL
personal_access_token = os.getenv('PIPELINE_TOKEN')
organization_url = 'https://dev.azure.com/azure-sdk'
# Create a connection to the org
credentials = BasicAuthentication('', personal_access_token)
run_parameters = models.RunPipelineParameters(**paramaters)
client = PipelinesClient(base_url=organization_url, creds=credentials)
result = client.run_pipeline(project='internal', pipeline_id=2500, run_parameters=run_parameters)
return result.state == 'inProgress'
def record_release(package_name: str, issue_info: Any, file: str, version: str) -> None:
created_at = issue_info.created_at.strftime('%Y-%m-%d')
closed_at = issue_info.closed_at.strftime('%Y-%m-%d')
assignee = issue_info.assignee.login
link = issue_info.html_url
is_stable = True if 'b' not in version else ''
closed_issue_info = f'{package_name},{assignee},{created_at},{closed_at},{link},{version},{is_stable}\n'
with open(file, 'r') as file_read:
lines = file_read.readlines()
with open(file, 'w') as file_write:
lines.insert(1, closed_issue_info)
file_write.writelines(lines)
class IssuePackage:
issue = None # origin issue instance
rest_repo = None # repo instance: Azure/azure-rest-api-specs
labels_name = {} # name set of issue labels
def __init__(self, issue: Issue, rest_repo: Repository):
self.issue = issue
self.rest_repo = rest_repo
self.labels_name = {label.name for label in issue.labels}
|