Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
02a3298
Add standalone errata-workflow agent with MCP tools
martinky82 Jun 10, 2026
b1c12eb
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 10, 2026
33c2cc9
Update ymir/tools/privileged/errata.py
martinky82 Jun 11, 2026
21138a7
Update ymir/tools/privileged/errata.py
martinky82 Jun 11, 2026
929a90d
Update ymir/tools/privileged/errata.py
martinky82 Jun 11, 2026
439ef60
Update ymir/tools/privileged/errata.py
martinky82 Jun 11, 2026
035f2e3
Update ymir/tools/privileged/jira.py
martinky82 Jun 11, 2026
6ec98fe
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 11, 2026
a36ae88
Update ymir/tools/privileged/errata.py
martinky82 Jun 11, 2026
a396df0
Update ymir/tools/privileged/errata.py
martinky82 Jun 11, 2026
912e035
Add ERRATA_ALLOW_STATUS_CHANGES guard to errata workflow agent
martinky82 Jun 11, 2026
14ec933
Fix syntax errors from interleaved old/new code in errata conversion
martinky82 Jun 15, 2026
ec54adc
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 15, 2026
7a92cd3
Fix interleaved old/new user lookup code in jira.py
martinky82 Jun 15, 2026
0afea52
Add missing dependencies to ymir-tools package
martinky82 Jun 15, 2026
ff89f64
Fix _check_zstream_clones_shipped to use output.result directly
martinky82 Jun 15, 2026
da5004b
Address PR #594 review comments
martinky82 Jun 24, 2026
2bd298a
Fix CI failures: skill frontmatter and missing bs4 dependency
martinky82 Jun 24, 2026
1d7d5dc
renamed errata_wrokflow to errata-workflow
martinky82 Jun 24, 2026
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
2 changes: 2 additions & 0 deletions Containerfile.tests
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ RUN pip install --no-cache-dir \
flexmock \
koji \
ogr \
beautifulsoup4 \
lxml \
pytest \
pytest-asyncio \
rpm \
Expand Down
14 changes: 12 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ DRY_RUN ?= false
MOCK_JIRA ?= false
JIRA_DRY_RUN ?= false
JIRA_ALLOW_STATUS_CHANGES ?= false
ERRATA_ALLOW_STATUS_CHANGES ?= false
AUTO_CHAIN ?= true
FORCE_CVE_TRIAGE ?= false
RUN_LLM_JUDGE ?= true
Expand Down Expand Up @@ -201,11 +202,11 @@ build-jira-issue-fetcher:

.PHONY: start
start:
DRY_RUN=$(DRY_RUN) MOCK_JIRA=$(MOCK_JIRA) JIRA_DRY_RUN=$(JIRA_DRY_RUN) JIRA_ALLOW_STATUS_CHANGES=$(JIRA_ALLOW_STATUS_CHANGES) AUTO_CHAIN=$(AUTO_CHAIN) $(COMPOSE_AGENTS) up
DRY_RUN=$(DRY_RUN) MOCK_JIRA=$(MOCK_JIRA) JIRA_DRY_RUN=$(JIRA_DRY_RUN) JIRA_ALLOW_STATUS_CHANGES=$(JIRA_ALLOW_STATUS_CHANGES) ERRATA_ALLOW_STATUS_CHANGES=$(ERRATA_ALLOW_STATUS_CHANGES) AUTO_CHAIN=$(AUTO_CHAIN) $(COMPOSE_AGENTS) up

.PHONY: start-detached
start-detached:
DRY_RUN=$(DRY_RUN) MOCK_JIRA=$(MOCK_JIRA) JIRA_DRY_RUN=$(JIRA_DRY_RUN) JIRA_ALLOW_STATUS_CHANGES=$(JIRA_ALLOW_STATUS_CHANGES) AUTO_CHAIN=$(AUTO_CHAIN) $(COMPOSE_AGENTS) up -d
DRY_RUN=$(DRY_RUN) MOCK_JIRA=$(MOCK_JIRA) JIRA_DRY_RUN=$(JIRA_DRY_RUN) JIRA_ALLOW_STATUS_CHANGES=$(JIRA_ALLOW_STATUS_CHANGES) ERRATA_ALLOW_STATUS_CHANGES=$(ERRATA_ALLOW_STATUS_CHANGES) AUTO_CHAIN=$(AUTO_CHAIN) $(COMPOSE_AGENTS) up -d

