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
30 changes: 23 additions & 7 deletions ymir/agents/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,7 @@ async def clone_and_prep_sources(
dist_git_branch: str,
available_tools: list[Tool],
jira_issue: str,
ref: str | None = None,
) -> tuple[Path, Path, bool]:
"""
Clone dist-git repo and run centpkg/rhpkg sources + prep.
Expand All @@ -466,6 +467,10 @@ async def clone_and_prep_sources(
Falls back to manual archive extraction if prep fails (e.g. missing
language-specific RPM macros). When using the fallback, downstream
patches are NOT applied — the source is pristine upstream.

When *ref* is provided (a commit SHA), the repo is cloned with all
refs and that specific commit is checked out. This is used when the
target branch does not exist yet but we know the base commit from Koji.
"""
working_dir = Path(os.environ["GIT_REPO_BASEPATH"]) / "applicability" / jira_issue
working_dir.mkdir(parents=True, exist_ok=True)
Expand All @@ -475,13 +480,24 @@ async def clone_and_prep_sources(

namespace = "centos-stream" if is_cs_branch(dist_git_branch) else "rhel"
repository = f"https://gitlab.com/redhat/{namespace}/rpms/{package}"
await run_tool(
"clone_repository",
repository=repository,
branch=dist_git_branch,
clone_path=str(local_clone),
available_tools=available_tools,
)
if ref:
await run_tool(
"clone_repository",
repository=repository,
clone_path=str(local_clone),
available_tools=available_tools,
)
exit_code, _, stderr = await run_subprocess(["git", "checkout", ref], cwd=local_clone)
if exit_code != 0:
raise RuntimeError(f"Failed to checkout ref {ref}: {stderr}")
Comment thread
antbob marked this conversation as resolved.
else:
await run_tool(
"clone_repository",
repository=repository,
branch=dist_git_branch,
clone_path=str(local_clone),
available_tools=available_tools,
)

await run_tool(
"download_sources",
Expand Down
37 changes: 29 additions & 8 deletions ymir/agents/triage_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
from ymir.common.models import (
TriageOutputSchema as OutputSchema,
)
from ymir.common.utils import get_latest_candidate_build
from ymir.common.version_utils import is_older_zstream, normalize_fix_version, parse_rhel_version
from ymir.tools.unprivileged.commands import RunShellCommandTool

Expand Down Expand Up @@ -961,10 +962,12 @@ async def check_cve_applicability(state):

patch_urls = getattr(data, "patch_urls", None) or []

# For z-stream branches, check if the branch actually exists;
# fall back to CentOS Stream for source analysis since we only
# need to read the source, not push to the branch.
# For z-stream branches, check if the branch actually exists.
# For older z-streams whose branch doesn't exist yet, resolve
# the base commit from Koji so we analyze the right source
# (not CentOS Stream, which may already contain the fix).
clone_branch = state.target_branch
base_ref = None
parsed = parse_rhel_version(state.target_branch)
if parsed:
major_version = parsed[0]
Expand All @@ -975,11 +978,28 @@ async def check_cve_applicability(state):
package=package,
)
if state.target_branch not in available_branches:
clone_branch = f"c{major_version}s"
logger.info(
f"Branch {state.target_branch} not found for {package}, "
f"using {clone_branch} for applicability analysis"
)
if await is_older_zstream(state.target_branch):
try:
_, base_ref = await get_latest_candidate_build(package, state.target_branch)
logger.info(
f"Branch {state.target_branch} not found for {package}, "
f"using base ref {base_ref} for applicability analysis"
)
except Exception as e:
logger.warning(
f"Could not resolve base ref for {state.target_branch}: {e} — "
f"skipping applicability check"
)
state.applicability_check_skipped = True
if state.triage_result.resolution == Resolution.REBUILD:
return "consolidate_rebuild_siblings"
return "comment_in_jira"
Comment thread
antbob marked this conversation as resolved.
else:
clone_branch = f"c{major_version}s"
logger.info(
f"Branch {state.target_branch} not found for {package}, "
f"using {clone_branch} for applicability analysis"
)
except Exception as e:
logger.warning(f"Failed to check branches for {package}: {e}")

Expand All @@ -989,6 +1009,7 @@ async def check_cve_applicability(state):
dist_git_branch=clone_branch,
available_tools=gateway_tools,
jira_issue=state.jira_issue,
ref=base_ref,
)
except Exception as e:
logger.warning(f"Could not prep sources for applicability check: {e}")
Expand Down
5 changes: 1 addition & 4 deletions ymir/tools/privileged/distgit.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,9 @@ async def _run(
branch,
)
else:
# ref is a commit SHA from the Koji build source URL (git+https://...#<sha>).
# It may point to a commit on an older Z-stream branch (via tag inheritance)
# which is expected — we're branching from the last known good build.
_, ref = await get_latest_candidate_build(package, branch)
# The push can fail transiently due to bastion network issues; the beeai
# framework will retry the whole tool call in that case.
_, ref = await get_latest_candidate_build(package, branch)
push_infos = await asyncio.to_thread(
repo.remotes.origin.push, f"{ref}:refs/heads/{branch}"
)
Expand Down
Loading