cicaddy-github 0.5.0__tar.gz → 0.6.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/.agents/skills/cicaddy-action/SKILL.md +1 -1
  2. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/.github/workflows/pr-review.yml +2 -1
  3. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/PKG-INFO +2 -2
  4. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/action.yml +1 -1
  5. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/pyproject.toml +2 -2
  6. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/src/cicaddy_github/__init__.py +1 -1
  7. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/src/cicaddy_github/github_integration/agents.py +52 -2
  8. cicaddy_github-0.6.0/tests/unit/test_review_delegation_hooks.py +146 -0
  9. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/.github/dependabot.yml +0 -0
  10. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/.github/workflows/changelog.yml +0 -0
  11. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/.github/workflows/ci.yml +0 -0
  12. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/.github/workflows/release.yml +0 -0
  13. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/.gitignore +0 -0
  14. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/.pre-commit-config.yaml +0 -0
  15. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/AGENTS.md +0 -0
  16. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/CLAUDE.md +0 -0
  17. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/CODE_OF_CONDUCT.md +0 -0
  18. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/CONTRIBUTING.md +0 -0
  19. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/Dockerfile +0 -0
  20. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/LICENSE +0 -0
  21. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/README.md +0 -0
  22. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/docs/delegation.md +0 -0
  23. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/docs/providers.md +0 -0
  24. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/entrypoint.sh +0 -0
  25. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/src/cicaddy_github/config/__init__.py +0 -0
  26. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/src/cicaddy_github/config/settings.py +0 -0
  27. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/src/cicaddy_github/github_integration/__init__.py +0 -0
  28. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/src/cicaddy_github/github_integration/analyzer.py +0 -0
  29. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/src/cicaddy_github/github_integration/detector.py +0 -0
  30. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/src/cicaddy_github/github_integration/go_dep_review_tools.py +0 -0
  31. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/src/cicaddy_github/github_integration/tools.py +0 -0
  32. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/src/cicaddy_github/plugin.py +0 -0
  33. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/src/cicaddy_github/security/__init__.py +0 -0
  34. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/src/cicaddy_github/security/leak_detector.py +0 -0
  35. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/src/cicaddy_github/validation.py +0 -0
  36. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/tasks/changelog_report.yml +0 -0
  37. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/tasks/go_dep_impact_review.yml +0 -0
  38. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/tasks/pr_review.yml +0 -0
  39. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/templates/report_template.html +0 -0
  40. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/tests/__init__.py +0 -0
  41. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/tests/conftest.py +0 -0
  42. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/tests/unit/__init__.py +0 -0
  43. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/tests/unit/test_agents.py +0 -0
  44. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/tests/unit/test_analyzer.py +0 -0
  45. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/tests/unit/test_detector.py +0 -0
  46. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/tests/unit/test_go_dep_review.py +0 -0
  47. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/tests/unit/test_leak_detector.py +0 -0
  48. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/tests/unit/test_plugin.py +0 -0
  49. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/tests/unit/test_settings.py +0 -0
  50. {cicaddy_github-0.5.0 → cicaddy_github-0.6.0}/tests/unit/test_tools.py +0 -0
@@ -225,7 +225,7 @@ the `safe-to-review` label. The label is auto-removed on new pushes to prevent
225
225
  TOCTOU bypasses.
226
226
 
