Skip to content
Merged
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
18 changes: 15 additions & 3 deletions github_ops_manager/configuration/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
from github_ops_manager.processing.yaml_processor import YAMLProcessor
from github_ops_manager.schemas.default_issue import IssueModel, IssuesYAMLModel, PullRequestModel
from github_ops_manager.synchronize.driver import run_process_issues_workflow
from github_ops_manager.utils.constants import DEFAULT_MAX_ISSUE_BODY_LENGTH
from github_ops_manager.utils.tac import find_issue_with_title
from github_ops_manager.utils.templates import construct_jinja2_template_from_file, render_template_with_model
from github_ops_manager.utils.truncation import truncate_test_case_outputs
from github_ops_manager.utils.yaml import dump_yaml_to_file, load_test_case_definitions_from_directory, load_yaml_file

load_dotenv()
Expand Down Expand Up @@ -77,6 +79,10 @@ def tac_sync_issues_cli(
# can be constructed.
template = construct_jinja2_template_from_file(Path(__file__).parent.parent / "templates" / "tac_issues_body.j2")

# Get max body length from environment variable or use default
max_body_length = int(os.getenv("GITHUB_MAX_ISSUE_BODY_LENGTH", str(DEFAULT_MAX_ISSUE_BODY_LENGTH)))
typer.echo(f"Using max issue body length: {max_body_length}")

# Iterate through the test case definitions and ensure matching issues
# exist in the YAML file.
for test_case_definition in testing_as_code_test_case_definitions_model.test_cases:
Expand All @@ -100,10 +106,13 @@ def tac_sync_issues_cli(
# script will have a control label called "script-already-created".
# Additionally, a field named "generated_script_path" will be
# populated with the path to the created test automation script.
#
# Truncate outputs if they would exceed the max body length
truncated_test_case = truncate_test_case_outputs(test_case_definition, max_body_length)
new_issue = IssueModel(
title=test_case_definition.title,
body=render_template_with_model(
model=test_case_definition,
model=truncated_test_case,
template=template,
),
labels=test_case_definition.labels,
Expand All @@ -116,15 +125,18 @@ def tac_sync_issues_cli(
f"path of '{test_case_definition.generated_script_path}' - "
"creating a Pull Request"
)
script_path = test_automation_scripts_directory / test_case_definition.generated_script_path
new_issue.pull_request = PullRequestModel(
title=f"GenAI, Review: {test_case_definition.title}",
files=[test_case_definition.generated_script_path],
files=[str(script_path)],
)
desired_issues_yaml_model.issues.append(new_issue)
else:
# Update the existing issue based upon the test case definition.
# Truncate outputs if they would exceed the max body length
truncated_test_case = truncate_test_case_outputs(test_case_definition, max_body_length)
existing_issue.body = render_template_with_model(
model=test_case_definition,
model=truncated_test_case,
template=template,
)
existing_issue.labels = test_case_definition.labels
Expand Down
10 changes: 10 additions & 0 deletions github_ops_manager/synchronize/issues.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Contains synchronization logic for GitHub issues."""

import os
import time

import jinja2
Expand All @@ -11,7 +12,9 @@
from github_ops_manager.synchronize.models import SyncDecision
from github_ops_manager.synchronize.results import AllIssueSynchronizationResults, IssueSynchronizationResult
from github_ops_manager.synchronize.utils import compare_github_field, compare_label_sets
from github_ops_manager.utils.constants import DEFAULT_MAX_ISSUE_BODY_LENGTH
from github_ops_manager.utils.templates import construct_jinja2_template_from_file
from github_ops_manager.utils.truncation import truncate_data_dict_outputs

logger: structlog.stdlib.BoundLogger = structlog.get_logger(__name__)

Expand Down Expand Up @@ -140,8 +143,15 @@ async def render_issue_bodies(issues_yaml_model: IssuesYAMLModel) -> IssuesYAMLM
logger.error("Encountered a syntax error with the provided issue template", issue_template=issues_yaml_model.issue_template, error=str(exc))
raise

# Get max body length from environment variable or use default
max_body_length = int(os.getenv("GITHUB_MAX_ISSUE_BODY_LENGTH", str(DEFAULT_MAX_ISSUE_BODY_LENGTH)))

for issue in issues_yaml_model.issues:
if issue.data is not None:
# Truncate command outputs if present to fit within GitHub's body limit
if "commands" in issue.data:
issue.data = truncate_data_dict_outputs(issue.data, max_body_length)

# Render with all issue fields available
render_context = issue.model_dump()
try:
Expand Down
21 changes: 21 additions & 0 deletions github_ops_manager/utils/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,24 @@

DEFAULT_RELEASE_NOTES_HEADER = "# Release Notes\n\nThis document tracks the new features, enhancements, and bug fixes for each release."
"""Default header expected in release notes file."""

# Issue Body Truncation Constants
# -------------------------------

DEFAULT_MAX_ISSUE_BODY_LENGTH = 60000
"""Default maximum length for issue bodies (leaves margin for GitHub's 65,536 limit)."""

GITHUB_MAX_ISSUE_BODY_LENGTH = 65536
"""GitHub's actual maximum issue body length."""

TRUNCATION_SUFFIX = "\n... [truncated - {remaining} characters removed]"
"""Suffix template appended to truncated content. Use .format(remaining=N) to fill in count."""

TEMPLATE_OVERHEAD_PER_COMMAND = 500
"""Estimated character overhead per command in the TAC issue template (markdown, code fences)."""

BASE_TEMPLATE_OVERHEAD = 2000
"""Estimated base overhead for non-command template content (headers, pass criteria, etc)."""

MIN_OUTPUT_LENGTH = 500
"""Minimum characters to preserve in truncated output fields for readability."""
Loading