Skip to content

196 if catch log label on issue or pull request parse errortraceback from github actions log and print to pull request#197

Open
abuzarmahmood wants to merge 4 commits intomainfrom
196-if-catch_log-label-on-issue-or-pull-request-parse-errortraceback-from-github-actions-log-and-print-to-pull-request
Open

196 if catch log label on issue or pull request parse errortraceback from github actions log and print to pull request#197
abuzarmahmood wants to merge 4 commits intomainfrom
196-if-catch_log-label-on-issue-or-pull-request-parse-errortraceback-from-github-actions-log-and-print-to-pull-request

Conversation

@abuzarmahmood
Copy link
Owner

  • feat: implement catch_log label detection and log parsing feature
  • fix: import git_utils to resolve undefined name error in response_agent.py

abuzarmahmood and others added 2 commits July 23, 2025 00:10
Co-authored-by: aider (gpt-4o) <aider@aider.chat>
…nt.py

Co-authored-by: aider (gpt-4o) <aider@aider.chat>
@abuzarmahmood
Copy link
Owner Author

Generated edit command:

Summary of User's Issues and Requests

The user has requested the implementation of a feature that detects the 'catch_log' label on GitHub issues or pull requests, fetches logs from GitHub Actions, parses them for errors or tracebacks, and posts the parsed information as comments on the relevant pull requests. The last comment suggests implementing a parse_github_action_logs function to be used by the fetch_and_parse_github_actions_log function.

Overview of Plan to Address the Issues

  1. Detect the 'catch_log' Label: Implement a function in src/triggers.py to check for the 'catch_log' label.
  2. Fetch and Parse Logs: Implement a function in src/git_utils.py to fetch logs from GitHub Actions and parse them using a separate parse_github_action_logs function.
  3. Post Comments on Pull Requests: Modify src/response_agent.py to post the parsed logs as comments on pull requests when the 'catch_log' label is present.

Specific Details of Changes to be Made

  1. Detect the 'catch_log' Label

    • File: src/triggers.py
    • Line: Add a new function after line 20
    • Description: Add a function to check if an issue or pull request has the 'catch_log' label.
    • Code Snippet:
      def has_catch_log_label(issue: Issue) -> bool:
          """
          Check if the issue has the 'catch_log' label
      
          Args:
              issue: The GitHub issue to check
      
          Returns:
              True if the issue has the 'catch_log' label, False otherwise
          """
          return any(label.name == "catch_log" for label in issue.labels)
  2. Fetch and Parse Logs

    • File: src/git_utils.py

    • Line: Add the parse_github_action_logs function after line 115

    • Description: Implement a function to parse logs for errors or tracebacks.

    • Code Snippet:

      def parse_github_action_logs(logs: str) -> str:
          """
          Parse GitHub Actions logs for errors or tracebacks.
      
          Args:
              logs: The logs from a GitHub Actions workflow run.
      
          Returns:
              A string containing the parsed error or traceback messages.
          """
          error_lines = []
          for line in logs.splitlines():
              if "error" in line.lower() or "traceback" in line.lower():
                  error_lines.append(line)
      
          if not error_lines:
              return "No errors or tracebacks found in logs."
      
          return "\n".join(error_lines)
    • File: src/git_utils.py

    • Line: Update the fetch_and_parse_github_actions_log function to use parse_github_action_logs.

    • Code Snippet:

      import requests
      import os
      
      def fetch_and_parse_github_actions_log(issue: Issue) -> str:
          """
          Fetch and parse the GitHub Actions log for errors or tracebacks.
      
          Args:
              issue: The GitHub issue to fetch logs for.
      
          Returns:
              A string containing the parsed error or traceback.
          """
          repo = issue.repository
          workflow_runs = repo.get_workflow_runs(event='pull_request', branch=issue.pull_request.head.ref)
          
          if workflow_runs.total_count == 0:
              return "No workflow runs found for this pull request."
      
          latest_run = workflow_runs[0]
          logs_url = latest_run.logs_url
      
          headers = {'Authorization': f'token {os.getenv("GITHUB_TOKEN")}'}
          response = requests.get(logs_url, headers=headers)
      
          if response.status_code != 200:
              return f"Failed to fetch logs: {response.status_code} {response.reason}"
      
          logs = response.text
          return parse_github_action_logs(logs)
  3. Post Comments on Pull Requests

    • File: src/response_agent.py
    • Line: Modify the process_issue function around line 1019
    • Description: Integrate the logic to post parsed logs as comments on pull requests when the 'catch_log' label is present.
    • Code Snippet:
      if triggers.has_catch_log_label(issue_or_pr):
          parsed_log = git_utils.fetch_and_parse_github_actions_log(issue_or_pr)
          write_issue_response(issue_or_pr, f"Error log:\n```\n{parsed_log}\n```")
          return True, None

