cicaddy-github 0.2.0__tar.gz → 0.3.1__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.
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/.claude/skills/cicaddy-action/SKILL.md +6 -2
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/.github/workflows/pr-review.yml +22 -4
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/CLAUDE.md +10 -0
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/Dockerfile +1 -1
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/PKG-INFO +26 -22
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/README.md +24 -20
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/entrypoint.sh +7 -0
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/pyproject.toml +2 -2
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/src/cicaddy_github/github_integration/agents.py +22 -1
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/src/cicaddy_github/github_integration/detector.py +1 -1
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/tests/unit/test_agents.py +41 -2
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/tests/unit/test_detector.py +10 -0
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/.github/dependabot.yml +0 -0
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/.github/workflows/changelog.yml +0 -0
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/.github/workflows/ci.yml +0 -0
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/.github/workflows/release.yml +0 -0
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/.gitignore +0 -0
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/.pre-commit-config.yaml +0 -0
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/CODE_OF_CONDUCT.md +0 -0
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/CONTRIBUTING.md +0 -0
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/LICENSE +0 -0
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/action.yml +0 -0
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/src/cicaddy_github/__init__.py +0 -0
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/src/cicaddy_github/config/__init__.py +0 -0
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/src/cicaddy_github/config/settings.py +0 -0
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/src/cicaddy_github/github_integration/__init__.py +0 -0
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/src/cicaddy_github/github_integration/analyzer.py +0 -0
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/src/cicaddy_github/github_integration/tools.py +0 -0
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/src/cicaddy_github/plugin.py +0 -0
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/src/cicaddy_github/security/__init__.py +0 -0
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/src/cicaddy_github/security/leak_detector.py +0 -0
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/src/cicaddy_github/validation.py +0 -0
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/tasks/changelog_report.yml +0 -0
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/tasks/pr_review.yml +0 -0
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/templates/report_template.html +0 -0
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/tests/__init__.py +0 -0
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/tests/conftest.py +0 -0
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/tests/unit/__init__.py +0 -0
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/tests/unit/test_analyzer.py +0 -0
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/tests/unit/test_leak_detector.py +0 -0
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/tests/unit/test_plugin.py +0 -0
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/tests/unit/test_settings.py +0 -0
- {cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/tests/unit/test_tools.py +0 -0
|
@@ -219,15 +219,19 @@ context: |
|
|
|
219
219
|
|
|
220
220
|
## Workflow Usage
|
|
221
221
|
|
|
222
|
+
The PR review workflow uses `pull_request_target` so secrets are available for
|
|
223
|
+
fork PRs. Internal PRs run automatically; fork PRs require a maintainer to add
|
|
224
|
+
the `safe-to-review` label. The label is auto-removed on new pushes to prevent
|
|
225
|
+
TOCTOU bypasses.
|
|
226
|
+
|
|
222
227
|
```yaml
|
|
223
|
-
- uses: redhat-community-ai-tools/cicaddy-action@v0
|
|
228
|
+
- uses: redhat-community-ai-tools/cicaddy-action@v0.3.1
|
|
224
229
|
with:
|
|
225
230
|
ai_provider: gemini
|
|
226
231
|
ai_model: gemini-3-flash-preview
|
|
227
232
|
ai_api_key: ${{ secrets.AI_API_KEY }}
|
|
228
233
|
task_file: tasks/pr_review.yml
|
|
229
234
|
post_pr_comment: 'true'
|
|
230
|
-
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
231
235
|
```
|
|
232
236
|
|
|
233
237
|
## Running Locally
|
|
@@ -1,16 +1,35 @@
|
|
|
1
1
|
name: AI PR Review
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
|
-
|
|
5
|
-
types: [opened, synchronize]
|
|
4
|
+
pull_request_target:
|
|
5
|
+
types: [opened, synchronize, labeled]
|
|
6
6
|
|
|
7
7
|
permissions:
|
|
8
8
|
contents: read
|
|
9
9
|
pull-requests: write
|
|
10
10
|
|
|
11
11
|
jobs:
|
|
12
|
+
remove-label-on-push:
|
|
13
|
+
if: >-
|
|
14
|
+
github.event.action == 'synchronize' &&
|
|
15
|
+
github.event.pull_request.head.repo.full_name != github.repository &&
|
|
16
|
+
contains(github.event.pull_request.labels.*.name, 'safe-to-review')
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
permissions:
|
|
19
|
+
pull-requests: write
|
|
20
|
+
steps:
|
|
21
|
+
- name: Remove safe-to-review label on new push from fork
|
|
22
|
+
env:
|
|
23
|
+
GH_TOKEN: ${{ github.token }}
|
|
24
|
+
run: gh pr edit "${{ github.event.pull_request.number }}" --repo "${{ github.repository }}" --remove-label "safe-to-review"
|
|
25
|
+
|
|
12
26
|
review:
|
|
13
|
-
if:
|
|
27
|
+
if: >-
|
|
28
|
+
github.actor != 'dependabot[bot]' &&
|
|
29
|
+
(
|
|
30
|
+
(github.event.pull_request.head.repo.full_name == github.repository && github.event.action != 'labeled') ||
|
|
31
|
+
(github.event.action == 'labeled' && github.event.label.name == 'safe-to-review')
|
|
32
|
+
)
|
|
14
33
|
runs-on: ubuntu-latest
|
|
15
34
|
steps:
|
|
16
35
|
- uses: actions/checkout@v6
|
|
@@ -38,7 +57,6 @@ jobs:
|
|
|
38
57
|
ai_api_key: ${{ secrets.AI_API_KEY }}
|
|
39
58
|
task_file: tasks/pr_review.yml
|
|
40
59
|
post_pr_comment: 'true'
|
|
41
|
-
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
42
60
|
mcp_servers_config: ${{ steps.mcp.outputs.config }}
|
|
43
61
|
env:
|
|
44
62
|
ANALYSIS_FOCUS: "general"
|
|
@@ -27,5 +27,15 @@ GitHub Action that wraps cicaddy for running AI agent tasks in GitHub Actions wo
|
|
|
27
27
|
- Test files in `tests/unit/`
|
|
28
28
|
- Fixtures in `tests/conftest.py`
|
|
29
29
|
|
|
30
|
+
## Release Checklist
|
|
31
|
+
- **Bump `version` in `pyproject.toml` BEFORE tagging** — the release workflow builds from the checked-out source, so the `pyproject.toml` version must match the git tag. If the version doesn't match, PyPI will reject the upload (either as a duplicate or a mismatch).
|
|
32
|
+
- When bumping the version for a release, also update all `cicaddy-action@vX.Y.Z` version references in `README.md` and `.claude/skills/cicaddy-action/SKILL.md` to match the new version.
|
|
33
|
+
|
|
34
|
+
## PR Review Workflow Security
|
|
35
|
+
- The PR review workflow uses `pull_request_target` so secrets are available for fork PRs.
|
|
36
|
+
- Internal PRs (same repo) run automatically; fork PRs require the `safe-to-review` label.
|
|
37
|
+
- The label is auto-removed on `synchronize` (new pushes from forks) to prevent TOCTOU bypasses.
|
|
38
|
+
- The workflow never checks out or executes untrusted PR code — cicaddy fetches the diff via the GitHub API.
|
|
39
|
+
|
|
30
40
|
## Reference Repos
|
|
31
41
|
- [cicaddy core](https://github.com/waynesun09/cicaddy)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cicaddy-github
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.1
|
|
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
|
|
12
|
+
Requires-Dist: cicaddy>=0.3.0
|
|
13
13
|
Requires-Dist: detect-secrets>=1.4.0
|
|
14
14
|
Requires-Dist: pygithub>=2.1.0
|
|
15
15
|
Provides-Extra: test
|
|
@@ -32,59 +32,63 @@ GitHub Action that wraps [cicaddy](https://github.com/waynesun09/cicaddy) for ru
|
|
|
32
32
|
|
|
33
33
|
## Quick Start
|
|
34
34
|
|
|
35
|
-
###
|
|
35
|
+
### AI PR Review
|
|
36
|
+
|
|
37
|
+
This example uses the `pull_request` trigger, which works for in-repo PRs
|
|
38
|
+
(branches pushed to the same repository). For fork PR support, see
|
|
39
|
+
`.github/workflows/pr-review.yml` which uses `pull_request_target` with
|
|
40
|
+
a `safe-to-review` label gate.
|
|
36
41
|
|
|
37
42
|
```yaml
|
|
38
|
-
name:
|
|
43
|
+
name: PR Review
|
|
39
44
|
|
|
40
45
|
on:
|
|
41
|
-
|
|
42
|
-
types: [
|
|
46
|
+
pull_request:
|
|
47
|
+
types: [opened, synchronize]
|
|
48
|
+
|
|
49
|
+
permissions:
|
|
50
|
+
pull-requests: write
|
|
43
51
|
|
|
44
52
|
jobs:
|
|
45
|
-
|
|
53
|
+
review:
|
|
46
54
|
runs-on: ubuntu-latest
|
|
47
55
|
steps:
|
|
48
56
|
- uses: actions/checkout@v4
|
|
49
57
|
with:
|
|
50
58
|
fetch-depth: 0
|
|
51
59
|
|
|
52
|
-
- uses: redhat-community-ai-tools/cicaddy-action@v0
|
|
60
|
+
- uses: redhat-community-ai-tools/cicaddy-action@v0.3.1
|
|
53
61
|
with:
|
|
54
62
|
ai_provider: gemini
|
|
55
|
-
ai_model: gemini-
|
|
63
|
+
ai_model: gemini-3-flash-preview
|
|
56
64
|
ai_api_key: ${{ secrets.AI_API_KEY }}
|
|
57
|
-
task_file: tasks/
|
|
65
|
+
task_file: tasks/pr_review.yml
|
|
66
|
+
post_pr_comment: 'true'
|
|
58
67
|
```
|
|
59
68
|
|
|
60
|
-
###
|
|
69
|
+
### Changelog Report on Release
|
|
61
70
|
|
|
62
71
|
```yaml
|
|
63
|
-
name:
|
|
72
|
+
name: Generate Changelog
|
|
64
73
|
|
|
65
74
|
on:
|
|
66
|
-
|
|
67
|
-
types: [
|
|
68
|
-
|
|
69
|
-
permissions:
|
|
70
|
-
pull-requests: write
|
|
75
|
+
release:
|
|
76
|
+
types: [published]
|
|
71
77
|
|
|
72
78
|
jobs:
|
|
73
|
-
|
|
79
|
+
changelog:
|
|
74
80
|
runs-on: ubuntu-latest
|
|
75
81
|
steps:
|
|
76
82
|
- uses: actions/checkout@v4
|
|
77
83
|
with:
|
|
78
84
|
fetch-depth: 0
|
|
79
85
|
|
|
80
|
-
- uses: redhat-community-ai-tools/cicaddy-action@v0
|
|
86
|
+
- uses: redhat-community-ai-tools/cicaddy-action@v0.3.1
|
|
81
87
|
with:
|
|
82
88
|
ai_provider: gemini
|
|
83
89
|
ai_model: gemini-3-flash-preview
|
|
84
90
|
ai_api_key: ${{ secrets.AI_API_KEY }}
|
|
85
|
-
task_file: tasks/
|
|
86
|
-
post_pr_comment: 'true'
|
|
87
|
-
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
91
|
+
task_file: tasks/changelog_report.yml
|
|
88
92
|
```
|
|
89
93
|
|
|
90
94
|
## Inputs
|
|
@@ -12,59 +12,63 @@ GitHub Action that wraps [cicaddy](https://github.com/waynesun09/cicaddy) for ru
|
|
|
12
12
|
|
|
13
13
|
## Quick Start
|
|
14
14
|
|
|
15
|
-
###
|
|
15
|
+
### AI PR Review
|
|
16
|
+
|
|
17
|
+
This example uses the `pull_request` trigger, which works for in-repo PRs
|
|
18
|
+
(branches pushed to the same repository). For fork PR support, see
|
|
19
|
+
`.github/workflows/pr-review.yml` which uses `pull_request_target` with
|
|
20
|
+
a `safe-to-review` label gate.
|
|
16
21
|
|
|
17
22
|
```yaml
|
|
18
|
-
name:
|
|
23
|
+
name: PR Review
|
|
19
24
|
|
|
20
25
|
on:
|
|
21
|
-
|
|
22
|
-
types: [
|
|
26
|
+
pull_request:
|
|
27
|
+
types: [opened, synchronize]
|
|
28
|
+
|
|
29
|
+
permissions:
|
|
30
|
+
pull-requests: write
|
|
23
31
|
|
|
24
32
|
jobs:
|
|
25
|
-
|
|
33
|
+
review:
|
|
26
34
|
runs-on: ubuntu-latest
|
|
27
35
|
steps:
|
|
28
36
|
- uses: actions/checkout@v4
|
|
29
37
|
with:
|
|
30
38
|
fetch-depth: 0
|
|
31
39
|
|
|
32
|
-
- uses: redhat-community-ai-tools/cicaddy-action@v0
|
|
40
|
+
- uses: redhat-community-ai-tools/cicaddy-action@v0.3.1
|
|
33
41
|
with:
|
|
34
42
|
ai_provider: gemini
|
|
35
|
-
ai_model: gemini-
|
|
43
|
+
ai_model: gemini-3-flash-preview
|
|
36
44
|
ai_api_key: ${{ secrets.AI_API_KEY }}
|
|
37
|
-
task_file: tasks/
|
|
45
|
+
task_file: tasks/pr_review.yml
|
|
46
|
+
post_pr_comment: 'true'
|
|
38
47
|
```
|
|
39
48
|
|
|
40
|
-
###
|
|
49
|
+
### Changelog Report on Release
|
|
41
50
|
|
|
42
51
|
```yaml
|
|
43
|
-
name:
|
|
52
|
+
name: Generate Changelog
|
|
44
53
|
|
|
45
54
|
on:
|
|
46
|
-
|
|
47
|
-
types: [
|
|
48
|
-
|
|
49
|
-
permissions:
|
|
50
|
-
pull-requests: write
|
|
55
|
+
release:
|
|
56
|
+
types: [published]
|
|
51
57
|
|
|
52
58
|
jobs:
|
|
53
|
-
|
|
59
|
+
changelog:
|
|
54
60
|
runs-on: ubuntu-latest
|
|
55
61
|
steps:
|
|
56
62
|
- uses: actions/checkout@v4
|
|
57
63
|
with:
|
|
58
64
|
fetch-depth: 0
|
|
59
65
|
|
|
60
|
-
- uses: redhat-community-ai-tools/cicaddy-action@v0
|
|
66
|
+
- uses: redhat-community-ai-tools/cicaddy-action@v0.3.1
|
|
61
67
|
with:
|
|
62
68
|
ai_provider: gemini
|
|
63
69
|
ai_model: gemini-3-flash-preview
|
|
64
70
|
ai_api_key: ${{ secrets.AI_API_KEY }}
|
|
65
|
-
task_file: tasks/
|
|
66
|
-
post_pr_comment: 'true'
|
|
67
|
-
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
71
|
+
task_file: tasks/changelog_report.yml
|
|
68
72
|
```
|
|
69
73
|
|
|
70
74
|
## Inputs
|
|
@@ -50,6 +50,13 @@ export POST_PR_COMMENT="${INPUT_POST_PR_COMMENT:-false}"
|
|
|
50
50
|
# Extract PR number from GITHUB_REF (e.g. refs/pull/123/merge -> 123)
|
|
51
51
|
if [[ "${GITHUB_REF}" =~ ^refs/pull/([0-9]+)/ ]]; then
|
|
52
52
|
export GITHUB_PR_NUMBER="${BASH_REMATCH[1]}"
|
|
53
|
+
elif [[ -n "${GITHUB_EVENT_PATH}" && -f "${GITHUB_EVENT_PATH}" ]]; then
|
|
54
|
+
# For pull_request_target, GITHUB_REF is the base branch, not refs/pull/N/merge.
|
|
55
|
+
# Extract PR number from the event payload JSON instead.
|
|
56
|
+
PR_NUM=$(python3 -c "import json,sys; e=json.load(open(sys.argv[1])); print(e.get('pull_request',{}).get('number',''))" "${GITHUB_EVENT_PATH}" 2>/dev/null || true)
|
|
57
|
+
if [[ -n "${PR_NUM}" ]]; then
|
|
58
|
+
export GITHUB_PR_NUMBER="${PR_NUM}"
|
|
59
|
+
fi
|
|
53
60
|
fi
|
|
54
61
|
|
|
55
62
|
# Enable local tools (git operations) and set working directory
|
|
@@ -4,14 +4,14 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "cicaddy-github"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.3.1"
|
|
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
|
|
14
|
+
"cicaddy>=0.3.0",
|
|
15
15
|
"PyGithub>=2.1.0",
|
|
16
16
|
"detect-secrets>=1.4.0",
|
|
17
17
|
]
|
{cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/src/cicaddy_github/github_integration/agents.py
RENAMED
|
@@ -43,6 +43,26 @@ def dedent_code_blocks(text: str) -> str:
|
|
|
43
43
|
return _FENCED_CODE_BLOCK.sub(_dedent, text)
|
|
44
44
|
|
|
45
45
|
|
|
46
|
+
# Matches output wrapped in a single ```markdown ... ``` fence.
|
|
47
|
+
_MARKDOWN_WRAPPER = re.compile(
|
|
48
|
+
r"^\s*```(?:markdown|md)\s*\n(.*?)\n\s*```\s*$",
|
|
49
|
+
re.DOTALL | re.IGNORECASE,
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def strip_markdown_wrapper(text: str) -> str:
|
|
54
|
+
"""Strip a wrapping ```markdown fence from the entire AI output.
|
|
55
|
+
|
|
56
|
+
Some models interpret ``output_format: markdown`` as "wrap the response
|
|
57
|
+
in a markdown code fence", which causes GitHub to render the comment as
|
|
58
|
+
a literal code block instead of formatted markdown.
|
|
59
|
+
"""
|
|
60
|
+
m = _MARKDOWN_WRAPPER.match(text.strip())
|
|
61
|
+
if m:
|
|
62
|
+
return m.group(1)
|
|
63
|
+
return text
|
|
64
|
+
|
|
65
|
+
|
|
46
66
|
class GitHubTaskAgent(BaseAIAgent):
|
|
47
67
|
"""AI Agent for scheduled tasks and changelog generation."""
|
|
48
68
|
|
|
@@ -280,7 +300,8 @@ Please provide your comprehensive analysis in markdown format.
|
|
|
280
300
|
comment = f"{BOT_COMMENT_MARKER_PR_REVIEW}\n"
|
|
281
301
|
|
|
282
302
|
if "ai_analysis" in analysis_result:
|
|
283
|
-
|
|
303
|
+
cleaned = strip_markdown_wrapper(analysis_result["ai_analysis"])
|
|
304
|
+
comment += dedent_code_blocks(cleaned) + "\n"
|
|
284
305
|
|
|
285
306
|
comment += (
|
|
286
307
|
"\n<!-- cicaddy-footer -->\n---\n"
|
{cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/src/cicaddy_github/github_integration/detector.py
RENAMED
|
@@ -10,7 +10,7 @@ logger = get_logger(__name__)
|
|
|
10
10
|
def _detect_github_agent_type(settings) -> str | None:
|
|
11
11
|
"""Detect GitHub-specific agent types from Actions environment variables."""
|
|
12
12
|
event = os.getenv("GITHUB_EVENT_NAME")
|
|
13
|
-
if event
|
|
13
|
+
if event in ("pull_request", "pull_request_target"):
|
|
14
14
|
logger.info(f"Detected pull request context: GITHUB_EVENT_NAME={event}")
|
|
15
15
|
return "github_pr"
|
|
16
16
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
"""Tests for dedent_code_blocks in agents module."""
|
|
1
|
+
"""Tests for dedent_code_blocks and strip_markdown_wrapper in agents module."""
|
|
2
2
|
|
|
3
|
-
from cicaddy_github.github_integration.agents import dedent_code_blocks
|
|
3
|
+
from cicaddy_github.github_integration.agents import dedent_code_blocks, strip_markdown_wrapper
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
class TestDedentCodeBlocks:
|
|
@@ -72,3 +72,42 @@ class TestDedentCodeBlocks:
|
|
|
72
72
|
assert result.startswith("* Item one\n")
|
|
73
73
|
assert result.endswith("* Item two")
|
|
74
74
|
assert "+added line" in result
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class TestStripMarkdownWrapper:
|
|
78
|
+
"""Test stripping wrapping ```markdown fences from AI output."""
|
|
79
|
+
|
|
80
|
+
def test_strips_markdown_wrapper(self):
|
|
81
|
+
"""Output wrapped in ```markdown is unwrapped."""
|
|
82
|
+
text = "```markdown\n### Summary\nSome analysis.\n```"
|
|
83
|
+
result = strip_markdown_wrapper(text)
|
|
84
|
+
assert result == "### Summary\nSome analysis."
|
|
85
|
+
|
|
86
|
+
def test_strips_md_wrapper(self):
|
|
87
|
+
"""Output wrapped in ```md is also unwrapped."""
|
|
88
|
+
text = "```md\n## Title\nContent.\n```"
|
|
89
|
+
result = strip_markdown_wrapper(text)
|
|
90
|
+
assert result == "## Title\nContent."
|
|
91
|
+
|
|
92
|
+
def test_strips_case_insensitive(self):
|
|
93
|
+
"""Output wrapped in ```Markdown or ```MD is also unwrapped."""
|
|
94
|
+
for tag in ("Markdown", "MARKDOWN", "MD", "Md"):
|
|
95
|
+
text = f"```{tag}\nContent here.\n```"
|
|
96
|
+
result = strip_markdown_wrapper(text)
|
|
97
|
+
assert result == "Content here.", f"Failed for tag: {tag}"
|
|
98
|
+
|
|
99
|
+
def test_no_change_without_wrapper(self):
|
|
100
|
+
"""Plain markdown without wrapper is unchanged."""
|
|
101
|
+
text = "### Summary\nSome analysis."
|
|
102
|
+
assert strip_markdown_wrapper(text) == text
|
|
103
|
+
|
|
104
|
+
def test_preserves_internal_code_blocks(self):
|
|
105
|
+
"""Code blocks inside the markdown wrapper are preserved."""
|
|
106
|
+
text = "```markdown\n### Example\n```python\nprint('hi')\n```\n```"
|
|
107
|
+
result = strip_markdown_wrapper(text)
|
|
108
|
+
assert "```python\nprint('hi')\n```" in result
|
|
109
|
+
|
|
110
|
+
def test_no_change_for_non_markdown_fence(self):
|
|
111
|
+
"""A ```python wrapper is NOT stripped."""
|
|
112
|
+
text = "```python\nprint('hi')\n```"
|
|
113
|
+
assert strip_markdown_wrapper(text) == text
|
|
@@ -17,6 +17,16 @@ class TestDetectGitHubAgentType:
|
|
|
17
17
|
result = _detect_github_agent_type(settings)
|
|
18
18
|
assert result == "github_pr"
|
|
19
19
|
|
|
20
|
+
def test_pull_request_target_event_returns_github_pr(self):
|
|
21
|
+
"""GITHUB_EVENT_NAME=pull_request_target returns github_pr."""
|
|
22
|
+
from cicaddy_github.github_integration.detector import _detect_github_agent_type
|
|
23
|
+
|
|
24
|
+
settings = MagicMock()
|
|
25
|
+
settings.github_pr_number = None
|
|
26
|
+
with patch.dict(os.environ, {"GITHUB_EVENT_NAME": "pull_request_target"}):
|
|
27
|
+
result = _detect_github_agent_type(settings)
|
|
28
|
+
assert result == "github_pr"
|
|
29
|
+
|
|
20
30
|
def test_push_event_returns_none(self):
|
|
21
31
|
"""GITHUB_EVENT_NAME=push returns None (falls through to TaskAgent)."""
|
|
22
32
|
from cicaddy_github.github_integration.detector import _detect_github_agent_type
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/src/cicaddy_github/github_integration/__init__.py
RENAMED
|
File without changes
|
{cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/src/cicaddy_github/github_integration/analyzer.py
RENAMED
|
File without changes
|
{cicaddy_github-0.2.0 → cicaddy_github-0.3.1}/src/cicaddy_github/github_integration/tools.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|