.PHONY: stop
stop:
Expand Down Expand Up @@ -299,6 +300,15 @@ run-issue-verification-agent-standalone:
-e IGNORE_NEEDS_ATTENTION=$(IGNORE_NEEDS_ATTENTION) \
issue-verification-agent

.PHONY: run-errata-workflow-agent-standalone
run-errata-workflow-agent-standalone:
$(COMPOSE_AGENTS) run --rm \
-e ERRATUM_ID=$(ERRATUM_ID) \
-e DRY_RUN=$(DRY_RUN) \
-e IGNORE_NEEDS_ATTENTION=$(IGNORE_NEEDS_ATTENTION) \
-e ERRATA_ALLOW_STATUS_CHANGES=$(ERRATA_ALLOW_STATUS_CHANGES) \
errata-workflow-agent

.PHONY: run-preliminary-testing-agent-standalone
run-preliminary-testing-agent-standalone:
$(COMPOSE_AGENTS) run --rm \
Expand Down
116 changes: 116 additions & 0 deletions agents_as_skills/errata-workflow/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
---
name: errata-workflow
description: >
Runs the Errata Workflow for an erratum, advancing it through states
(NEW_FILES -> QE -> REL_PREP), handling stage pushes, CAT test timeouts,
product listing verification, and flagging for human attention.
---

# Errata Workflow Skill

You are the errata workflow agent for Project Ymir. Your task is to manage the lifecycle of an erratum — advancing it through states, handling stage pushes, verifying product listings, and flagging errata that need human attention.

## Input Arguments

- `erratum_id`: {{erratum_id}} — The erratum ID or advisory URL to process
- `dry_run`: {{dry_run}} — When true, skip all modifications
- `ignore_needs_attention`: {{ignore_needs_attention}} — When true, process even if already flagged

## Tools

This skill uses the following MCP tools:

**Errata Tools:**
- `get_erratum` — Fetch erratum details (basic or full with comments)
- `get_erratum_transition_rules` — Scrape HTML for state transition guard rules
- `get_erratum_build_map` — Get build NVR + package file lists for an erratum
- `get_previous_erratum` — Search RHEL version inheritance chain for previous erratum
- `get_erratum_stage_push_details` — Get latest stage push status and timestamp
- `erratum_push_to_stage` — Push erratum to CDN stage (respects DRY_RUN)
- `erratum_change_state` — Change erratum state (respects DRY_RUN)
- `erratum_add_comment` — Add comment to erratum (respects DRY_RUN)
- `erratum_refresh_security_alerts` — Refresh security alerts (respects DRY_RUN)

**JIRA Tools:**
- `get_jira_details` — Fetch full details of a JIRA issue
- `search_jira_issues` — Search JIRA with JQL
- `edit_jira_labels` — Add or remove labels on a JIRA issue
- `create_jira_issue` — Create a new JIRA issue (for RHELMISC attention tracking)

## Constants

- `WAIT_DELAY`: 20 minutes (1200 seconds) — delay between reschedule checks
- `POST_PUSH_TESTING_TIMEOUT`: 3 hours — timeout for CAT tests after stage push
- `ERRATA_YMIR_BOT_EMAIL`: jotnar-bot@IPA.REDHAT.COM — Ymir's Errata Tool identity
- `JIRA_YMIR_BOT_EMAIL`: jotnar+bot@redhat.com — Ymir's JIRA identity
- `JIRA_YMIR_TEAM`: rhel-jotnar — Ymir's assigned team name

## Workflow Steps

### Step 1: Fetch Erratum
Fetch erratum details using `get_erratum`. Extract status, jira_issues, assigned_to_email, package_owner_email, and other fields.