These changes will enable the bot to detect the 'catch_log' label, fetch and parse logs from GitHub Actions, and post the parsed errors or tracebacks as comments on the relevant pull requests.


This response was automatically generated by blech_bot using model gpt-4o

Aider output:

View Aider Output
Aider v0.85.2
Main model: gpt-4o with diff edit format
Weak model: gpt-4o-mini
Git repo: .git with 19 files
Repo-map: using 4096 tokens, auto refresh


src/git_utils.py

src/response_agent.py

src/triggers.py
Let's implement the changes as planned:                                                                                                                                                                                                          

 1 Detect the 'catch_log' Label in src/triggers.py.                                                                                                                                                                                              
 2 Fetch and Parse Logs in src/git_utils.py.                                                                                                                                                                                                     
 3 Post Comments on Pull Requests in src/response_agent.py.                                                                                                                                                                                      

Here are the SEARCH/REPLACE blocks:                                                                                                                                                                                                              

src/triggers.py                                                                                                                                                                                                                                  

                                                                                                                                                                                                                                                 
<<<<<<< SEARCH                                                                                                                                                                                                                                   
def has_generate_edit_command_trigger(issue: Issue) -> bool:                                                                                                                                                                                     
=======                                                                                                                                                                                                                                          
def has_catch_log_label(issue: Issue) -> bool:                                                                                                                                                                                                   
    """                                                                                                                                                                                                                                          
    Check if the issue has the 'catch_log' label                                                                                                                                                                                                 
                                                                                                                                                                                                                                                 
    Args:                                                                                                                                                                                                                                        
        issue: The GitHub issue to check                                                                                                                                                                                                         
                                                                                                                                                                                                                                                 
    Returns:                                                                                                                                                                                                                                     
        True if the issue has the 'catch_log' label, False otherwise                                                                                                                                                                             
    """                                                                                                                                                                                                                                          
    return any(label.name == "catch_log" for label in issue.labels)                                                                                                                                                                              
                                                                                                                                                                                                                                                 
                                                                                                                                                                                                                                                 
def has_generate_edit_command_trigger(issue: Issue) -> bool:                                                                                                                                                                                     
>>>>>>> REPLACE                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                 

src/git_utils.py                                                                                                                                                                                                                                 

                                                                                                                                                                                                                                                 
<<<<<<< SEARCH                                                                                                                                                                                                                                   
def get_issue_comments(issue: Issue) -> List[IssueComment]:                                                                                                                                                                                      
=======                                                                                                                                                                                                                                          
def parse_github_action_logs(logs: str) -> str:                                                                                                                                                                                                  
    """                                                                                                                                                                                                                                          
    Parse GitHub Actions logs for errors or tracebacks.                                                                                                                                                                                          
                                                                                                                                                                                                                                                 
    Args:                                                                                                                                                                                                                                        
        logs: The logs from a GitHub Actions workflow run.                                                                                                                                                                                       
                                                                                                                                                                                                                                                 
    Returns:                                                                                                                                                                                                                                     
        A string containing the parsed error or traceback messages.                                                                                                                                                                              
    """                                                                                                                                                                                                                                          
    error_lines = []                                                                                                                                                                                                                             
    for line in logs.splitlines():                                                                                                                                                                                                               
        if "error" in line.lower() or "traceback" in line.lower():                                                                                                                                                                               
            error_lines.append(line)                                                                                                                                                                                                             
                                                                                                                                                                                                                                                 
    if not error_lines:                                                                                                                                                                                                                          
        return "No errors or tracebacks found in logs."                                                                                                                                                                                          
                                                                                                                                                                                                                                                 
    return "\n".join(error_lines)                                                                                                                                                                                                                
                                                                                                                                                                                                                                                 
                                                                                                                                                                                                                                                 
def get_issue_comments(issue: Issue) -> List[IssueComment]:                                                                                                                                                                                      
>>>>>>> REPLACE                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                 