227
227
  ```yaml
228
- - uses: redhat-community-ai-tools/cicaddy-action@v0.5.0
228
+ - uses: redhat-community-ai-tools/cicaddy-action@v0.6.0
229
229
  with:
230
230
  ai_provider: gemini
231
231
  ai_model: gemini-3-flash-preview
@@ -49,7 +49,7 @@ jobs:
49
49
  fi
50
50
 
51
51
  - name: AI Code Review
52
- uses: ./
52
+ uses: redhat-community-ai-tools/cicaddy-action@v0.5.0
53
53
  id: review
54
54
  with:
55
55
  ai_provider: gemini
@@ -57,6 +57,7 @@ jobs:
57
57
  ai_api_key: ${{ secrets.AI_API_KEY }}
58
58
  task_file: tasks/pr_review.yml
59
59
  post_pr_comment: 'true'
60
+ delegation_mode: auto
60
61
  mcp_servers_config: ${{ steps.mcp.outputs.config }}
61
62
  env:
62
63
  ANALYSIS_FOCUS: "general"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cicaddy-github
3
- Version: 0.5.0
3
+ Version: 0.6.0
4
4
  Summary: GitHub Actions plugin for cicaddy AI agent framework
5
5
  Project-URL: Homepage, https://github.com/redhat-community-ai-tools/cicaddy-action
6
6
  Project-URL: Repository, https://github.com/redhat-community-ai-tools/cicaddy-action.git
@@ -9,7 +9,7 @@ Author: Wayne Sun
9
9
  License: Apache-2.0
10
10
  License-File: LICENSE
11
11
  Requires-Python: >=3.11
12
- Requires-Dist: cicaddy>=0.8.0
12
+ Requires-Dist: cicaddy>=0.10.0
13
13
  Requires-Dist: detect-secrets>=1.4.0
14
14
  Requires-Dist: pygithub>=2.1.0
15
15
  Provides-Extra: test
@@ -78,4 +78,4 @@ runs:
78
78
  using: 'docker'
79
79
  image: 'Dockerfile'
80
80
  # After first GHCR publish, switch to pre-built image for faster startup:
81
- # image: 'docker://ghcr.io/redhat-community-ai-tools/cicaddy-action:0.1.0'
81
+ # image: 'docker://ghcr.io/redhat-community-ai-tools/cicaddy-action:0.6.0'
@@ -4,14 +4,14 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "cicaddy-github"
7
- version = "0.5.0"
7
+ version = "0.6.0"
8
8
  description = "GitHub Actions plugin for cicaddy AI agent framework"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
11
11
  license = {text = "Apache-2.0"}
12
12
  authors = [{name = "Wayne Sun"}]
13
13
  dependencies = [
14
- "cicaddy>=0.8.0",
14
+ "cicaddy>=0.10.0",
15
15
  "PyGithub>=2.1.0",
16
16
  "detect-secrets>=1.4.0",
17
17
  ]
@@ -1,3 +1,3 @@
1
1
  """cicaddy-github: GitHub Actions plugin for cicaddy AI agent framework."""
2
2
 
3
- __version__ = "0.1.0"
3
+ __version__ = "0.6.0"
@@ -173,9 +173,36 @@ class GitHubPRAgent(BaseAIAgent):
173
173
  self.pr_number = settings.github_pr_number if settings else os.getenv("GITHUB_PR_NUMBER")
174
174
  self.leak_detector = LeakDetector()
175
175
 
176
+ # Delegation hooks — forward to cicaddy core's BaseReviewAgent.
177
+ #
178
+ # This class inherits from BaseAIAgent (not BaseReviewAgent) because it
179
+ # handles GitHub platform integration inline. We forward review-specific
180
+ # delegation hooks as explicit unbound method calls to keep all delegation
181
+ # logic in cicaddy core.
182
+
176
183
  def _get_agent_type(self) -> str:
177
184
  """PR review agents use the 'review' delegation registry."""
178
- return "review"
185
+ from cicaddy.agent.base_review_agent import (
186
+ BaseReviewAgent as _CoreReviewAgent,
187
+ )
188
+
189
+ return _CoreReviewAgent._get_agent_type(self) # ty: ignore[invalid-argument-type]
190
+
191
+ def _get_delegation_context(self, context: dict[str, Any]) -> dict[str, Any]:
192
+ """Shape context for review delegation triage."""
193
+ from cicaddy.agent.base_review_agent import (
194
+ BaseReviewAgent as _CoreReviewAgent,
195
+ )
196
+
197
+ return _CoreReviewAgent._get_delegation_context(self, context) # ty: ignore[invalid-argument-type]
198
+
199
+ def _post_process_plan(self, plan: Any, registry: dict[str, Any]) -> Any:
200
+ """Ensure general-reviewer is always included in review plans."""
201
+ from cicaddy.agent.base_review_agent import (
202
+ BaseReviewAgent as _CoreReviewAgent,
203
+ )
204
+
205
+ return _CoreReviewAgent._post_process_plan(self, plan, registry) # ty: ignore[invalid-argument-type, unresolved-attribute]
179
206
 
180
207
  async def _setup_local_tools(self):
181
208
  """Setup local tools for PR review."""
@@ -433,9 +460,32 @@ class GitHubGoDepReviewAgent(BaseAIAgent):
433
460
  self.pr_number = getattr(settings, "github_pr_number", None) if settings else None
434
461
  self.leak_detector = LeakDetector()
435
462
 
463
+ # Delegation hooks — forward to cicaddy core's BaseReviewAgent.
464
+ # See GitHubPRAgent docstring for rationale.
465
+
436
466
  def _get_agent_type(self) -> str:
437
467
  """Dependency review agents use the 'review' delegation registry."""
438
- return "review"
468
+ from cicaddy.agent.base_review_agent import (
469
+ BaseReviewAgent as _CoreReviewAgent,
470
+ )
471
+
472
+ return _CoreReviewAgent._get_agent_type(self) # ty: ignore[invalid-argument-type]
473
+
474
+ def _get_delegation_context(self, context: dict[str, Any]) -> dict[str, Any]:
475
+ """Shape context for review delegation triage."""
476
+ from cicaddy.agent.base_review_agent import (
477
+ BaseReviewAgent as _CoreReviewAgent,
478
+ )
479
+
480
+ return _CoreReviewAgent._get_delegation_context(self, context) # ty: ignore[invalid-argument-type]
481
+
482
+ def _post_process_plan(self, plan: Any, registry: dict[str, Any]) -> Any:
483
+ """Ensure general-reviewer is always included in review plans."""
484
+ from cicaddy.agent.base_review_agent import (
485
+ BaseReviewAgent as _CoreReviewAgent,
486
+ )
487
+
488
+ return _CoreReviewAgent._post_process_plan(self, plan, registry) # ty: ignore[invalid-argument-type, unresolved-attribute]
439
489
 
440
490
  async def _setup_local_tools(self):
441
491
  """Setup local tools including git and dependency review tools."""
@@ -0,0 +1,146 @@
1
+ """Tests for review agent delegation hook forwarding to cicaddy core."""
2
+
3
+ from unittest.mock import MagicMock
4
+
5
+ import pytest
6
+ from cicaddy.delegation.registry import SubAgentSpec
7
+ from cicaddy.delegation.triage import DelegationEntry, DelegationPlan
8
+
9
+ from cicaddy_github.github_integration.agents import (
10
+ GitHubGoDepReviewAgent,
11
+ GitHubPRAgent,
12
+ )
13
+
14
+ # _post_process_plan exists in cicaddy core >= 0.9.0 (PR #50).
15
+ # CI may install an older release; skip tests that depend on it.
16
+ _has_post_process = hasattr(
17
+ __import__("cicaddy.agent.base_review_agent", fromlist=["BaseReviewAgent"]).BaseReviewAgent,
18
+ "_post_process_plan",
19
+ )
20
+ _skip_no_post_process = pytest.mark.skipif(
21
+ not _has_post_process,
22
+ reason="cicaddy core missing _post_process_plan (needs >= 0.9.0)",
23
+ )
24
+
25
+
26
+ def _make_pr_agent():
27
+ """Create a minimal GitHubPRAgent with mocked settings."""
28
+ settings = MagicMock()
29
+ settings.github_pr_number = "123"
30
+ agent = GitHubPRAgent.__new__(GitHubPRAgent)
31
+ agent.settings = settings
32
+ agent.pr_number = "123"
33
+ return agent
34
+
35
+
36
+ def _make_dep_review_agent():
37
+ """Create a minimal GitHubGoDepReviewAgent with mocked settings."""
38
+ settings = MagicMock()
39
+ agent = GitHubGoDepReviewAgent.__new__(GitHubGoDepReviewAgent)
40
+ agent.settings = settings
41
+ agent.pr_number = "456"
42
+ return agent
43
+
44
+
45
+ class TestPRAgentDelegationHooks:
46
+ """Verify GitHubPRAgent delegation hooks forward to cicaddy core."""
47
+
48
+ def test_get_agent_type_returns_review(self):
49
+ agent = _make_pr_agent()
50
+ assert agent._get_agent_type() == "review"
51
+
52
+ def test_get_delegation_context_extracts_diff(self):
53
+ agent = _make_pr_agent()
54
+ context = {
55
+ "diff": ("diff --git a/main.go b/main.go\n+import fmt\n"),
56
+ "diff_lines": 2,
57
+ "analysis_type": "pull_request",
58
+ "pull_request": {"title": "Fix bug"},
59
+ }
60
+ result = agent._get_delegation_context(context)
61
+ assert "diff" in result
62
+ assert result["changed_files"] == ["main.go"]
63
+ assert result["analysis_type"] == "pull_request"
64
+
65
+ @_skip_no_post_process
66
+ def test_post_process_plan_injects_general_reviewer(self):
67
+ agent = _make_pr_agent()
68
+ plan = DelegationPlan(
69
+ entries=[
70
+ DelegationEntry(
71
+ agent_name="security-reviewer",
72
+ categories=["security"],
73
+ rationale="test",
74
+ priority=10,
75
+ )
76
+ ]
77
+ )
78
+ registry = {
79
+ "security-reviewer": SubAgentSpec(
80
+ name="security-reviewer",
81
+ persona="sec",
82
+ description="Security review",
83
+ categories=["security"],
84
+ priority=10,
85
+ agent_type="review",
86
+ ),
87
+ "general-reviewer": SubAgentSpec(
88
+ name="general-reviewer",
89
+ persona="eng",
90
+ description="General review",
91
+ categories=["code_quality"],
92
+ priority=100,
93
+ agent_type="review",
94
+ ),
95
+ }
96
+
97
+ result = agent._post_process_plan(plan, registry)
98
+ names = [e.agent_name for e in result.entries]
99
+ assert "general-reviewer" in names
100
+ assert len(result.entries) == 2
101
+
102
+ @_skip_no_post_process
103
+ def test_post_process_plan_no_duplicate(self):
104
+ agent = _make_pr_agent()
105
+ plan = DelegationPlan(
106
+ entries=[
107
+ DelegationEntry(
108
+ agent_name="general-reviewer",
109
+ categories=["code_quality"],
110
+ rationale="test",
111
+ priority=100,
112
+ )
113
+ ]
114
+ )
115
+ registry = {
116
+ "general-reviewer": SubAgentSpec(
117
+ name="general-reviewer",
118
+ persona="eng",
119
+ description="General review",
120
+ categories=["code_quality"],
121
+ priority=100,
122
+ agent_type="review",
123
+ ),
124
+ }
125
+
126
+ result = agent._post_process_plan(plan, registry)
127
+ assert len(result.entries) == 1
128
+
129
+
130
+ class TestGoDepReviewAgentDelegationHooks:
131
+ """Verify GitHubGoDepReviewAgent delegation hooks forward to cicaddy core."""
132
+
133
+ def test_get_agent_type_returns_review(self):
134
+ agent = _make_dep_review_agent()
135
+ assert agent._get_agent_type() == "review"
136
+
137
+ def test_get_delegation_context_extracts_diff(self):
138
+ agent = _make_dep_review_agent()
139
+ context = {
140
+ "diff": ("diff --git a/go.mod b/go.mod\n+require example.com/pkg v1.2.0\n"),
141
+ "diff_lines": 2,
142
+ "analysis_type": "go_dependency_review",
143
+ }
144
+ result = agent._get_delegation_context(context)
145
+ assert result["changed_files"] == ["go.mod"]
146
+ assert result["analysis_type"] == "go_dependency_review"
File without changes
File without changes
File without changes
File without changes