Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Mute tools for pr #9468

Open
wants to merge 24 commits into
base: main
Choose a base branch
from
40 changes: 39 additions & 1 deletion .github/actions/test_ya/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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" \
Expand Down Expand Up @@ -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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Мне кажется лишняя проверка: файл наверное всегда должен быть?

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)"
Copy link
Collaborator

Choose a reason for hiding this comment

The 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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Тоже кажется лишняя проверка

LINE_COUNT_unmute=$(wc -l < "$FILE_PATH")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LINE_COUNT_unmute -- какой-то странный стайл именования, предлагаю всю перменную в uppercase

if [ "$LINE_COUNT_unmute" -gt 0 ]; then
MESSAGE="${MESSAGE}${SEPARATOR}Unmuted $LINE_COUNT_unmute [tests](${PUBLIC_DIR_URL}/mute_info/3_unmuted_tests.txt)"
Copy link
Collaborator

Choose a reason for hiding this comment

The 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
Expand Down
8 changes: 1 addition & 7 deletions .github/config/muted_ya.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ ydb/core/keyvalue/ut_trace TKeyValueTracingTest.*
ydb/core/kqp/provider/ut KikimrIcGateway.TestLoadBasicSecretValueFromExternalDataSourceMetadata
ydb/core/kqp/ut/olap KqpOlapBlobsSharing.*
ydb/core/kqp/ut/olap KqpOlapStatistics.StatsUsageWithTTL
ydb/core/kqp/ut/olap KqpOlapSysView.StatsSysViewBytesDictStatActualization
ydb/core/kqp/ut/pg KqpPg.CreateIndex
ydb/core/kqp/ut/query KqpLimits.QueryReplySize
ydb/core/kqp/ut/query KqpQuery.QueryTimeout
Expand All @@ -24,13 +25,6 @@ ydb/core/kqp/ut/service [*/*]*
ydb/core/kqp/ut/service KqpQueryService.ExecuteQueryPgTableSelect
ydb/core/kqp/ut/service KqpQueryService.QueryOnClosedSession
ydb/core/kqp/ut/service KqpService.CloseSessionsWithLoad
ydb/core/kqp/ut/service KqpQueryService.TableSink_OlapRWQueries
ydb/core/kqp/ut/service KqpQueryService.TableSink_Htap
ydb/core/kqp/ut/tx KqpSnapshotRead.ReadOnlyTxWithIndexCommitsOnConcurrentWrite+withSink
ydb/core/kqp/ut/tx KqpSinkMvcc.OltpNamedStatement
ydb/core/kqp/ut/tx KqpSinkMvcc.OlapNamedStatement
ydb/core/kqp/ut/tx KqpSinkMvcc.OltpMultiSinks
ydb/core/kqp/ut/tx KqpSinkMvcc.OlapMultiSinks
ydb/core/persqueue/ut [*/*]*
ydb/core/persqueue/ut TPQTest.*DirectRead*
ydb/core/persqueue/ut/ut_with_sdk [*/*]*
Expand Down
226 changes: 226 additions & 0 deletions .github/scripts/analytics/get_mute_issues.py
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()
52 changes: 52 additions & 0 deletions .github/scripts/tests/get_diff_lines_of_file.py
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):
Copy link
Collaborator

Choose a reason for hiding this comment

The 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)
Loading
Loading