src/git_utils.py                                                                                                                                                                                                                                 

                                                                                                                                                                                                                                                 
<<<<<<< SEARCH                                                                                                                                                                                                                                   
from github.IssueComment import IssueComment                                                                                                                                                                                                     
=======                                                                                                                                                                                                                                          
import requests                                                                                                                                                                                                                                  
import os                                                                                                                                                                                                                                        
from github.IssueComment import IssueComment                                                                                                                                                                                                     
                                                                                                                                                                                                                                                 
                                                                                                                                                                                                                                                 
def fetch_and_parse_github_actions_log(issue: Issue) -> str:                                                                                                                                                                                     
    """                                                                                                                                                                                                                                          
    Fetch and parse the GitHub Actions log for errors or tracebacks.                                                                                                                                                                             
                                                                                                                                                                                                                                                 
    Args:                                                                                                                                                                                                                                        
        issue: The GitHub issue to fetch logs for.                                                                                                                                                                                               
                                                                                                                                                                                                                                                 
    Returns:                                                                                                                                                                                                                                     
        A string containing the parsed error or traceback.                                                                                                                                                                                       
    """                                                                                                                                                                                                                                          
    repo = issue.repository                                                                                                                                                                                                                      
    workflow_runs = repo.get_workflow_runs(event='pull_request', branch=issue.pull_request.head.ref)                                                                                                                                             
                                                                                                                                                                                                                                                 
    if workflow_runs.total_count == 0:                                                                                                                                                                                                           
        return "No workflow runs found for this pull request."                                                                                                                                                                                   
                                                                                                                                                                                                                                                 
    latest_run = workflow_runs[0]                                                                                                                                                                                                                
    logs_url = latest_run.logs_url                                                                                                                                                                                                               
                                                                                                                                                                                                                                                 
    headers = {'Authorization': f'token {os.getenv("GITHUB_TOKEN")}'}                                                                                                                                                                            
    response = requests.get(logs_url, headers=headers)                                                                                                                                                                                           
                                                                                                                                                                                                                                                 
    if response.status_code != 200:                                                                                                                                                                                                              
        return f"Failed to fetch logs: {response.status_code} {response.reason}"                                                                                                                                                                 
                                                                                                                                                                                                                                                 
    logs = response.text                                                                                                                                                                                                                         
    return parse_github_action_logs(logs)                                                                                                                                                                                                        
                                                                                                                                                                                                                                                 
                                                                                                                                                                                                                                                 
>>>>>>> REPLACE                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                 

src/response_agent.py                                                                                                                                                                                                                            

                                                                                                                                                                                                                                                 
<<<<<<< SEARCH                                                                                                                                                                                                                                   
        has_bot_mention = triggers.has_blech_bot_tag(issue_or_pr) \                                                                                                                                                                              
=======                                                                                                                                                                                                                                          
        if triggers.has_catch_log_label(issue_or_pr):                                                                                                                                                                                            
            parsed_log = git_utils.fetch_and_parse_github_actions_log(issue_or_pr)                                                                                                                                                               
            write_issue_response(issue_or_pr, f"Error log:\n```\n{parsed_log}\n```")                                                                                                                                                             
            return True, None                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                 
        has_bot_mention = triggers.has_blech_bot_tag(issue_or_pr) \                                                                                                                                                                              
>>>>>>> REPLACE                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                 

These changes will enable the bot to detect the 'catch_log' label, fetch and parse logs from GitHub Actions, and post the parsed errors or tracebacks as comments on the relevant pull requests.                                                 

Tokens: 20k sent, 747 received. Cost: $0.06 message, $0.06 session.
Applied edit to src/response_agent.py
Applied edit to src/git_utils.py
Applied edit to src/triggers.py
Commit 019972f feat: implement catch_log label detection and log parsing feature

# Fix any errors below, if possible.

## Running: /home/exouser/Desktop/blech_github_bot/venv/bin/python -m flake8 --select=E9,F821,F823,F831,F406,F407,F701,F702,F704,F706 --show-source --isolated src/response_agent.py

src/response_agent.py:1005:26: F821 undefined name 'git_utils'
            parsed_log = git_utils.fetch_and_parse_github_actions_log(issue_or_pr)
                         ^

## See relevant line below marked with █.

