Skip to content

Commit 6cdb6d9

Browse files
authored
Merge 0c06345 into bc4696e
2 parents bc4696e + 0c06345 commit 6cdb6d9

File tree

2 files changed

+216
-1
lines changed

2 files changed

+216
-1
lines changed
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Script to create and update PR comments for test runs.
4+
Used by run_tests.yml workflow.
5+
"""
6+
import os
7+
import sys
8+
from github import Github, Auth as GithubAuth
9+
10+
def get_pr_number():
11+
"""Extract PR number from environment variable."""
12+
pr_number = os.environ.get("PR_NUMBER")
13+
if not pr_number:
14+
raise ValueError("PR_NUMBER environment variable is not set")
15+
16+
# Remove pull/ prefix if present
17+
if pr_number.startswith("pull/"):
18+
pr_number = pr_number.replace("pull/", "")
19+
20+
return int(pr_number)
21+
22+
def get_workflow_run_url():
23+
"""Get workflow run URL for identification."""
24+
github_server = os.environ.get("GITHUB_SERVER_URL")
25+
if not github_server:
26+
raise ValueError("GITHUB_SERVER_URL environment variable is not set")
27+
28+
github_repo = os.environ.get("GITHUB_REPOSITORY")
29+
if not github_repo:
30+
raise ValueError("GITHUB_REPOSITORY environment variable is not set")
31+
32+
run_id = os.environ.get("GITHUB_RUN_ID")
33+
if not run_id:
34+
raise ValueError("GITHUB_RUN_ID environment variable is not set")
35+
36+
return f"{github_server}/{github_repo}/actions/runs/{run_id}"
37+
38+
def create_or_update_comment(pr_number, message, workflow_run_url):
39+
"""Create or update PR comment with test run information."""
40+
github_token = os.environ.get("GITHUB_TOKEN")
41+
if not github_token:
42+
raise ValueError("GITHUB_TOKEN environment variable is not set")
43+
44+
github_repo = os.environ.get("GITHUB_REPOSITORY")
45+
if not github_repo:
46+
raise ValueError("GITHUB_REPOSITORY environment variable is not set")
47+
48+
gh = Github(auth=GithubAuth.Token(github_token))
49+
repo = gh.get_repo(github_repo)
50+
pr = repo.get_pull(pr_number)
51+
52+
# Find existing comment by workflow run URL
53+
comment = None
54+
for c in pr.get_issue_comments():
55+
if workflow_run_url in c.body:
56+
comment = c
57+
break
58+
59+
# Add workflow run link to message
60+
full_body = f"{message}\n\n[View workflow run]({workflow_run_url})"
61+
62+
if comment:
63+
print(f"::notice::Updating existing comment id={comment.id}")
64+
try:
65+
comment.edit(full_body)
66+
except Exception as e:
67+
print(f"::error::Failed to update comment id={comment.id}: {e}", file=sys.stderr)
68+
raise
69+
else:
70+
print(f"::notice::Creating new comment")
71+
try:
72+
pr.create_issue_comment(full_body)
73+
except Exception as e:
74+
print(f"::error::Failed to create new comment: {e}", file=sys.stderr)
75+
raise
76+
77+
def format_start_message(build_preset, test_size, test_targets):
78+
"""Format message for test run start."""
79+
parts = []
80+
parts.append("🧪 **Test Run Started**")
81+
parts.append("")
82+
83+
info = []
84+
info.append(f"**Build Preset:** `{build_preset}`")
85+
info.append(f"**Test Size:** `{test_size}`")
86+
87+
if test_targets and test_targets != "ydb/":
88+
info.append(f"**Test Targets:** `{test_targets}`")
89+
90+
parts.append("\n".join(info))
91+
parts.append("")
92+
parts.append("⏳ Tests are running...")
93+
94+
return "\n".join(parts)
95+
96+
def format_completion_message(build_preset, test_size, test_targets, summary_content, status):
97+
"""Format message for test run completion."""
98+
parts = []
99+
100+
# Status emoji
101+
if status == "success":
102+
parts.append("✅ **Test Run Completed Successfully**")
103+
elif status == "failure":
104+
parts.append("❌ **Test Run Failed**")
105+
elif status == "cancelled":
106+
parts.append("⚠️ **Test Run Cancelled**")
107+
else:
108+
parts.append("⚠️ **Test Run Completed**")
109+
110+
parts.append("")
111+
112+
info = []
113+
info.append(f"**Build Preset:** `{build_preset}`")
114+
info.append(f"**Test Size:** `{test_size}`")
115+
116+
if test_targets and test_targets != "ydb/":
117+
info.append(f"**Test Targets:** `{test_targets}`")
118+
119+
parts.append("\n".join(info))
120+
parts.append("")
121+
122+
# Add summary content if available
123+
if summary_content and summary_content.strip():
124+
parts.append("**Test Results:**")
125+
parts.append("")
126+
parts.append(summary_content.strip())
127+
128+
return "\n".join(parts)
129+
130+
if __name__ == "__main__":
131+
if len(sys.argv) < 2:
132+
print("::error::Usage: run_tests_pr_comment.py <start|complete>")
133+
sys.exit(1)
134+
135+
command = sys.argv[1]
136+
137+
if command not in ["start", "complete"]:
138+
print(f"::error::Unknown command: {command}. Must be 'start' or 'complete'")
139+
sys.exit(1)
140+
141+
pr_number = get_pr_number()
142+
143+
build_preset = os.environ.get("BUILD_PRESET")
144+
if not build_preset:
145+
raise ValueError("BUILD_PRESET environment variable is not set")
146+
147+
test_size = os.environ.get("TEST_SIZE")
148+
if not test_size:
149+
raise ValueError("TEST_SIZE environment variable is not set")
150+
151+
test_targets = os.environ.get("TEST_TARGETS", "ydb/")
152+
153+
workflow_run_url = get_workflow_run_url()
154+
155+
if command == "start":
156+
message = format_start_message(build_preset, test_size, test_targets)
157+
create_or_update_comment(pr_number, message, workflow_run_url)
158+
else: # complete
159+
status = os.environ.get("TEST_STATUS")
160+
if not status:
161+
raise ValueError("TEST_STATUS environment variable is not set")
162+
163+
# Read summary from summary_text.txt in workspace
164+
workspace = os.environ.get("GITHUB_WORKSPACE")
165+
if not workspace:
166+
raise ValueError("GITHUB_WORKSPACE environment variable is not set")
167+
summary_text_path = os.path.join(workspace, "summary_text.txt")
168+
169+
summary_content = ""
170+
if os.path.exists(summary_text_path):
171+
with open(summary_text_path, 'r', encoding='utf-8') as f:
172+
summary_content = f.read()
173+
if summary_content.strip():
174+
print(f"::notice::Read {len(summary_content)} characters from {summary_text_path}")
175+
else:
176+
print(f"::warning::Summary file {summary_text_path} is empty")
177+
else:
178+
print(f"::warning::Summary file not found: {summary_text_path}")
179+
180+
message = format_completion_message(
181+
build_preset, test_size, test_targets,
182+
summary_content, status
183+
)
184+
create_or_update_comment(pr_number, message, workflow_run_url)
185+

.github/workflows/run_tests.yml

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ on:
5959
default: small,medium,large
6060
options:
6161
- small
62-
- medium,
62+
- medium
6363
- large
6464
- small,medium
6565
- small,medium,large
@@ -93,6 +93,7 @@ jobs:
9393
with:
9494
sparse-checkout: |
9595
.github/config/stable_branches.json
96+
.github/scripts/run_tests_pr_comment.py
9697
9798
- name: Set branches
9899
id: set-branches
@@ -163,6 +164,21 @@ jobs:
163164
164165
echo "Final branches to use: $(cat $GITHUB_OUTPUT | grep branch_array | cut -d= -f2)"
165166
167+
- name: Post start comment to PR
168+
if: inputs.pull_number != ''
169+
env:
170+
GITHUB_TOKEN: ${{ github.token }}
171+
PR_NUMBER: ${{ inputs.pull_number }}
172+
BUILD_PRESET: ${{ inputs.build_preset }}
173+
TEST_SIZE: ${{ inputs.test_size }}
174+
TEST_TARGETS: ${{ inputs.test_targets }}
175+
GITHUB_SERVER_URL: ${{ github.server_url }}
176+
GITHUB_REPOSITORY: ${{ github.repository }}
177+
GITHUB_RUN_ID: ${{ github.run_id }}
178+
run: |
179+
python3 -m pip install PyGithub -q
180+
python3 ./.github/scripts/run_tests_pr_comment.py start
181+
166182
run_tests:
167183
needs: prepare
168184
name: ${{ matrix.branch }}:${{ inputs.build_preset }}
@@ -204,6 +220,7 @@ jobs:
204220
ci_ydb_service_account_key_file_credentials: ${{ secrets.CI_YDB_SERVICE_ACCOUNT_KEY_FILE_CREDENTIALS }}
205221

206222
- name: Run YDB Tests
223+
id: run_tests
207224
timeout-minutes: ${{ fromJson(env.timeout) }}
208225
uses: ./.github/actions/build_and_test_ya
209226
with:
@@ -224,3 +241,16 @@ jobs:
224241
secrets.AWS_KEY_ID, secrets.AWS_KEY_VALUE, secrets.REMOTE_CACHE_USERNAME, secrets.REMOTE_CACHE_PASSWORD, secrets.TELEGRAM_YDBOT_TOKEN ) }}
225242
vars: ${{ format('{{"AWS_BUCKET":"{0}","AWS_ENDPOINT":"{1}","REMOTE_CACHE_URL":"{2}","GH_ALERTS_TG_LOGINS":"{3}","GH_ALERTS_TG_CHAT":"{4}"}}',
226243
vars.AWS_BUCKET, vars.AWS_ENDPOINT, vars.REMOTE_CACHE_URL_YA, vars.GH_ALERTS_TG_LOGINS, vars.GH_ALERTS_TG_CHAT ) }}
244+
245+
- name: Update PR comment with results
246+
if: always() && inputs.pull_number != ''
247+
env:
248+
GITHUB_TOKEN: ${{ github.token }}
249+
PR_NUMBER: ${{ inputs.pull_number }}
250+
BUILD_PRESET: ${{ inputs.build_preset }}
251+
TEST_SIZE: ${{ inputs.test_size }}
252+
TEST_TARGETS: ${{ inputs.test_targets }}
253+
TEST_STATUS: ${{ steps.run_tests.outcome }}
254+
run: |
255+
python3 -m pip install PyGithub -q
256+
python3 ./.github/scripts/run_tests_pr_comment.py complete

0 commit comments

Comments
 (0)