### Step 2: Check Needs Attention
Unless `ignore_needs_attention` is true, search for an existing RHELMISC issue with a YmirTag matching this erratum AND the `ymir_needs_attention` label. If found, stop processing — the erratum is already flagged for human attention.

### Step 3: Fetch Related Issues
For each JIRA issue key in the erratum's `jira_issues` list, fetch full issue details using `get_jira_details`. Store all issue data for later checks.

### Step 4: Route by Status
Based on erratum status:
- **NEW_FILES**: Target advancing to QE
- **QE**: Check if all related JIRA issues are in "Release Pending" status. If yes, target advancing to REL_PREP. If not, stop.
- **Other statuses**: No action needed, stop.

### Step 5: Try to Advance
Get transition rules using `get_erratum_transition_rules`. Handle outcomes:

**All rules OK:**
- For REL_PREP target: proceed to product listing verification (Step 6)
- For other targets: change state immediately

**Stagepush blocking:**
- If no push or previous push completed: initiate new stage push, reschedule in 20 minutes
- If push failed: flag for human attention
- If push in progress: reschedule in 20 minutes

**Cat (CAT tests) blocking:**
- Get stage push details to check completion time
- If push not complete: reschedule in 20 minutes
- If push completed but within 3-hour timeout: reschedule in 20 minutes
- If push completed and timeout exceeded: flag for human attention

**Securityalert blocking:**
- Refresh security alerts and reschedule in 20 minutes

**Unknown blocking rules:**
- Flag for human attention with details of blocking rules

### Step 6: Verify Product Listings (REL_PREP only)
Sanity check before advancing to REL_PREP: compare the package file lists of the current builds against previous erratum builds to catch unintentional changes. A mismatch could mean shipping unwanted packages or dropping packages that should be shipped.

For each package in the erratum build map:
1. Check if already verified (magic string `ymir-product-listings-checked(NVR)` or `jotnar-product-listings-checked(NVR)` in erratum comments)
2. Find the previous erratum using `get_previous_erratum` (RHEL version inheritance search)
3. Compare package file lists between current and previous builds
4. Add verification comment to erratum
5. If mismatches found: flag for human attention — the change may be unintentional
6. If all match (or no previous erratum): advance to REL_PREP

## Flagging for Human Attention

When an erratum needs human attention:
1. Search JIRA for an existing RHELMISC issue with a YmirTag matching this erratum
2. If found: add `ymir_needs_attention` label to the existing issue
3. If not found: create a new RHELMISC issue with:
- Summary: `{advisory} ({synopsis}) needs attention`
- Description: YmirTag + erratum URL + reason
- Reporter/Assignee: jotnar+bot@redhat.com
- Labels: `ymir_needs_attention`
- Component: `jotnar-package-automation`

## Output Schema

The workflow returns a `WorkflowResult` with:
- `status`: A message describing what happened and why
- `reschedule_in`: Delay in seconds (-1 = don't reschedule, 0 = immediate, 1200 = 20 minutes)
8 changes: 8 additions & 0 deletions compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ x-beeai-env: &beeai-env
DRY_RUN: ${DRY_RUN:-false}
JIRA_DRY_RUN: ${JIRA_DRY_RUN:-false}
JIRA_ALLOW_STATUS_CHANGES: ${JIRA_ALLOW_STATUS_CHANGES:-false}
ERRATA_ALLOW_STATUS_CHANGES: ${ERRATA_ALLOW_STATUS_CHANGES:-false}
AUTO_CHAIN: ${AUTO_CHAIN:-true}
REQUESTS_CA_BUNDLE: /etc/pki/tls/certs/ca-bundle.crt

Expand Down Expand Up @@ -198,6 +199,13 @@ services:
command: ["python", "-m", "ymir.agents.issue_verification_agent"]
profiles: ["agents"]

errata-workflow-agent:
<<: *beeai-agent-c10s
environment:
<<: *beeai-env
command: ["python", "-m", "ymir.agents.errata_workflow_agent"]
profiles: ["agents"]

triage-agent-e2e-tests:
<<: *beeai-agent-c10s
environment:
Expand Down
Loading
Loading