src/response_agent.py:
...⋮...
 986│def process_issue(
 987│    issue_or_pr: Union[Issue, PullRequest],
 988│    repo_name: str,
 989│) -> Tuple[bool, Optional[str]]:
 990│    """
 991│    Process a single issue or PR - check if it needs response and generate one
 992│
 993│    Args:
 994│        issue_or_pr: The GitHub issue or PR to process
 995│
 996│    Returns:
 997│        Tuple of (whether response was posted, optional error message)
...⋮...
 1002│
 1003│    try:
 1004│        if triggers.has_catch_log_label(issue_or_pr):
 1005█            parsed_log = git_utils.fetch_and_parse_github_actions_log(issue_or_pr)
 1006│            write_issue_response(issue_or_pr, f"Error log:\n```\n{parsed_log}\n```")
 1007│            return True, None
 1008│
...⋮...


To fix the error, we need to ensure that git_utils is imported in src/response_agent.py. Let's add the import statement for git_utils.                                                                                                           

Here is the SEARCH/REPLACE block:                                                                                                                                                                                                                

src/response_agent.py                                                                                                                                                                                                                            

                                                                                                                                                                                                                                                 
<<<<<<< SEARCH                                                                                                                                                                                                                                   
from src.git_utils import (                                                                                                                                                                                                                      
=======                                                                                                                                                                                                                                          
import src.git_utils as git_utils                                                                                                                                                                                                                
from src.git_utils import (                                                                                                                                                                                                                      
>>>>>>> REPLACE                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                 

This change will import git_utils as a module, allowing us to use git_utils.fetch_and_parse_github_actions_log without any issues.                                                                                                               

Tokens: 22k sent, 113 received. Cost: $0.06 message, $0.11 session.
Applied edit to src/response_agent.py
Commit 9c5fcfd fix: import git_utils to resolve undefined name error in response_agent.py

@codecov
Copy link

codecov bot commented Jul 23, 2025

Codecov Report

Attention: Patch coverage is 23.33333% with 23 lines in your changes missing coverage. Please review.

Project coverage is 41.24%. Comparing base (ddfcdbb) to head (f7a6160).
Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
src/git_utils.py 19.23% 21 Missing ⚠️
src/triggers.py 50.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #197      +/-   ##
==========================================
- Coverage   42.16%   41.24%   -0.93%     
==========================================
  Files           4        4              
  Lines         581      611      +30     
  Branches       66       71       +5     
==========================================
+ Hits          245      252       +7     
- Misses        334      357      +23     
  Partials        2        2              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

abuzarmahmood and others added 2 commits July 23, 2025 00:18
…logs

Co-authored-by: aider (gpt-4o) <aider@aider.chat>
Co-authored-by: aider (gpt-4o) <aider@aider.chat>
@abuzarmahmood
Copy link
Owner Author

Applied changes based on comment:

View Aider Output
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Aider v0.85.2
Main model: gpt-4o with diff edit format
Weak model: gpt-4o-mini
Git repo: .git with 19 files
Repo-map: using 4096 tokens, auto refresh


src/git_utils.py

src/response_agent.py

src/triggers.py
To implement the requested changes, we will make modifications to the following files:                                                                                                                                                           

 1 src/triggers.py: Add a function to detect the 'catch_log' label.                                                                                                                                                                              
 2 src/git_utils.py: Implement functions to fetch and parse GitHub Actions logs.                                                                                                                                                                 
 3 src/response_agent.py: Modify the process_issue function to post parsed logs as comments when the 'catch_log' label is detected.                                                                                                              

Here are the SEARCH/REPLACE blocks for each file:                                                                                                                                                                                                

1. src/triggers.py                                                                                                                                                                                                                               

Add a function to detect the 'catch_log' label.                                                                                                                                                                                                  

src/triggers.py                                                                                                                                                                                                                                  

                                                                                                                                                                                                                                                 
<<<<<<< SEARCH                                                                                                                                                                                                                                   
def has_generate_edit_command_trigger(issue: Issue) -> bool:                                                                                                                                                                                     
=======                                                                                                                                                                                                                                          
def has_catch_log_label(issue: Issue) -> bool:                                                                                                                                                                                                   
    """                                                                                                                                                                                                                                          
    Check if the issue has the 'catch_log' label                                                                                                                                                                                                 
                                                                                                                                                                                                                                                 
    Args:                                                                                                                                                                                                                                        
        issue: The GitHub issue to check                                                                                                                                                                                                         
                                                                                                                                                                                                                                                 
    Returns:                                                                                                                                                                                                                                     
        True if the issue has the 'catch_log' label, False otherwise                                                                                                                                                                             
    """                                                                                                                                                                                                                                          
    return any(label.name == "catch_log" for label in issue.labels)                                                                                                                                                                              
                                                                                                                                                                                                                                                 
def has_generate_edit_command_trigger(issue: Issue) -> bool:                                                                                                                                                                                     
>>>>>>> REPLACE                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                 

2. src/git_utils.py                                                                                                                                                                                                                              

Implement functions to fetch and parse GitHub Actions logs.                                                                                                                                                                                      

src/git_utils.py                                                                                                                                                                                                                                 

                                                                                                                                                                                                                                                 
<<<<<<< SEARCH                                                                                                                                                                                                                                   
    return response.text                                                                                                                                                                                                                         
=======                                                                                                                                                                                                                                          
    return parse_github_action_logs(response.text)                                                                                                                                                                                               
>>>>>>> REPLACE                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                 

src/git_utils.py                                                                                                                                                                                                                                 

                                                                                                                                                                                                                                                 
<<<<<<< SEARCH                                                                                                                                                                                                                                   
def get_github_client() -> Github:                                                                                                                                                                                                               
=======                                                                                                                                                                                                                                          
def parse_github_action_logs(logs: str) -> str:                                                                                                                                                                                                  
    """                                                                                                                                                                                                                                          
    Parse GitHub Actions logs for errors or tracebacks.                                                                                                                                                                                          
                                                                                                                                                                                                                                                 
    Args:                                                                                                                                                                                                                                        
        logs: The logs from a GitHub Actions workflow run.                                                                                                                                                                                       
                                                                                                                                                                                                                                                 
    Returns:                                                                                                                                                                                                                                     
        A string containing the parsed error or traceback messages.                                                                                                                                                                              
    """                                                                                                                                                                                                                                          
    error_lines = [line for line in logs.splitlines() if "error" in line.lower() or "traceback" in line.lower()]                                                                                                                                 
    return "\n".join(error_lines) if error_lines else "No errors or tracebacks found in logs."                                                                                                                                                   
                                                                                                                                                                                                                                                 
def get_github_client() -> Github:                                                                                                                                                                                                               
>>>>>>> REPLACE                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                 

3. src/response_agent.py                                                                                                                                                                                                                         

Modify the process_issue function to post parsed logs as comments when the 'catch_log' label is detected.                                                                                                                                        

src/response_agent.py                                                                                                                                                                                                                            

                                                                                                                                                                                                                                                 
<<<<<<< SEARCH                                                                                                                                                                                                                                   
    try:                                                                                                                                                                                                                                         
=======                                                                                                                                                                                                                                          
    if triggers.has_catch_log_label(issue_or_pr):                                                                                                                                                                                                
        parsed_log = git_utils.fetch_and_parse_github_actions_log(issue_or_pr)                                                                                                                                                                   
        write_issue_response(issue_or_pr, f"Error log:\n```\n{parsed_log}\n```")                                                                                                                                                                 
        return True, None                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                 
    try:                                                                                                                                                                                                                                         
>>>>>>> REPLACE                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                 

These changes will enable the bot to detect the 'catch_log' label, fetch logs from GitHub Actions, parse them for errors or tracebacks, and post the parsed information as comments on the relevant pull requests.                               

Tokens: 20k sent, 601 received. Cost: $0.06 message, $0.06 session.
The LLM did not conform to the edit format.
https://aider.chat/docs/troubleshooting/edit-errors.html

# 1 SEARCH/REPLACE block failed to match!

## SearchReplaceNoExactMatch: This SEARCH block failed to exactly match lines in src/git_utils.py
<<<<<<< SEARCH
    return response.text
=======
    return parse_github_action_logs(response.text)
>>>>>>> REPLACE

The SEARCH section must exactly match an existing block of lines including all white space, comments, indentation, docstrings, etc

# The other 3 SEARCH/REPLACE blocks were applied successfully.
Don't re-send them.
Just reply with fixed versions of the block above that failed to match.

Commit f763aff feat: enhance blech_github_bot to handle 'catch_log' label and fetch logs
Let's correct the SEARCH/REPLACE block for src/git_utils.py to ensure it matches the existing content exactly.                                                                                                                                   

src/git_utils.py                                                                                                                                                                                                                                 

                                                                                                                                                                                                                                                 
<<<<<<< SEARCH                                                                                                                                                                                                                                   
    logs = response.text                                                                                                                                                                                                                         
=======                                                                                                                                                                                                                                          
    logs = response.text                                                                                                                                                                                                                         
    return parse_github_action_logs(logs)                                                                                                                                                                                                        
>>>>>>> REPLACE                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                 

Tokens: 21k sent, 65 received. Cost: $0.05 message, $0.11 session.
Applied edit to src/git_utils.py
Commit f7a6160 fix: correct search/replace block in src/git_utils.py for matching lines


This response was automatically generated by blech_bot using model gpt-4o

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

If 'catch_log' label on issue or pull request, parse error/traceback from GitHub actions log and print to pull request

1 participant