From bb0b6e410b995b68bfbe6e49d5038493cc367d14 Mon Sep 17 00:00:00 2001 From: naspirato Date: Mon, 10 Nov 2025 12:22:10 +0100 Subject: [PATCH 1/6] init --- .../tests/process_muted_tests_after_merge.py | 243 ++++++++++++++++++ .../create_issues_for_muted_tests.yml | 108 ++++---- .../reusable/update_ydb_for_muted_tests.yml | 45 ++++ .github/workflows/update_muted_ya.yml | 17 +- 4 files changed, 339 insertions(+), 74 deletions(-) create mode 100755 .github/scripts/tests/process_muted_tests_after_merge.py create mode 100644 .github/workflows/reusable/update_ydb_for_muted_tests.yml diff --git a/.github/scripts/tests/process_muted_tests_after_merge.py b/.github/scripts/tests/process_muted_tests_after_merge.py new file mode 100755 index 000000000000..f3ca4dcb7b3f --- /dev/null +++ b/.github/scripts/tests/process_muted_tests_after_merge.py @@ -0,0 +1,243 @@ +#!/usr/bin/env python3 +""" +Process muted tests after PR merge: +- Get PR data from GitHub API +- Get muted_ya.txt from merge commit +- Create issues (if main branch) +- Send Telegram notifications (if main branch) +- Comment PR +""" +import os +import sys +import argparse +import subprocess +from pathlib import Path +from github import Github + +# Add scripts directory to path +sys.path.append(os.path.dirname(os.path.abspath(__file__))) +sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'telegram')) + + +def get_pr_data(github_token, repository, event_name, pr_number=None): + """Get PR data from GitHub API""" + g = Github(github_token) + repo = g.get_repo(repository) + + if not pr_number: + raise ValueError("PR number is required") + + pr = repo.get_pull(int(pr_number)) + + return { + 'number': pr.number, + 'base_branch': pr.base.ref, + 'merge_commit_sha': pr.merge_commit_sha, + 'merged': pr.merged, + 'labels': [label.name for label in pr.labels] + } + + +def get_muted_ya_from_commit(merge_commit_sha, base_branch, output_path='muted_ya.txt'): + """Get muted_ya.txt from merge commit or base branch""" + try: + if merge_commit_sha: + print(f"Getting muted_ya.txt from merge commit: {merge_commit_sha}") + subprocess.run( + ['git', 'fetch', 'origin', merge_commit_sha], + capture_output=True, + text=True, + check=True + ) + result = subprocess.run( + ['git', 'show', f'{merge_commit_sha}:.github/config/muted_ya.txt'], + capture_output=True, + text=True, + check=True + ) + with open(output_path, 'w') as f: + f.write(result.stdout) + print(f"✓ Retrieved muted_ya.txt from merge commit") + return output_path + else: + print(f"⚠️ Merge commit SHA not available, trying to get from base branch: {base_branch}") + subprocess.run( + ['git', 'fetch', 'origin', base_branch], + capture_output=True, + text=True, + check=True + ) + result = subprocess.run( + ['git', 'show', f'origin/{base_branch}:.github/config/muted_ya.txt'], + capture_output=True, + text=True, + check=True + ) + with open(output_path, 'w') as f: + f.write(result.stdout) + print(f"✓ Retrieved muted_ya.txt from base branch") + return output_path + except subprocess.CalledProcessError as e: + print(f"Error getting muted_ya.txt: {e}") + if e.stderr: + print(f"stderr: {e.stderr}") + raise + + +def create_issues_for_muted_tests(muted_ya_path, branch): + """Create issues for muted tests""" + print(f"Creating issues for muted tests from {muted_ya_path}") + script_path = os.path.join( + os.path.dirname(__file__), + 'create_new_muted_ya.py' + ) + + result = subprocess.run( + [ + sys.executable, script_path, 'create_issues', + '--file_path', os.path.abspath(muted_ya_path), + '--branch', branch + ], + capture_output=True, + text=True + ) + + if result.returncode != 0: + print(f"Error creating issues: {result.stderr}") + return None + + issues_file = os.path.join(os.getcwd(), 'created_issues.txt') + if os.path.exists(issues_file): + print(f"✓ Issues created, results in {issues_file}") + return issues_file + return None + + +def send_telegram_notifications(issues_file, telegram_bot_token, team_channels): + """Send Telegram notifications""" + if not issues_file or not os.path.exists(issues_file): + print("No issues file, skipping Telegram notifications") + return + + print("Sending Telegram notifications...") + script_path = os.path.join( + os.path.dirname(__file__), + '..', 'telegram', 'parse_and_send_team_issues.py' + ) + + result = subprocess.run( + [ + sys.executable, script_path, + '--on-mute-change-update', + '--file', issues_file, + '--bot-token', telegram_bot_token, + '--team-channels', team_channels, + '--include-plots', + '--delay', '2' + ], + capture_output=True, + text=True + ) + + if result.returncode != 0: + print(f"Error sending Telegram notifications: {result.stderr}") + else: + print("✓ Telegram notifications sent") + + +def comment_pr(github_token, repository, pr_number, base_branch, issues_file, run_id, run_number): + """Comment on PR""" + g = Github(github_token) + repo = g.get_repo(repository) + pr = repo.get_issue(int(pr_number)) + + workflow_url = f"https://github.com/{repository}/actions/runs/{run_id}" + body = f"Workflow completed for branch {base_branch} in workflow [#{run_number}]({workflow_url})\n\n" + + if issues_file and os.path.exists(issues_file): + with open(issues_file, 'r') as f: + body += f.read() + else: + body += "Muted tests data updated in YDB. Issues creation and Telegram notifications are only performed for main branch." + + pr.create_comment(body) + print(f"✓ Comment added to PR #{pr_number}") + + +def main(): + parser = argparse.ArgumentParser(description="Process muted tests after PR merge") + parser.add_argument('--event_name', required=True, help='GitHub event name') + parser.add_argument('--pr_number', help='PR number') + parser.add_argument('--merge_commit_sha', help='Merge commit SHA') + parser.add_argument('--base_branch', help='Base branch') + parser.add_argument('--build_type', default='relwithdebinfo', help='Build type') + + args = parser.parse_args() + + # Get GitHub token and repository from environment + github_token = os.environ.get('GITHUB_TOKEN') + if not github_token: + raise ValueError("GITHUB_TOKEN environment variable is required") + + repository = os.environ.get('GITHUB_REPOSITORY') + if not repository: + raise ValueError("GITHUB_REPOSITORY environment variable is required") + + run_id = os.environ.get('GITHUB_RUN_ID', '') + run_number = os.environ.get('GITHUB_RUN_NUMBER', '') + + # Get PR data if pr_number is provided + pr_data = None + if args.pr_number: + print("Getting PR data from GitHub...") + pr_data = get_pr_data( + github_token, + repository, + args.event_name, + args.pr_number + ) + + # Use provided values or from PR data + base_branch = args.base_branch or (pr_data['base_branch'] if pr_data else None) + merge_commit_sha = args.merge_commit_sha or (pr_data['merge_commit_sha'] if pr_data else None) + pr_number = args.pr_number or (pr_data['number'] if pr_data else None) + + if not base_branch: + raise ValueError("Base branch is required (provide --base_branch or --pr_number)") + if not pr_number: + raise ValueError("PR number is required (provide --pr_number)") + + is_main = base_branch == 'main' + + print(f"PR #{pr_number}: base_branch={base_branch}, is_main={is_main}") + + # Get muted_ya.txt from merge commit + muted_ya_path = get_muted_ya_from_commit(merge_commit_sha, base_branch) + + # Create issues and send Telegram (only for main) + issues_file = None + if is_main: + issues_file = create_issues_for_muted_tests(muted_ya_path, base_branch) + + telegram_bot_token = os.environ.get('TELEGRAM_BOT_TOKEN') + team_channels = os.environ.get('TEAM_CHANNELS') + if telegram_bot_token and team_channels: + send_telegram_notifications(issues_file, telegram_bot_token, team_channels) + + # Comment PR (for all branches) + comment_pr( + github_token, + repository, + pr_number, + base_branch, + issues_file, + run_id, + run_number + ) + + print("✓ Process completed successfully") + + +if __name__ == "__main__": + main() + diff --git a/.github/workflows/create_issues_for_muted_tests.yml b/.github/workflows/create_issues_for_muted_tests.yml index 5218fb496ab0..57e503a8b133 100644 --- a/.github/workflows/create_issues_for_muted_tests.yml +++ b/.github/workflows/create_issues_for_muted_tests.yml @@ -1,93 +1,71 @@ name: Create issues for muted tests on: - pull_request_review: + pull_request: types: - - submitted - branches: - - main + - closed workflow_dispatch: inputs: - pr_number: - description: 'The pull request number' - required: true - type: number + pr_number: + description: 'The pull request number' + required: true + type: number env: GH_TOKEN: ${{ secrets.YDBOT_TOKEN }} - MUTED_YA_FILE_PATH: .github/config/muted_ya.txt + BUILD_TYPE: relwithdebinfo jobs: - create-issues-for-muted-tests: - runs-on: ubuntu-latest + update-ydb: if: | - ((github.event_name == 'pull_request_review' && - github.event.review.state == 'approved' && - contains(github.event.pull_request.labels.*.name, 'mute-unmute') && - github.event.pull_request.base.ref == 'main') || + ((github.event_name == 'pull_request' && + github.event.pull_request.merged == true && + contains(github.event.pull_request.labels.*.name, 'mute-unmute')) || github.event_name == 'workflow_dispatch') + uses: ./.github/workflows/reusable/update_ydb_for_muted_tests.yml + with: + branch: ${{ github.event.pull_request.base.ref || 'main' }} + build_type: ${{ env.BUILD_TYPE }} + secrets: + CI_YDB_SERVICE_ACCOUNT_KEY_FILE_CREDENTIALS: ${{ secrets.CI_YDB_SERVICE_ACCOUNT_KEY_FILE_CREDENTIALS }} + process-muted-tests: + needs: update-ydb + if: | + ((github.event_name == 'pull_request' && + github.event.pull_request.merged == true && + contains(github.event.pull_request.labels.*.name, 'mute-unmute')) || + github.event_name == 'workflow_dispatch') + runs-on: ubuntu-latest steps: - - name: Set environment variables for branches - run: | - echo "BRANCH_FOR_PR=${{ github.event.pull_request.head.ref || github.head_ref }}" >> $GITHUB_ENV - echo "BASE_BRANCH=${{ github.event.pull_request.base.ref || github.base_ref }}" >> $GITHUB_ENV - - name: Checkout repository uses: actions/checkout@v4 with: - ref: ${{ github.event.pull_request.head.ref || github.head_ref }} - + ref: main + fetch-depth: 0 + - name: Install dependencies run: | - python -m pip install --upgrade pip - pip install ydb[yc] PyGithub requests matplotlib numpy - + python -m pip install --upgrade pip + pip install ydb[yc] PyGithub requests matplotlib numpy + - name: Setup ydb access uses: ./.github/actions/setup_ci_ydb_service_account_key_file_credentials with: - ci_ydb_service_account_key_file_credentials: ${{ secrets.CI_YDB_SERVICE_ACCOUNT_KEY_FILE_CREDENTIALS }} - - - name: Create issues for muted tests - id: create_issues - env: - GITHUB_TOKEN: ${{ env.GH_TOKEN }} - run: .github/scripts/tests/create_new_muted_ya.py create_issues --file_path=${{ github.workspace }}/${{ env.MUTED_YA_FILE_PATH }} - - - name: Add issues to PR - env: - GITHUB_TOKEN: ${{ env.GH_TOKEN }} - run: python .github/scripts/create_or_update_pr.py append_pr_body --pr_number=${{ github.event.pull_request.number || github.event.inputs.pr_number }} --body=${{ steps.create_issues.outputs.created_issues_file }} - - - name: Comment PR - uses: actions/github-script@v7 - with: - github-token: ${{ env.GH_TOKEN }} - script: | - const fs = require('fs'); - const path = require('path'); - - const workflowUrl = `https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}`; - const filePath = '${{ steps.create_issues.outputs.created_issues_file }}'; - const bodyText = fs.readFileSync(filePath, 'utf8'); - const completeBody = `Collected in workflow [#${{ github.run_number }}](${workflowUrl})\n\n${bodyText}`; + ci_ydb_service_account_key_file_credentials: ${{ secrets.CI_YDB_SERVICE_ACCOUNT_KEY_FILE_CREDENTIALS }} - github.rest.issues.createComment({ - issue_number: ${{ github.event.pull_request.number || github.event.inputs.pr_number }}, - owner: context.repo.owner, - repo: context.repo.repo, - body: completeBody - }); - - - name: Send team-specific messages to Telegram + - name: Process muted tests after merge env: + GITHUB_TOKEN: ${{ secrets.YDBOT_TOKEN }} TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_YDBOT_TOKEN }} TEAM_CHANNELS: ${{ vars.TG_TEAM_CHANNELS }} + GITHUB_REPOSITORY: ${{ github.repository }} + GITHUB_RUN_ID: ${{ github.run_id }} + GITHUB_RUN_NUMBER: ${{ github.run_number }} run: | - python .github/scripts/telegram/parse_and_send_team_issues.py \ - --on-mute-change-update \ - --file "${{ steps.create_issues.outputs.created_issues_file }}" \ - --bot-token "$TELEGRAM_BOT_TOKEN" \ - --team-channels "$TEAM_CHANNELS" \ - --include-plots \ - --delay 2 + python3 .github/scripts/tests/process_muted_tests_after_merge.py \ + --event_name="${{ github.event_name }}" \ + --pr_number="${{ github.event.pull_request.number || github.event.inputs.pr_number }}" \ + --merge_commit_sha="${{ github.event.pull_request.merge_commit_sha }}" \ + --base_branch="${{ github.event.pull_request.base.ref }}" \ + --build_type="${{ env.BUILD_TYPE }}" diff --git a/.github/workflows/reusable/update_ydb_for_muted_tests.yml b/.github/workflows/reusable/update_ydb_for_muted_tests.yml new file mode 100644 index 000000000000..e77004b64309 --- /dev/null +++ b/.github/workflows/reusable/update_ydb_for_muted_tests.yml @@ -0,0 +1,45 @@ +name: Update YDB for muted tests + +on: + workflow_call: + inputs: + branch: + required: true + type: string + build_type: + required: true + type: string + default: 'relwithdebinfo' + secrets: + CI_YDB_SERVICE_ACCOUNT_KEY_FILE_CREDENTIALS: + required: true + +jobs: + update-ydb: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + ref: main + fetch-depth: 0 + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install ydb[yc] codeowners pandas + + - name: Setup ydb access + uses: ./.github/actions/setup_ci_ydb_service_account_key_file_credentials + with: + ci_ydb_service_account_key_file_credentials: ${{ secrets.CI_YDB_SERVICE_ACCOUNT_KEY_FILE_CREDENTIALS }} + + - name: Collect test history data + run: python3 .github/scripts/analytics/flaky_tests_history.py --branch=${{ inputs.branch }} --build_type=${{ inputs.build_type }} + + - name: Update muted tests in DB + run: python3 .github/scripts/tests/get_muted_tests.py upload_muted_tests --branch=${{ inputs.branch }} --build_type=${{ inputs.build_type }} + + - name: Update test monitor + run: python3 .github/scripts/analytics/tests_monitor.py --branch=${{ inputs.branch }} --build_type=${{ inputs.build_type }} + diff --git a/.github/workflows/update_muted_ya.yml b/.github/workflows/update_muted_ya.yml index 554e98225f40..461876f84ece 100644 --- a/.github/workflows/update_muted_ya.yml +++ b/.github/workflows/update_muted_ya.yml @@ -71,7 +71,7 @@ jobs: - name: Checkout main branch uses: actions/checkout@v4 with: - ref: main + ref: muted_ya_new_iteration fetch-depth: 0 - name: Install dependencies @@ -92,14 +92,13 @@ jobs: git show origin/${{ env.BASE_BRANCH }}:.github/config/muted_ya.txt > base_muted_ya.txt echo "✓ Retrieved base muted_ya.txt from ${{ env.BASE_BRANCH }}" - - name: Collect test history data - run: python3 .github/scripts/analytics/flaky_tests_history.py --branch=${{ env.BASE_BRANCH }} --build_type=${{ env.BUILD_TYPE }} - - - name: Update muted tests in DB - run: python3 .github/scripts/tests/get_muted_tests.py upload_muted_tests --branch=${{ env.BASE_BRANCH }} --build_type=${{ env.BUILD_TYPE }} - - - name: Update test monitor - run: python3 .github/scripts/analytics/tests_monitor.py --branch=${{ env.BASE_BRANCH }} --build_type=${{ env.BUILD_TYPE }} + - name: Update YDB for muted tests + uses: ./.github/workflows/reusable/update_ydb_for_muted_tests.yml + with: + branch: ${{ env.BASE_BRANCH }} + build_type: ${{ env.BUILD_TYPE }} + secrets: + CI_YDB_SERVICE_ACCOUNT_KEY_FILE_CREDENTIALS: ${{ secrets.CI_YDB_SERVICE_ACCOUNT_KEY_FILE_CREDENTIALS }} - name: Generate new muted_ya.txt run: | From a08cb5555f5ae0f0532caacb8cbccc2c3d35cdb4 Mon Sep 17 00:00:00 2001 From: naspirato Date: Mon, 10 Nov 2025 12:37:57 +0100 Subject: [PATCH 2/6] wip --- .github/workflows/create_issues_for_muted_tests.yml | 1 + .../reusable/update_ydb_for_muted_tests.yml | 13 +++++++++++++ .github/workflows/update_muted_ya.yml | 1 + 3 files changed, 15 insertions(+) diff --git a/.github/workflows/create_issues_for_muted_tests.yml b/.github/workflows/create_issues_for_muted_tests.yml index 57e503a8b133..b111de71602f 100644 --- a/.github/workflows/create_issues_for_muted_tests.yml +++ b/.github/workflows/create_issues_for_muted_tests.yml @@ -28,6 +28,7 @@ jobs: build_type: ${{ env.BUILD_TYPE }} secrets: CI_YDB_SERVICE_ACCOUNT_KEY_FILE_CREDENTIALS: ${{ secrets.CI_YDB_SERVICE_ACCOUNT_KEY_FILE_CREDENTIALS }} + GITHUB_TOKEN: ${{ secrets.YDBOT_TOKEN }} process-muted-tests: needs: update-ydb diff --git a/.github/workflows/reusable/update_ydb_for_muted_tests.yml b/.github/workflows/reusable/update_ydb_for_muted_tests.yml index e77004b64309..72ee1e08ccf4 100644 --- a/.github/workflows/reusable/update_ydb_for_muted_tests.yml +++ b/.github/workflows/reusable/update_ydb_for_muted_tests.yml @@ -13,6 +13,8 @@ on: secrets: CI_YDB_SERVICE_ACCOUNT_KEY_FILE_CREDENTIALS: required: true + GITHUB_TOKEN: + required: true jobs: update-ydb: @@ -43,3 +45,14 @@ jobs: - name: Update test monitor run: python3 .github/scripts/analytics/tests_monitor.py --branch=${{ inputs.branch }} --build_type=${{ inputs.build_type }} + - name: Export GitHub issues + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: python3 .github/scripts/analytics/export_issues_to_ydb.py + + - name: Update GitHub issue mapping table + run: python3 .github/scripts/analytics/github_issue_mapping.py + + - name: Update test_muted_monitor_mart + run: python3 .github/scripts/analytics/data_mart_executor.py --query_path .github/scripts/analytics/data_mart_queries/test_muted_monitor_mart_with_issue.sql --table_path test_results/analytics/test_muted_monitor_mart --store_type column --partition_keys date_window branch build_type owner_team suite_folder --primary_keys date_window owner_team branch build_type suite_folder full_name --ttl_min 43200 --ttl_key date_window + diff --git a/.github/workflows/update_muted_ya.yml b/.github/workflows/update_muted_ya.yml index 461876f84ece..6e38e1240846 100644 --- a/.github/workflows/update_muted_ya.yml +++ b/.github/workflows/update_muted_ya.yml @@ -99,6 +99,7 @@ jobs: build_type: ${{ env.BUILD_TYPE }} secrets: CI_YDB_SERVICE_ACCOUNT_KEY_FILE_CREDENTIALS: ${{ secrets.CI_YDB_SERVICE_ACCOUNT_KEY_FILE_CREDENTIALS }} + GITHUB_TOKEN: ${{ secrets.YDBOT_TOKEN }} - name: Generate new muted_ya.txt run: | From ec334a9c1df7c85ad0e2775fef40c8e671a82cc6 Mon Sep 17 00:00:00 2001 From: naspirato Date: Mon, 10 Nov 2025 13:08:28 +0100 Subject: [PATCH 3/6] wip --- .../tests/process_muted_tests_after_merge.py | 191 ++++-------------- .../create_issues_for_muted_tests.yml | 47 ++++- 2 files changed, 79 insertions(+), 159 deletions(-) diff --git a/.github/scripts/tests/process_muted_tests_after_merge.py b/.github/scripts/tests/process_muted_tests_after_merge.py index f3ca4dcb7b3f..4a514162fe7f 100755 --- a/.github/scripts/tests/process_muted_tests_after_merge.py +++ b/.github/scripts/tests/process_muted_tests_after_merge.py @@ -1,42 +1,15 @@ #!/usr/bin/env python3 """ -Process muted tests after PR merge: -- Get PR data from GitHub API +Helper script for processing muted tests after PR merge: - Get muted_ya.txt from merge commit -- Create issues (if main branch) -- Send Telegram notifications (if main branch) - Comment PR """ import os import sys import argparse import subprocess -from pathlib import Path from github import Github -# Add scripts directory to path -sys.path.append(os.path.dirname(os.path.abspath(__file__))) -sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'telegram')) - - -def get_pr_data(github_token, repository, event_name, pr_number=None): - """Get PR data from GitHub API""" - g = Github(github_token) - repo = g.get_repo(repository) - - if not pr_number: - raise ValueError("PR number is required") - - pr = repo.get_pull(int(pr_number)) - - return { - 'number': pr.number, - 'base_branch': pr.base.ref, - 'merge_commit_sha': pr.merge_commit_sha, - 'merged': pr.merged, - 'labels': [label.name for label in pr.labels] - } - def get_muted_ya_from_commit(merge_commit_sha, base_branch, output_path='muted_ya.txt'): """Get muted_ya.txt from merge commit or base branch""" @@ -84,67 +57,6 @@ def get_muted_ya_from_commit(merge_commit_sha, base_branch, output_path='muted_y raise -def create_issues_for_muted_tests(muted_ya_path, branch): - """Create issues for muted tests""" - print(f"Creating issues for muted tests from {muted_ya_path}") - script_path = os.path.join( - os.path.dirname(__file__), - 'create_new_muted_ya.py' - ) - - result = subprocess.run( - [ - sys.executable, script_path, 'create_issues', - '--file_path', os.path.abspath(muted_ya_path), - '--branch', branch - ], - capture_output=True, - text=True - ) - - if result.returncode != 0: - print(f"Error creating issues: {result.stderr}") - return None - - issues_file = os.path.join(os.getcwd(), 'created_issues.txt') - if os.path.exists(issues_file): - print(f"✓ Issues created, results in {issues_file}") - return issues_file - return None - - -def send_telegram_notifications(issues_file, telegram_bot_token, team_channels): - """Send Telegram notifications""" - if not issues_file or not os.path.exists(issues_file): - print("No issues file, skipping Telegram notifications") - return - - print("Sending Telegram notifications...") - script_path = os.path.join( - os.path.dirname(__file__), - '..', 'telegram', 'parse_and_send_team_issues.py' - ) - - result = subprocess.run( - [ - sys.executable, script_path, - '--on-mute-change-update', - '--file', issues_file, - '--bot-token', telegram_bot_token, - '--team-channels', team_channels, - '--include-plots', - '--delay', '2' - ], - capture_output=True, - text=True - ) - - if result.returncode != 0: - print(f"Error sending Telegram notifications: {result.stderr}") - else: - print("✓ Telegram notifications sent") - - def comment_pr(github_token, repository, pr_number, base_branch, issues_file, run_id, run_number): """Comment on PR""" g = Github(github_token) @@ -165,79 +77,52 @@ def comment_pr(github_token, repository, pr_number, base_branch, issues_file, ru def main(): - parser = argparse.ArgumentParser(description="Process muted tests after PR merge") - parser.add_argument('--event_name', required=True, help='GitHub event name') - parser.add_argument('--pr_number', help='PR number') - parser.add_argument('--merge_commit_sha', help='Merge commit SHA') - parser.add_argument('--base_branch', help='Base branch') - parser.add_argument('--build_type', default='relwithdebinfo', help='Build type') + parser = argparse.ArgumentParser(description="Helper script for processing muted tests after PR merge") + subparsers = parser.add_subparsers(dest='command', help='Command to execute') - args = parser.parse_args() + # get-muted-file command + get_file_parser = subparsers.add_parser('get-muted-file', help='Get muted_ya.txt from merge commit') + get_file_parser.add_argument('--merge_commit_sha', help='Merge commit SHA') + get_file_parser.add_argument('--base_branch', required=True, help='Base branch') + get_file_parser.add_argument('--output', default='muted_ya.txt', help='Output file path') - # Get GitHub token and repository from environment - github_token = os.environ.get('GITHUB_TOKEN') - if not github_token: - raise ValueError("GITHUB_TOKEN environment variable is required") + # comment-pr command + comment_parser = subparsers.add_parser('comment-pr', help='Comment on PR') + comment_parser.add_argument('--pr_number', required=True, help='PR number') + comment_parser.add_argument('--base_branch', required=True, help='Base branch') + comment_parser.add_argument('--issues_file', help='Path to issues file (optional)') - repository = os.environ.get('GITHUB_REPOSITORY') - if not repository: - raise ValueError("GITHUB_REPOSITORY environment variable is required") + args = parser.parse_args() - run_id = os.environ.get('GITHUB_RUN_ID', '') - run_number = os.environ.get('GITHUB_RUN_NUMBER', '') + if args.command == 'get-muted-file': + get_muted_ya_from_commit(args.merge_commit_sha, args.base_branch, args.output) + print(f"✓ File saved to {args.output}") - # Get PR data if pr_number is provided - pr_data = None - if args.pr_number: - print("Getting PR data from GitHub...") - pr_data = get_pr_data( + elif args.command == 'comment-pr': + github_token = os.environ.get('GITHUB_TOKEN') + if not github_token: + raise ValueError("GITHUB_TOKEN environment variable is required") + + repository = os.environ.get('GITHUB_REPOSITORY') + if not repository: + raise ValueError("GITHUB_REPOSITORY environment variable is required") + + run_id = os.environ.get('GITHUB_RUN_ID', '') + run_number = os.environ.get('GITHUB_RUN_NUMBER', '') + + comment_pr( github_token, repository, - args.event_name, - args.pr_number + args.pr_number, + args.base_branch, + args.issues_file, + run_id, + run_number ) - - # Use provided values or from PR data - base_branch = args.base_branch or (pr_data['base_branch'] if pr_data else None) - merge_commit_sha = args.merge_commit_sha or (pr_data['merge_commit_sha'] if pr_data else None) - pr_number = args.pr_number or (pr_data['number'] if pr_data else None) - - if not base_branch: - raise ValueError("Base branch is required (provide --base_branch or --pr_number)") - if not pr_number: - raise ValueError("PR number is required (provide --pr_number)") - - is_main = base_branch == 'main' - - print(f"PR #{pr_number}: base_branch={base_branch}, is_main={is_main}") - - # Get muted_ya.txt from merge commit - muted_ya_path = get_muted_ya_from_commit(merge_commit_sha, base_branch) - - # Create issues and send Telegram (only for main) - issues_file = None - if is_main: - issues_file = create_issues_for_muted_tests(muted_ya_path, base_branch) - - telegram_bot_token = os.environ.get('TELEGRAM_BOT_TOKEN') - team_channels = os.environ.get('TEAM_CHANNELS') - if telegram_bot_token and team_channels: - send_telegram_notifications(issues_file, telegram_bot_token, team_channels) - - # Comment PR (for all branches) - comment_pr( - github_token, - repository, - pr_number, - base_branch, - issues_file, - run_id, - run_number - ) - - print("✓ Process completed successfully") + else: + parser.print_help() + sys.exit(1) if __name__ == "__main__": main() - diff --git a/.github/workflows/create_issues_for_muted_tests.yml b/.github/workflows/create_issues_for_muted_tests.yml index b111de71602f..1f7dd7f76c19 100644 --- a/.github/workflows/create_issues_for_muted_tests.yml +++ b/.github/workflows/create_issues_for_muted_tests.yml @@ -55,18 +55,53 @@ jobs: with: ci_ydb_service_account_key_file_credentials: ${{ secrets.CI_YDB_SERVICE_ACCOUNT_KEY_FILE_CREDENTIALS }} - - name: Process muted tests after merge + - name: Get muted_ya.txt from merge commit + id: get_file + run: | + python3 .github/scripts/tests/process_muted_tests_after_merge.py get-muted-file \ + --merge_commit_sha="${{ github.event.pull_request.merge_commit_sha }}" \ + --base_branch="${{ github.event.pull_request.base.ref }}" \ + --output="muted_ya.txt" + echo "muted_ya_file=muted_ya.txt" >> $GITHUB_OUTPUT + echo "base_branch=${{ github.event.pull_request.base.ref }}" >> $GITHUB_OUTPUT + echo "is_main=$([ \"${{ github.event.pull_request.base.ref }}\" == \"main\" ] && echo \"true\" || echo \"false\")" >> $GITHUB_OUTPUT + + - name: Create issues for muted tests + if: steps.get_file.outputs.is_main == 'true' + id: create_issues env: GITHUB_TOKEN: ${{ secrets.YDBOT_TOKEN }} + run: | + python3 .github/scripts/tests/create_new_muted_ya.py create_issues \ + --file_path=muted_ya.txt \ + --branch=${{ steps.get_file.outputs.base_branch }} + # Скрипт создает created_issues.txt и сохраняет путь в GITHUB_OUTPUT + if [ -f created_issues.txt ]; then + echo "issues_file=created_issues.txt" >> $GITHUB_OUTPUT + fi + + - name: Send Telegram notifications + if: steps.get_file.outputs.is_main == 'true' && steps.create_issues.outputs.issues_file != '' + env: TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_YDBOT_TOKEN }} TEAM_CHANNELS: ${{ vars.TG_TEAM_CHANNELS }} + run: | + python3 .github/scripts/telegram/parse_and_send_team_issues.py \ + --on-mute-change-update \ + --file "created_issues.txt" \ + --bot-token "$TELEGRAM_BOT_TOKEN" \ + --team-channels "$TEAM_CHANNELS" \ + --include-plots \ + --delay 2 + + - name: Comment PR + env: + GITHUB_TOKEN: ${{ secrets.YDBOT_TOKEN }} GITHUB_REPOSITORY: ${{ github.repository }} GITHUB_RUN_ID: ${{ github.run_id }} GITHUB_RUN_NUMBER: ${{ github.run_number }} run: | - python3 .github/scripts/tests/process_muted_tests_after_merge.py \ - --event_name="${{ github.event_name }}" \ + python3 .github/scripts/tests/process_muted_tests_after_merge.py comment-pr \ --pr_number="${{ github.event.pull_request.number || github.event.inputs.pr_number }}" \ - --merge_commit_sha="${{ github.event.pull_request.merge_commit_sha }}" \ - --base_branch="${{ github.event.pull_request.base.ref }}" \ - --build_type="${{ env.BUILD_TYPE }}" + --base_branch="${{ steps.get_file.outputs.base_branch }}" \ + --issues_file="${{ steps.create_issues.outputs.issues_file || '' }}" From 04541a055231b67ffa92cc0d096ec4a9c5314488 Mon Sep 17 00:00:00 2001 From: naspirato Date: Mon, 10 Nov 2025 14:16:39 +0100 Subject: [PATCH 4/6] wip --- .../create_issues_for_muted_tests.yml | 68 ++++++++++++++++--- .github/workflows/update_muted_ya.yml | 25 ++++--- 2 files changed, 73 insertions(+), 20 deletions(-) diff --git a/.github/workflows/create_issues_for_muted_tests.yml b/.github/workflows/create_issues_for_muted_tests.yml index 1f7dd7f76c19..4ded254b2559 100644 --- a/.github/workflows/create_issues_for_muted_tests.yml +++ b/.github/workflows/create_issues_for_muted_tests.yml @@ -16,27 +16,46 @@ env: BUILD_TYPE: relwithdebinfo jobs: + get-pr-base-branch: + runs-on: ubuntu-latest + outputs: + base_branch: ${{ steps.get_base_branch.outputs.base_branch }} + steps: + - name: Get PR base branch + if: github.event_name == 'workflow_dispatch' + id: get_base_branch + env: + GH_TOKEN: ${{ secrets.YDBOT_TOKEN }} + run: | + PR_NUMBER="${{ github.event.inputs.pr_number }}" + BASE_BRANCH=$(gh pr view $PR_NUMBER --json baseRefName --jq -r '.baseRefName') + echo "base_branch=${BASE_BRANCH}" >> $GITHUB_OUTPUT + - name: Skip for pull_request + if: github.event_name == 'pull_request' + run: echo "Skipping - using event data" + update-ydb: if: | ((github.event_name == 'pull_request' && github.event.pull_request.merged == true && contains(github.event.pull_request.labels.*.name, 'mute-unmute')) || - github.event_name == 'workflow_dispatch') + (github.event_name == 'workflow_dispatch' && needs.get-pr-base-branch.result == 'success')) + needs: get-pr-base-branch uses: ./.github/workflows/reusable/update_ydb_for_muted_tests.yml with: - branch: ${{ github.event.pull_request.base.ref || 'main' }} + branch: ${{ github.event.pull_request.base.ref || needs.get-pr-base-branch.outputs.base_branch }} build_type: ${{ env.BUILD_TYPE }} secrets: CI_YDB_SERVICE_ACCOUNT_KEY_FILE_CREDENTIALS: ${{ secrets.CI_YDB_SERVICE_ACCOUNT_KEY_FILE_CREDENTIALS }} GITHUB_TOKEN: ${{ secrets.YDBOT_TOKEN }} process-muted-tests: - needs: update-ydb + needs: [update-ydb, get-pr-base-branch] if: | ((github.event_name == 'pull_request' && github.event.pull_request.merged == true && contains(github.event.pull_request.labels.*.name, 'mute-unmute')) || - github.event_name == 'workflow_dispatch') + (github.event_name == 'workflow_dispatch' && needs.get-pr-base-branch.result == 'success')) runs-on: ubuntu-latest steps: - name: Checkout repository @@ -55,16 +74,39 @@ jobs: with: ci_ydb_service_account_key_file_credentials: ${{ secrets.CI_YDB_SERVICE_ACCOUNT_KEY_FILE_CREDENTIALS }} + - name: Get PR details for workflow_dispatch + if: github.event_name == 'workflow_dispatch' + id: get_pr_details + env: + GH_TOKEN: ${{ secrets.YDBOT_TOKEN }} + GITHUB_REPOSITORY: ${{ github.repository }} + run: | + PR_NUMBER="${{ github.event.inputs.pr_number }}" + PR_DATA=$(gh pr view $PR_NUMBER --json baseRefName,mergeCommit --jq '{base_branch: .baseRefName, merge_commit_sha: .mergeCommit.oid}') + BASE_BRANCH=$(echo "$PR_DATA" | jq -r '.base_branch') + MERGE_SHA=$(echo "$PR_DATA" | jq -r '.merge_commit_sha // empty') + echo "base_branch=${BASE_BRANCH}" >> $GITHUB_OUTPUT + echo "merge_commit_sha=${MERGE_SHA}" >> $GITHUB_OUTPUT + echo "pr_number=${PR_NUMBER}" >> $GITHUB_OUTPUT + - name: Get muted_ya.txt from merge commit id: get_file run: | + if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then + MERGE_SHA="${{ steps.get_pr_details.outputs.merge_commit_sha }}" + BASE_BRANCH="${{ steps.get_pr_details.outputs.base_branch }}" + else + MERGE_SHA="${{ github.event.pull_request.merge_commit_sha || '' }}" + BASE_BRANCH="${{ github.event.pull_request.base.ref || 'main' }}" + fi + python3 .github/scripts/tests/process_muted_tests_after_merge.py get-muted-file \ - --merge_commit_sha="${{ github.event.pull_request.merge_commit_sha }}" \ - --base_branch="${{ github.event.pull_request.base.ref }}" \ + --merge_commit_sha="${MERGE_SHA}" \ + --base_branch="${BASE_BRANCH}" \ --output="muted_ya.txt" echo "muted_ya_file=muted_ya.txt" >> $GITHUB_OUTPUT - echo "base_branch=${{ github.event.pull_request.base.ref }}" >> $GITHUB_OUTPUT - echo "is_main=$([ \"${{ github.event.pull_request.base.ref }}\" == \"main\" ] && echo \"true\" || echo \"false\")" >> $GITHUB_OUTPUT + echo "base_branch=${BASE_BRANCH}" >> $GITHUB_OUTPUT + echo "is_main=$([ \"${BASE_BRANCH}\" == \"main\" ] && echo \"true\" || echo \"false\")" >> $GITHUB_OUTPUT - name: Create issues for muted tests if: steps.get_file.outputs.is_main == 'true' @@ -75,7 +117,7 @@ jobs: python3 .github/scripts/tests/create_new_muted_ya.py create_issues \ --file_path=muted_ya.txt \ --branch=${{ steps.get_file.outputs.base_branch }} - # Скрипт создает created_issues.txt и сохраняет путь в GITHUB_OUTPUT + # Script creates created_issues.txt and saves path in GITHUB_OUTPUT if [ -f created_issues.txt ]; then echo "issues_file=created_issues.txt" >> $GITHUB_OUTPUT fi @@ -101,7 +143,13 @@ jobs: GITHUB_RUN_ID: ${{ github.run_id }} GITHUB_RUN_NUMBER: ${{ github.run_number }} run: | + if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then + PR_NUMBER="${{ steps.get_pr_details.outputs.pr_number }}" + else + PR_NUMBER="${{ github.event.pull_request.number }}" + fi + python3 .github/scripts/tests/process_muted_tests_after_merge.py comment-pr \ - --pr_number="${{ github.event.pull_request.number || github.event.inputs.pr_number }}" \ + --pr_number="${PR_NUMBER}" \ --base_branch="${{ steps.get_file.outputs.base_branch }}" \ --issues_file="${{ steps.create_issues.outputs.issues_file || '' }}" diff --git a/.github/workflows/update_muted_ya.yml b/.github/workflows/update_muted_ya.yml index 6e38e1240846..3095ff37bac5 100644 --- a/.github/workflows/update_muted_ya.yml +++ b/.github/workflows/update_muted_ya.yml @@ -53,8 +53,22 @@ jobs: - name: Collect testowners run: python3 .github/scripts/analytics/upload_testowners.py - update-muted-tests: + update-ydb: needs: [setup, collect-testowners] + uses: ./.github/workflows/reusable/update_ydb_for_muted_tests.yml + strategy: + fail-fast: false + matrix: + BASE_BRANCH: ${{ fromJson(needs.setup.outputs.matrix_branches) }} + with: + branch: ${{ matrix.BASE_BRANCH }} + build_type: ${{ env.BUILD_TYPE }} + secrets: + CI_YDB_SERVICE_ACCOUNT_KEY_FILE_CREDENTIALS: ${{ secrets.CI_YDB_SERVICE_ACCOUNT_KEY_FILE_CREDENTIALS }} + GITHUB_TOKEN: ${{ secrets.YDBOT_TOKEN }} + + update-muted-tests: + needs: [setup, update-ydb] runs-on: [ self-hosted, auto-provisioned, build-preset-analytic-node] strategy: fail-fast: false @@ -91,15 +105,6 @@ jobs: git fetch origin ${{ env.BASE_BRANCH }}:refs/remotes/origin/${{ env.BASE_BRANCH }} git show origin/${{ env.BASE_BRANCH }}:.github/config/muted_ya.txt > base_muted_ya.txt echo "✓ Retrieved base muted_ya.txt from ${{ env.BASE_BRANCH }}" - - - name: Update YDB for muted tests - uses: ./.github/workflows/reusable/update_ydb_for_muted_tests.yml - with: - branch: ${{ env.BASE_BRANCH }} - build_type: ${{ env.BUILD_TYPE }} - secrets: - CI_YDB_SERVICE_ACCOUNT_KEY_FILE_CREDENTIALS: ${{ secrets.CI_YDB_SERVICE_ACCOUNT_KEY_FILE_CREDENTIALS }} - GITHUB_TOKEN: ${{ secrets.YDBOT_TOKEN }} - name: Generate new muted_ya.txt run: | From 8c5312f6049ed00eac4d77a813eb0cfa1b052a8c Mon Sep 17 00:00:00 2001 From: naspirato Date: Mon, 10 Nov 2025 14:16:48 +0100 Subject: [PATCH 5/6] debug --- .github/workflows/create_issues_for_muted_tests.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/create_issues_for_muted_tests.yml b/.github/workflows/create_issues_for_muted_tests.yml index 4ded254b2559..0e3ab89d41c6 100644 --- a/.github/workflows/create_issues_for_muted_tests.yml +++ b/.github/workflows/create_issues_for_muted_tests.yml @@ -108,6 +108,14 @@ jobs: echo "base_branch=${BASE_BRANCH}" >> $GITHUB_OUTPUT echo "is_main=$([ \"${BASE_BRANCH}\" == \"main\" ] && echo \"true\" || echo \"false\")" >> $GITHUB_OUTPUT + - name: DEBUG: Stop before create_issues + if: steps.get_file.outputs.is_main == 'true' + run: | + echo "DEBUG: Stopping before create_issues step" + echo "muted_ya.txt content preview:" + head -20 muted_ya.txt || echo "File not found" + exit 1 + - name: Create issues for muted tests if: steps.get_file.outputs.is_main == 'true' id: create_issues From 83d281689bf800386823f2318b69a3bd2998016a Mon Sep 17 00:00:00 2001 From: naspirato Date: Mon, 10 Nov 2025 14:32:24 +0100 Subject: [PATCH 6/6] fix --- .github/workflows/create_issues_for_muted_tests.yml | 4 ++-- .github/workflows/update_muted_ya.yml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/create_issues_for_muted_tests.yml b/.github/workflows/create_issues_for_muted_tests.yml index 0e3ab89d41c6..4243f2fe3d5f 100644 --- a/.github/workflows/create_issues_for_muted_tests.yml +++ b/.github/workflows/create_issues_for_muted_tests.yml @@ -107,7 +107,7 @@ jobs: echo "muted_ya_file=muted_ya.txt" >> $GITHUB_OUTPUT echo "base_branch=${BASE_BRANCH}" >> $GITHUB_OUTPUT echo "is_main=$([ \"${BASE_BRANCH}\" == \"main\" ] && echo \"true\" || echo \"false\")" >> $GITHUB_OUTPUT - + - name: DEBUG: Stop before create_issues if: steps.get_file.outputs.is_main == 'true' run: | @@ -115,7 +115,7 @@ jobs: echo "muted_ya.txt content preview:" head -20 muted_ya.txt || echo "File not found" exit 1 - + - name: Create issues for muted tests if: steps.get_file.outputs.is_main == 'true' id: create_issues diff --git a/.github/workflows/update_muted_ya.yml b/.github/workflows/update_muted_ya.yml index 3095ff37bac5..31b711cd0427 100644 --- a/.github/workflows/update_muted_ya.yml +++ b/.github/workflows/update_muted_ya.yml @@ -56,6 +56,9 @@ jobs: update-ydb: needs: [setup, collect-testowners] uses: ./.github/workflows/reusable/update_ydb_for_muted_tests.yml + secrets: + CI_YDB_SERVICE_ACCOUNT_KEY_FILE_CREDENTIALS: ${{ secrets.CI_YDB_SERVICE_ACCOUNT_KEY_FILE_CREDENTIALS }} + GITHUB_TOKEN: ${{ secrets.YDBOT_TOKEN }} strategy: fail-fast: false matrix: @@ -63,9 +66,6 @@ jobs: with: branch: ${{ matrix.BASE_BRANCH }} build_type: ${{ env.BUILD_TYPE }} - secrets: - CI_YDB_SERVICE_ACCOUNT_KEY_FILE_CREDENTIALS: ${{ secrets.CI_YDB_SERVICE_ACCOUNT_KEY_FILE_CREDENTIALS }} - GITHUB_TOKEN: ${{ secrets.YDBOT_TOKEN }} update-muted-tests: needs: [setup, update-ydb]