-
Notifications
You must be signed in to change notification settings - Fork 567
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mute tools for pr #9468
base: main
Are you sure you want to change the base?
Mute tools for pr #9468
Changes from all commits
66c2e30
5b4d234
b1ebd40
f717686
caeb50e
9a88666
d2d068f
b1a6316
a3600ed
b276922
4da83c7
162be0b
94b416f
bd74122
9af5a8a
0ca7347
0f608fd
7a78899
e65f04c
58b3880
14136cb
2c39c27
542d68f
d130043
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -399,7 +399,7 @@ runs: | |
gzip -c $CURRENT_JUNIT_XML_PATH > $CURRENT_PUBLIC_DIR/orig_junit.xml.gz | ||
|
||
# postprocess junit report | ||
.github/scripts/tests/transform-ya-junit.py -i \ | ||
.github/scripts/tests/transform_ya_junit.py -i \ | ||
-m .github/config/muted_ya.txt \ | ||
--ya_out "$YA_MAKE_OUT_DIR" \ | ||
--public_dir "$PUBLIC_DIR" \ | ||
|
@@ -533,6 +533,44 @@ runs: | |
run: | | ||
.github/scripts/tests/fail-checker.py "$LAST_JUNIT_REPORT_XML" | ||
|
||
- name: show diff mute_ya.txt | ||
if: inputs.build_preset == 'relwithdebinfo' && (github.event_name == 'pull_request' || github.event_name == 'pull_request_target') | ||
shell: bash | ||
continue-on-error: true | ||
env: | ||
GITHUB_TOKEN: ${{ github.token }} | ||
run: | | ||
ORIGINAL_HEAD=$(git rev-parse HEAD) | ||
get_file_diff_script=.github/scripts/tests/get_diff_lines_of_file.py | ||
file_to_check=.github/config/muted_ya.txt | ||
check_result=`$get_file_diff_script --base_sha $ORIGINAL_HEAD~1 --head_sha $ORIGINAL_HEAD --file_path $file_to_check` | ||
if [[ ${check_result} == *"not changed" ]];then | ||
echo file ${file_to_check} NOT changed | ||
else | ||
echo file ${file_to_check} changed | ||
.github/scripts/tests/get_muted_tests.py --output_folder "$PUBLIC_DIR/mute_info/" get_mute_diff --base_sha $ORIGINAL_HEAD~1 --head_sha $ORIGINAL_HEAD --job-id "${{ github.run_id }}" --branch "${GITHUB_REF_NAME}" | ||
FILE_PATH=$PUBLIC_DIR/mute_info/2_new_muted_tests.txt | ||
SEPARATOR="" | ||
if [ -f "$FILE_PATH" ]; then | ||
LINE_COUNT=$(wc -l < "$FILE_PATH") | ||
if [ "$LINE_COUNT" -gt 0 ]; then | ||
SEPARATOR=', ' | ||
MESSAGE="Muted new $LINE_COUNT [tests](${PUBLIC_DIR_URL}/mute_info/2_new_muted_tests.txt)" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Как вариант, возможно лучше бы формировать мессагу на уровне питона, а не программировать на баше |
||
fi | ||
fi | ||
FILE_PATH=$PUBLIC_DIR/mute_info/3_unmuted_tests.txt | ||
if [ -f "$FILE_PATH" ]; then | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Тоже кажется лишняя проверка |
||
LINE_COUNT_unmute=$(wc -l < "$FILE_PATH") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
if [ "$LINE_COUNT_unmute" -gt 0 ]; then | ||
MESSAGE="${MESSAGE}${SEPARATOR}Unmuted $LINE_COUNT_unmute [tests](${PUBLIC_DIR_URL}/mute_info/3_unmuted_tests.txt)" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Теперь я еще больше уверен, что надо на стороне питона формировать сообщение) Давай переделаем после залития |
||
fi | ||
fi | ||
if [ -n "$MESSAGE" ]; then | ||
printf "$MESSAGE" | .github/scripts/tests/comment-pr.py --color orange | ||
fi | ||
fi | ||
|
||
|
||
- name: sync results to s3 and publish links | ||
if: always() | ||
shell: bash | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,226 @@ | ||
import os | ||
import re | ||
import requests | ||
|
||
ORG_NAME = 'ydb-platform' | ||
PROJECT_ID = '45' | ||
query_template = """ | ||
{ | ||
organization(login: "%s") { | ||
projectV2(number: %s) { | ||
id | ||
title | ||
items(first: 100, after: %s) { | ||
nodes { | ||
content { | ||
... on Issue { | ||
id | ||
title | ||
url | ||
state | ||
body | ||
createdAt | ||
} | ||
} | ||
fieldValues(first: 20) { | ||
nodes { | ||
... on ProjectV2ItemFieldSingleSelectValue { | ||
field { | ||
... on ProjectV2SingleSelectField { | ||
name | ||
} | ||
} | ||
name | ||
id | ||
updatedAt | ||
} | ||
... on ProjectV2ItemFieldLabelValue { | ||
labels(first: 20) { | ||
nodes { | ||
id | ||
name | ||
} | ||
} | ||
} | ||
... on ProjectV2ItemFieldTextValue { | ||
text | ||
id | ||
updatedAt | ||
creator { | ||
url | ||
} | ||
} | ||
... on ProjectV2ItemFieldMilestoneValue { | ||
milestone { | ||
id | ||
} | ||
} | ||
... on ProjectV2ItemFieldRepositoryValue { | ||
repository { | ||
id | ||
url | ||
} | ||
} | ||
} | ||
} | ||
} | ||
pageInfo { | ||
hasNextPage | ||
endCursor | ||
} | ||
} | ||
} | ||
} | ||
} | ||
""" | ||
|
||
|
||
def run_query(query, headers): | ||
request = requests.post('https://api.github.com/graphql', json={'query': query}, headers=headers) | ||
if request.status_code == 200: | ||
return request.json() | ||
else: | ||
raise Exception(f"Query failed to run by returning code of {request.status_code}. {query}") | ||
|
||
maximyurchuk marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
def fetch_all_issues(org_name, project_id): | ||
issues = [] | ||
has_next_page = True | ||
end_cursor = "null" | ||
|
||
while has_next_page: | ||
query = query_template % (org_name, project_id, end_cursor) | ||
GITHUB_TOKEN = os.environ["GITHUB_TOKEN"] | ||
headers = {"Authorization": f"Bearer {GITHUB_TOKEN}"} | ||
result = run_query(query, headers) | ||
|
||
if result: | ||
project_items = result['data']['organization']['projectV2']['items'] | ||
issues.extend(project_items['nodes']) | ||
|
||
page_info = project_items['pageInfo'] | ||
has_next_page = page_info['hasNextPage'] | ||
end_cursor = f"\"{page_info['endCursor']}\"" if page_info['endCursor'] else "null" | ||
else: | ||
has_next_page = False | ||
|
||
return issues | ||
|
||
|
||
def parse_body(body): | ||
tests = [] | ||
branches = [] | ||
prepared_body = '' | ||
start_mute_list = "<!--mute_list_start-->" | ||
end_mute_list = "<!--mute_list_end-->" | ||
start_branch_list = "<!--branch_list_start-->" | ||
end_branch_list = "<!--branch_list_end-->" | ||
|
||
# tests | ||
if all(x in body for x in [start_mute_list, end_mute_list]): | ||
idx1 = body.find(start_mute_list) | ||
idx2 = body.find(end_mute_list) | ||
lines = body[idx1 + len(start_mute_list) + 1 : idx2].split('\n') | ||
else: | ||
if body.startswith('Mute:'): | ||
prepared_body = body.split('Mute:', 1)[1].strip() | ||
elif body.startswith('Mute'): | ||
prepared_body = body.split('Mute', 1)[1].strip() | ||
elif body.startswith('ydb'): | ||
prepared_body = body | ||
lines = prepared_body.split('**Add line to')[0].split('\n') | ||
tests = [line.strip() for line in lines if line.strip().startswith('ydb/')] | ||
|
||
# branch | ||
if all(x in body for x in [start_branch_list, end_branch_list]): | ||
idx1 = body.find(start_branch_list) | ||
idx2 = body.find(end_branch_list) | ||
branches = body[idx1 + len(start_branch_list) + 1 : idx2].split('\n') | ||
else: | ||
branches = ['main'] | ||
|
||
return tests, branches | ||
|
||
|
||
def get_issues_and_tests_from_project(ORG_NAME, PROJECT_ID): | ||
issues = fetch_all_issues(ORG_NAME, PROJECT_ID) | ||
issues_prepared = {} | ||
for issue in issues: | ||
content = issue['content'] | ||
if content: | ||
body = content['body'] | ||
|
||
# for debug | ||
if content['id'] == 'I_kwDOGzZjoM6V3BoE': | ||
print(1) | ||
# | ||
|
||
tests, branches = parse_body(body) | ||
|
||
field_values = issue.get('fieldValues', {}).get('nodes', []) | ||
for field_value in field_values: | ||
field_name = field_value.get('field', {}).get('name', '').lower() | ||
|
||
if field_name == "status" and 'name' in field_value: | ||
status = field_value.get('name', 'N/A') | ||
status_updated = field_value.get('updatedAt', '1970-01-0901T00:00:01Z') | ||
elif field_name == "owner" and 'name' in field_value: | ||
owner = field_value.get('name', 'N/A') | ||
|
||
print(f"Issue ID: {content['id']}") | ||
print(f"Title: {content['title']}") | ||
print(f"URL: {content['url']}") | ||
print(f"State: {content['state']}") | ||
print(f"CreatedAt: {content['createdAt']}") | ||
print(f"Status: {status}") | ||
print(f"Status updated: {status_updated}") | ||
print(f"Owner: {owner}") | ||
print("Tests:") | ||
|
||
issues_prepared[content['id']] = {} | ||
issues_prepared[content['id']]['title'] = content['title'] | ||
issues_prepared[content['id']]['url'] = content['url'] | ||
issues_prepared[content['id']]['state'] = content['state'] | ||
issues_prepared[content['id']]['createdAt'] = content['createdAt'] | ||
issues_prepared[content['id']]['status_updated'] = status_updated | ||
issues_prepared[content['id']]['status'] = status | ||
issues_prepared[content['id']]['owner'] = owner | ||
issues_prepared[content['id']]['tests'] = [] | ||
issues_prepared[content['id']]['branches'] = branches | ||
|
||
for test in tests: | ||
issues_prepared[content['id']]['tests'].append(test) | ||
print(f"- {test}") | ||
print('\n') | ||
|
||
return issues_prepared | ||
|
||
|
||
def get_muted_tests(): | ||
issues = get_issues_and_tests_from_project(ORG_NAME, PROJECT_ID) | ||
muted_tests = {} | ||
for issue in issues: | ||
if issues[issue]["status"] == "Muted": | ||
for test in issues[issue]['tests']: | ||
if test not in muted_tests: | ||
muted_tests[test] = [] | ||
muted_tests[test].append( | ||
{ | ||
'url': issues[issue]['url'], | ||
'createdAt': issues[issue]['createdAt'], | ||
'status_updated': issues[issue]['status_updated'], | ||
} | ||
) | ||
|
||
return muted_tests | ||
|
||
|
||
def main(): | ||
if "GITHUB_TOKEN" not in os.environ: | ||
print("Error: Env variable GITHUB_TOKEN is missing, skipping") | ||
return 1 | ||
get_muted_tests() | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
#!/usr/bin/env python3 | ||
import argparse | ||
import json | ||
import os | ||
import requests | ||
import subprocess | ||
import sys | ||
|
||
|
||
def get_diff_lines_of_file(base_sha, head_sha, file_path): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Я что-то не уверен, что есть потребность в отдельном файле для этой функции, предлагаю подумать чтобы пока переместить в место использования |
||
print(f"base_sha: {base_sha}") | ||
print(f"head_sha: {head_sha}") | ||
print(f"file_path: {file_path}") | ||
|
||
# Use git to get two versions of file | ||
result_base = subprocess.run(['git', 'show', base_sha + ':' + file_path], capture_output=True, text=True) | ||
if result_base.returncode != 0: | ||
raise RuntimeError(f"Error running git show: {result_base.stderr}") | ||
|
||
result_head = subprocess.run(['git', 'show', head_sha + ':' + file_path], capture_output=True, text=True) | ||
if result_head.returncode != 0: | ||
raise RuntimeError(f"Error running git show: {result_base.stderr}") | ||
|
||
base_set_lines = set([line for line in result_base.stdout.splitlines() if line]) | ||
head_set_lines = set([line for line in result_head.stdout.splitlines() if line]) | ||
added_lines = list(head_set_lines - base_set_lines) | ||
removed_lines = list(base_set_lines - head_set_lines) | ||
print("\n### Added Lines:") | ||
print("\n".join(added_lines)) | ||
print("\n### Removed Lines:") | ||
print("\n".join(removed_lines)) | ||
return added_lines, removed_lines | ||
|
||
|
||
def main(base_sha, head_sha, file_path): | ||
added_lines, removed_lines = get_diff_lines_of_file(base_sha, head_sha, file_path) | ||
if added_lines or removed_lines: | ||
print(f"file {file_path} changed") | ||
else: | ||
print(f"file {file_path} not changed") | ||
|
||
|
||
if __name__ == "__main__": | ||
parser = argparse.ArgumentParser( | ||
description="Returns added and removed lines for file compared by git diff in two commit sha's" | ||
) | ||
parser.add_argument('--base_sha', type=str, required=True) | ||
parser.add_argument('--head_sha', type=str, required=True) | ||
parser.add_argument('--file_path', type=str, required=True) | ||
args = parser.parse_args() | ||
|
||
main(args.base_sha, args.head_sha, args.file_path) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Мне кажется лишняя проверка: файл наверное всегда должен быть?