Skip to content

Commit 332843a

Browse files
authored
Mute tools + mute info in for pr (#9714)
1 parent 18174b0 commit 332843a

File tree

5 files changed

+613
-2
lines changed

5 files changed

+613
-2
lines changed

.github/actions/test_ya/action.yml

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ runs:
399399
gzip -c $CURRENT_JUNIT_XML_PATH > $CURRENT_PUBLIC_DIR/orig_junit.xml.gz
400400

401401
# postprocess junit report
402-
.github/scripts/tests/transform-ya-junit.py -i \
402+
.github/scripts/tests/transform_ya_junit.py -i \
403403
-m .github/config/muted_ya.txt \
404404
--ya_out "$YA_MAKE_OUT_DIR" \
405405
--public_dir "$PUBLIC_DIR" \
@@ -533,6 +533,44 @@ runs:
533533
run: |
534534
.github/scripts/tests/fail-checker.py "$LAST_JUNIT_REPORT_XML"
535535
536+
- name: show diff mute_ya.txt
537+
if: inputs.build_preset == 'relwithdebinfo' && (github.event_name == 'pull_request' || github.event_name == 'pull_request_target')
538+
shell: bash
539+
continue-on-error: true
540+
env:
541+
GITHUB_TOKEN: ${{ github.token }}
542+
run: |
543+
ORIGINAL_HEAD=$(git rev-parse HEAD)
544+
get_file_diff_script=.github/scripts/tests/get_diff_lines_of_file.py
545+
file_to_check=.github/config/muted_ya.txt
546+
check_result=`$get_file_diff_script --base_sha $ORIGINAL_HEAD~1 --head_sha $ORIGINAL_HEAD --file_path $file_to_check`
547+
if [[ ${check_result} == *"not changed" ]];then
548+
echo file ${file_to_check} NOT changed
549+
else
550+
echo file ${file_to_check} changed
551+
.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}"
552+
FILE_PATH=$PUBLIC_DIR/mute_info/2_new_muted_tests.txt
553+
SEPARATOR=""
554+
if [ -f "$FILE_PATH" ]; then
555+
LINE_COUNT=$(wc -l < "$FILE_PATH")
556+
if [ "$LINE_COUNT" -gt 0 ]; then
557+
SEPARATOR=', '
558+
MESSAGE="Muted new $LINE_COUNT [tests](${PUBLIC_DIR_URL}/mute_info/2_new_muted_tests.txt)"
559+
fi
560+
fi
561+
FILE_PATH=$PUBLIC_DIR/mute_info/3_unmuted_tests.txt
562+
if [ -f "$FILE_PATH" ]; then
563+
LINE_COUNT_unmute=$(wc -l < "$FILE_PATH")
564+
if [ "$LINE_COUNT_unmute" -gt 0 ]; then
565+
MESSAGE="${MESSAGE}${SEPARATOR}Unmuted $LINE_COUNT_unmute [tests](${PUBLIC_DIR_URL}/mute_info/3_unmuted_tests.txt)"
566+
fi
567+
fi
568+
if [ -n "$MESSAGE" ]; then
569+
printf "$MESSAGE" | .github/scripts/tests/comment-pr.py --color orange
570+
fi
571+
fi
572+
573+
536574
- name: sync results to s3 and publish links
537575
if: always()
538576
shell: bash
@@ -602,4 +640,4 @@ runs:
602640
env:
603641
BUILD_PRESET: ${{ inputs.build_preset }}
604642
GITHUB_TOKEN: ${{ github.token }}
605-
run: echo "Check cancelled" | .github/scripts/tests/comment-pr.py --color black
643+
run: echo "Check cancelled" | .github/scripts/tests/comment-pr.py --color black
Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
import os
2+
import re
3+
import requests
4+
5+
ORG_NAME = 'ydb-platform'
6+
PROJECT_ID = '45'
7+
query_template = """
8+
{
9+
organization(login: "%s") {
10+
projectV2(number: %s) {
11+
id
12+
title
13+
items(first: 100, after: %s) {
14+
nodes {
15+
content {
16+
... on Issue {
17+
id
18+
title
19+
url
20+
state
21+
body
22+
createdAt
23+
}
24+
}
25+
fieldValues(first: 20) {
26+
nodes {
27+
... on ProjectV2ItemFieldSingleSelectValue {
28+
field {
29+
... on ProjectV2SingleSelectField {
30+
name
31+
}
32+
}
33+
name
34+
id
35+
updatedAt
36+
}
37+
... on ProjectV2ItemFieldLabelValue {
38+
labels(first: 20) {
39+
nodes {
40+
id
41+
name
42+
}
43+
}
44+
}
45+
... on ProjectV2ItemFieldTextValue {
46+
text
47+
id
48+
updatedAt
49+
creator {
50+
url
51+
}
52+
}
53+
... on ProjectV2ItemFieldMilestoneValue {
54+
milestone {
55+
id
56+
}
57+
}
58+
... on ProjectV2ItemFieldRepositoryValue {
59+
repository {
60+
id
61+
url
62+
}
63+
}
64+
}
65+
}
66+
}
67+
pageInfo {
68+
hasNextPage
69+
endCursor
70+
}
71+
}
72+
}
73+
}
74+
}
75+
"""
76+
77+
78+
def run_query(query, headers):
79+
request = requests.post('https://api.github.com/graphql', json={'query': query}, headers=headers)
80+
if request.status_code == 200:
81+
return request.json()
82+
else:
83+
raise Exception(f"Query failed to run by returning code of {request.status_code}. {query}")
84+
85+
86+
def fetch_all_issues(org_name, project_id):
87+
issues = []
88+
has_next_page = True
89+
end_cursor = "null"
90+
91+
while has_next_page:
92+
query = query_template % (org_name, project_id, end_cursor)
93+
GITHUB_TOKEN = os.environ["GITHUB_TOKEN"]
94+
headers = {"Authorization": f"Bearer {GITHUB_TOKEN}"}
95+
result = run_query(query, headers)
96+
97+
if result:
98+
project_items = result['data']['organization']['projectV2']['items']
99+
issues.extend(project_items['nodes'])
100+
101+
page_info = project_items['pageInfo']
102+
has_next_page = page_info['hasNextPage']
103+
end_cursor = f"\"{page_info['endCursor']}\"" if page_info['endCursor'] else "null"
104+
else:
105+
has_next_page = False
106+
107+
return issues
108+
109+
110+
def parse_body(body):
111+
tests = []
112+
branches = []
113+
prepared_body = ''
114+
start_mute_list = "<!--mute_list_start-->"
115+
end_mute_list = "<!--mute_list_end-->"
116+
start_branch_list = "<!--branch_list_start-->"
117+
end_branch_list = "<!--branch_list_end-->"
118+
119+
# tests
120+
if all(x in body for x in [start_mute_list, end_mute_list]):
121+
idx1 = body.find(start_mute_list)
122+
idx2 = body.find(end_mute_list)
123+
lines = body[idx1 + len(start_mute_list) + 1 : idx2].split('\n')
124+
else:
125+
if body.startswith('Mute:'):
126+
prepared_body = body.split('Mute:', 1)[1].strip()
127+
elif body.startswith('Mute'):
128+
prepared_body = body.split('Mute', 1)[1].strip()
129+
elif body.startswith('ydb'):
130+
prepared_body = body
131+
lines = prepared_body.split('**Add line to')[0].split('\n')
132+
tests = [line.strip() for line in lines if line.strip().startswith('ydb/')]
133+
134+
# branch
135+
if all(x in body for x in [start_branch_list, end_branch_list]):
136+
idx1 = body.find(start_branch_list)
137+
idx2 = body.find(end_branch_list)
138+
branches = body[idx1 + len(start_branch_list) + 1 : idx2].split('\n')
139+
else:
140+
branches = ['main']
141+
142+
return tests, branches
143+
144+
145+
def get_issues_and_tests_from_project(ORG_NAME, PROJECT_ID):
146+
issues = fetch_all_issues(ORG_NAME, PROJECT_ID)
147+
issues_prepared = {}
148+
for issue in issues:
149+
content = issue['content']
150+
if content:
151+
body = content['body']
152+
153+
# for debug
154+
if content['id'] == 'I_kwDOGzZjoM6V3BoE':
155+
print(1)
156+
#
157+
158+
tests, branches = parse_body(body)
159+
160+
field_values = issue.get('fieldValues', {}).get('nodes', [])
161+
for field_value in field_values:
162+
field_name = field_value.get('field', {}).get('name', '').lower()
163+
164+
if field_name == "status" and 'name' in field_value:
165+
status = field_value.get('name', 'N/A')
166+
status_updated = field_value.get('updatedAt', '1970-01-0901T00:00:01Z')
167+
elif field_name == "owner" and 'name' in field_value:
168+
owner = field_value.get('name', 'N/A')
169+
170+
print(f"Issue ID: {content['id']}")
171+
print(f"Title: {content['title']}")
172+
print(f"URL: {content['url']}")
173+
print(f"State: {content['state']}")
174+
print(f"CreatedAt: {content['createdAt']}")
175+
print(f"Status: {status}")
176+
print(f"Status updated: {status_updated}")
177+
print(f"Owner: {owner}")
178+
print("Tests:")
179+
180+
issues_prepared[content['id']] = {}
181+
issues_prepared[content['id']]['title'] = content['title']
182+
issues_prepared[content['id']]['url'] = content['url']
183+
issues_prepared[content['id']]['state'] = content['state']
184+
issues_prepared[content['id']]['createdAt'] = content['createdAt']
185+
issues_prepared[content['id']]['status_updated'] = status_updated
186+
issues_prepared[content['id']]['status'] = status
187+
issues_prepared[content['id']]['owner'] = owner
188+
issues_prepared[content['id']]['tests'] = []
189+
issues_prepared[content['id']]['branches'] = branches
190+
191+
for test in tests:
192+
issues_prepared[content['id']]['tests'].append(test)
193+
print(f"- {test}")
194+
print('\n')
195+
196+
return issues_prepared
197+
198+
199+
def get_muted_tests():
200+
issues = get_issues_and_tests_from_project(ORG_NAME, PROJECT_ID)
201+
muted_tests = {}
202+
for issue in issues:
203+
if issues[issue]["status"] == "Muted":
204+
for test in issues[issue]['tests']:
205+
if test not in muted_tests:
206+
muted_tests[test] = []
207+
muted_tests[test].append(
208+
{
209+
'url': issues[issue]['url'],
210+
'createdAt': issues[issue]['createdAt'],
211+
'status_updated': issues[issue]['status_updated'],
212+
}
213+
)
214+
215+
return muted_tests
216+
217+
218+
def main():
219+
if "GITHUB_TOKEN" not in os.environ:
220+
print("Error: Env variable GITHUB_TOKEN is missing, skipping")
221+
return 1
222+
get_muted_tests()
223+
224+
225+
if __name__ == "__main__":
226+
main()
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#!/usr/bin/env python3
2+
import argparse
3+
import json
4+
import os
5+
import requests
6+
import subprocess
7+
import sys
8+
9+
10+
def get_diff_lines_of_file(base_sha, head_sha, file_path):
11+
print(f"base_sha: {base_sha}")
12+
print(f"head_sha: {head_sha}")
13+
print(f"file_path: {file_path}")
14+
15+
# Use git to get two versions of file
16+
result_base = subprocess.run(['git', 'show', base_sha + ':' + file_path], capture_output=True, text=True)
17+
if result_base.returncode != 0:
18+
raise RuntimeError(f"Error running git show: {result_base.stderr}")
19+
20+
result_head = subprocess.run(['git', 'show', head_sha + ':' + file_path], capture_output=True, text=True)
21+
if result_head.returncode != 0:
22+
raise RuntimeError(f"Error running git show: {result_base.stderr}")
23+
24+
base_set_lines = set([line for line in result_base.stdout.splitlines() if line])
25+
head_set_lines = set([line for line in result_head.stdout.splitlines() if line])
26+
added_lines = list(head_set_lines - base_set_lines)
27+
removed_lines = list(base_set_lines - head_set_lines)
28+
print("\n### Added Lines:")
29+
print("\n".join(added_lines))
30+
print("\n### Removed Lines:")
31+
print("\n".join(removed_lines))
32+
return added_lines, removed_lines
33+
34+
35+
def main(base_sha, head_sha, file_path):
36+
added_lines, removed_lines = get_diff_lines_of_file(base_sha, head_sha, file_path)
37+
if added_lines or removed_lines:
38+
print(f"file {file_path} changed")
39+
else:
40+
print(f"file {file_path} not changed")
41+
42+
43+
if __name__ == "__main__":
44+
parser = argparse.ArgumentParser(
45+
description="Returns added and removed lines for file compared by git diff in two commit sha's"
46+
)
47+
parser.add_argument('--base_sha', type=str, required=True)
48+
parser.add_argument('--head_sha', type=str, required=True)
49+
parser.add_argument('--file_path', type=str, required=True)
50+
args = parser.parse_args()
51+
52+
main(args.base_sha, args.head_sha, args.file_path)

0 commit comments

Comments
 (0)