Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 45 additions & 18 deletions .github/workflows/label_checker.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
import requests
import sys

# Get all existing labels in the repository
labels = []
Expand All @@ -11,22 +12,48 @@
else:
exit(0)

# Get affected component
i = os.environ["ISSUE_BODY"].index("### Affected Component")
j = os.environ["ISSUE_BODY"].index("### Version")
component = os.environ["ISSUE_BODY"][i+23:j].strip()
component_label = "Component/" + component
if component_label in all_existing_labels:
labels.append(component_label)

# Get component version
version = os.environ["ISSUE_BODY"][j+13:j+18].strip()
affected_label = "Affected/" + component + "-" + version
if affected_label in all_existing_labels:
labels.append(affected_label)

# Return verified labels
if len(labels) > 0:
print(",".join(labels))
else:
try:
# Check if ISSUE_BODY environment variable exists
issue_body = os.environ.get("ISSUE_BODY", "")
if not issue_body:
print("Missing/Component")
sys.exit(0)

# Get affected component
if "### Affected Component" not in issue_body or "### Version" not in issue_body:
print("Missing/Component")
sys.exit(0)
Comment on lines +18 to +25
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

The fallback print('Missing/Component') bypasses the existing-label check and will make gh issue edit --add-label $labels fail if that label doesn’t already exist in the repo. Either verify Missing/Component is in all_existing_labels before printing it, or print an empty string and have the workflow skip --add-label when no valid labels were found.

Copilot uses AI. Check for mistakes.

i = issue_body.index("### Affected Component")
j = issue_body.index("### Version")
component = issue_body[i+25:j].strip()
Comment on lines +27 to +29
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

component = issue_body[i+25:j].strip() relies on a hard-coded offset that can truncate the first character of the component depending on whether the issue body uses \n\n vs \r\n\r\n after the header. Safer approach is to slice from i + len('### Affected Component') and then trim leading whitespace/newlines (or parse the section by splitting on headers / using a regex).

Suggested change
i = issue_body.index("### Affected Component")
j = issue_body.index("### Version")
component = issue_body[i+25:j].strip()
affected_header = "### Affected Component"
i = issue_body.index(affected_header)
j = issue_body.index("### Version")
component = issue_body[i + len(affected_header):j].strip()

Copilot uses AI. Check for mistakes.
component_label = "Component/" + component
if component_label in all_existing_labels:
labels.append(component_label)
Comment on lines +27 to +32
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# Find the label_checker.py file and examine its content
find . -name "label_checker.py" -type f

Repository: wso2/api-manager

Length of output: 96


🏁 Script executed:

# List files in .github directory to understand structure
ls -la .github/ | head -20

Repository: wso2/api-manager

Length of output: 359


🏁 Script executed:

# Search for issue template files
find .github -type f \( -name "*.md" -o -name "*.yml" -o -name "*.yaml" \) | grep -i template

Repository: wso2/api-manager

Length of output: 328


🏁 Script executed:

# Read the label_checker.py file to see the implementation
cat -n .github/workflows/label_checker.py

Repository: wso2/api-manager

Length of output: 2416


🏁 Script executed:

# Check one of the issue template files to see the actual format
cat .github/ISSUE_TEMPLATE/bug.yml

Repository: wso2/api-manager

Length of output: 1039


🏁 Script executed:

# Check another issue template to see if format is consistent
cat .github/ISSUE_TEMPLATE/new-feature.yml

Repository: wso2/api-manager

Length of output: 895


🏁 Script executed:

# Search for "Affected Component" in the codebase to see if it's defined anywhere
rg -i "affected component" --type md --type yml --type yaml

Repository: wso2/api-manager

Length of output: 87


🏁 Script executed:

# Check if there are any other references to this in the repository
rg -i "affected component" -type py

Repository: wso2/api-manager

Length of output: 87


🏁 Script executed:

# Let's check all issue templates to see which ones might have these fields
for file in .github/ISSUE_TEMPLATE/*.yml; do echo "=== $file ===" && cat "$file"; done

Repository: wso2/api-manager

Length of output: 5198


🏁 Script executed:

# Let's check the git history to see if these templates were recently changed
git log --oneline .github/ISSUE_TEMPLATE/ | head -20

Repository: wso2/api-manager

Length of output: 149


🏁 Script executed:

# Check if there are any other references to "Affected Component" in the codebase
rg "Affected Component"

Repository: wso2/api-manager

Length of output: 42


🏁 Script executed:

# Let's verify how GitHub renders issue form bodies by checking any documentation or examples
rg "### Affected" -A 3 -B 3

Repository: wso2/api-manager

Length of output: 42


🏁 Script executed:

# Check when the label_checker.py was last modified and what the commit message says
git log --oneline .github/workflows/label_checker.py | head -10

Repository: wso2/api-manager

Length of output: 149


🏁 Script executed:

# Check the git diff for the recent commit to understand what changed
git show 7eb7524 --stat

Repository: wso2/api-manager

Length of output: 1201


🏁 Script executed:

# See the full diff of the recent commit
git show 7eb7524

Repository: wso2/api-manager

Length of output: 27211


🏁 Script executed:

# Check if there are any workflow files that reference ISSUE_BODY
rg "ISSUE_BODY"

Repository: wso2/api-manager

Length of output: 42


🏁 Script executed:

# Let's verify how GitHub renders the issue body from these YAML form templates
# by checking if there's any example or documentation about the format
python3 << 'EOF'
# Simulate what GitHub would render from the question_form.yml template
# When a user fills out a GitHub issue form, the rendered body looks like:
# FieldLabel
# user_input
# 
# Not as:
# ### FieldLabel
# user_input

template_example = """Description
Example question

Affected Component
APIM

Version
3.2.0"""

print("Example rendered issue body from GitHub form:")
print(template_example)
print("\nSearching for '### Affected Component' in this body:")
try:
    index = template_example.index("### Affected Component")
    print(f"Found at index {index}")
except ValueError:
    print("NOT FOUND - ValueError would be raised")
    print("\nThe code would fail at line 27 with ValueError")
    print("This exception is caught by the broad except block")
    print("Script always outputs: 'Missing/Component'")
EOF

Repository: wso2/api-manager

Length of output: 409


Critical issue: Code expects markdown headers that GitHub issue forms don't produce.

The script searches for "### Affected Component" in the issue body (line 27), but GitHub's YAML form templates don't render field labels as markdown headers. The actual rendered issue body uses plain text format (e.g., Affected Component followed by the user input). This means index() will always raise ValueError, caught by the broad exception handler on line 56, causing the script to always output "Missing/Component" regardless of input.

The script is fundamentally incompatible with the current issue templates and needs to be rewritten to parse the correct plain-text format produced by GitHub forms. Additionally, remove the unused variable e on line 56 and replace the broad except Exception with specific exception handling.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/label_checker.py around lines 27 - 32, The current logic
that slices issue_body using index("### Affected Component") fails because
GitHub form output is plain text; replace that slicing with a regex search
against issue_body (e.g., a multiline regex that finds the plain "Affected
Component" label and captures the user-provided value on the same line or the
following line) to set component and component_label and append to labels only
if it matches all_existing_labels; also remove the unused variable e and change
the broad except Exception handler to catch specific errors (e.g.,
ValueError/IndexError from parsing or re-related exceptions) so parsing failures
fall back to adding "Missing/Component" without hiding other bugs.


# Get component version - extract until next newline or end of string
version_start = j + 13
version_text = issue_body[version_start:].strip()
Comment on lines +35 to +36
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

The version_start = j + 13 offset is still hard-coded to a specific header+newline layout. This can break with different newline conventions or template formatting. Consider deriving the start index from len('### Version') and then skipping any following whitespace/newlines before extracting the value (or reuse the same section-parsing helper as for the component).

Suggested change
version_start = j + 13
version_text = issue_body[version_start:].strip()
header = "### Version"
header_len = len(header)
version_start = j + header_len
# Skip any whitespace/newlines immediately after the header
while version_start < len(issue_body) and issue_body[version_start] in (" ", "\t", "\r", "\n"):
version_start += 1
version_text = issue_body[version_start:]

Copilot uses AI. Check for mistakes.
# Extract version until newline or '###' (next section)
version_end = len(version_text)
for idx, char in enumerate(version_text):
if char in ['\n', '\r'] or version_text[idx:idx+3] == '###':
version_end = idx
break
version = version_text[:version_end].strip()

if version:
affected_label = "Affected/" + component + "-" + version
if affected_label in all_existing_labels:
labels.append(affected_label)

# Return verified labels
if len(labels) > 0:
print(",".join(labels))
else:
print("Missing/Component")

except Exception as e:
# If any error occurs, default to Missing/Component label
print("Missing/Component")
sys.exit(0)
2 changes: 1 addition & 1 deletion .github/workflows/resolution_label_notifier.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
contains(github.event.issue.labels.*.name, 'Resolution/Not a bug') ||
contains(github.event.issue.labels.*.name, 'Resolution/Postponed') ||
contains(github.event.issue.labels.*.name, 'Resolution/Won’t Fix') ||
contains(github.event.issue.labels.*.name, 'Resolution/Done)
contains(github.event.issue.labels.*.name, 'Resolution/Done')
)}}
steps:
- run: gh issue comment $ISSUE --body "This issue is **NOT** closed with a proper **Resolution/** label. Make sure to add proper reason label before closing. Please add or leave a comment with the proper reason label now.<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- **Resolution/Answered** - Issue is answered.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- **Resolution/Cannot Reproduce** - Issue cannot be reproduced.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- **Resolution/Done** - Issue is done.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- **Resolution/Duplicate** - Issue is already reported before.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- **Resolution/Fixed** - Issue is fixed.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- **Resolution/Invalid** - Issue is invalid.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- **Resolution/Not a bug** - Issue is not a bug.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- **Resolution/Postponed** - Issue is postponed.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- **Resolution/Won’t Fix** - Issue won't be fixed."
Expand Down
Loading