Skip to content

Commit 872f8d0

Browse files
fix(docs): code analysis engine
changes: - file: ci_runner.py area: core added: [main, TestResult, run_tests, run_loop, check_strategy_completion, BugReport, +7 more] - file: auto_loop.py area: cli added: [ci_status, auto_loop, get_backend] stats: lines: "+4390/-21 (net +4369)" files: 30 complexity: "Large structural change (normalized)"
1 parent 0a7bdfc commit 872f8d0

32 files changed

+4411
-21
lines changed

.github/workflows/ci-auto-loop.yml

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
name: CI/CD with Auto Bug-Fix Loop
2+
3+
on:
4+
push:
5+
branches: [main, develop]
6+
pull_request:
7+
branches: [main]
8+
9+
env:
10+
PYTHON_VERSION: "3.11"
11+
12+
jobs:
13+
ci-loop:
14+
runs-on: ubuntu-latest
15+
permissions:
16+
contents: read
17+
issues: write
18+
pull-requests: write
19+
20+
steps:
21+
- name: Checkout code
22+
uses: actions/checkout@v4
23+
with:
24+
fetch-depth: 0 # Full history for better analysis
25+
26+
- name: Setup Python
27+
uses: actions/setup-python@v4
28+
with:
29+
python-version: ${{ env.PYTHON_VERSION }}
30+
31+
- name: Cache pip
32+
uses: actions/cache@v3
33+
with:
34+
path: ~/.cache/pip
35+
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements*.txt') }}
36+
restore-keys: |
37+
${{ runner.os }}-pip-
38+
39+
- name: Install dependencies
40+
run: |
41+
python -m pip install --upgrade pip
42+
pip install strategy-pm[github] pytest pytest-cov
43+
pip install llx # Install llx for AI analysis
44+
45+
- name: Install Ollama (for local LLM)
46+
if: env.AUTO_FIX == 'true'
47+
run: |
48+
curl -fsSL https://ollama.ai/install.sh | sh
49+
ollama serve &
50+
sleep 5
51+
ollama pull qwen2.5:3b
52+
53+
- name: Run CI Auto-Loop
54+
env:
55+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
56+
GITHUB_REPO: ${{ github.repository }}
57+
AUTO_FIX: ${{ vars.AUTO_FIX || 'false' }}
58+
run: |
59+
strategy-pm auto loop \
60+
--strategy ./strategy.yaml \
61+
--project . \
62+
--backend github \
63+
--max-iterations 5 \
64+
--auto-fix ${{ env.AUTO_FIX }} \
65+
--output ci-results.json
66+
67+
- name: Comment PR with results
68+
if: github.event_name == 'pull_request'
69+
uses: actions/github-script@v6
70+
with:
71+
script: |
72+
const fs = require('fs');
73+
74+
if (fs.existsSync('ci-results.json')) {
75+
const results = JSON.parse(fs.readFileSync('ci-results.json', 'utf8'));
76+
77+
const comment = `
78+
## 🤖 CI/CD Auto-Loop Results
79+
80+
**Status**: ${results.success ? '✅ Success' : '❌ Failed'}
81+
**Iterations**: ${results.total_iterations}
82+
**Tickets Created**: ${results.tickets_created.length}
83+
84+
${results.tickets_created.length > 0 ? `
85+
### 📫 Created Tickets
86+
${results.tickets_created.map(url => `- [Ticket](${url})`).join('\n')}
87+
` : ''}
88+
89+
${!results.success ? `
90+
### ❌ Issues
91+
Final status: ${results.final_status}
92+
` : ''}
93+
94+
---
95+
*Generated by SprintStrat CI/CD*
96+
`;
97+
98+
github.rest.issues.createComment({
99+
issue_number: context.issue.number,
100+
owner: context.repo.owner,
101+
repo: context.repo.repo,
102+
body: comment
103+
});
104+
}
105+
106+
- name: Update strategy if needed
107+
if: failure() && env.UPDATE_STRATEGY == 'true'
108+
run: |
109+
# Generate updated strategy based on failures
110+
llx chat --model balanced \
111+
--prompt "Update strategy.yaml based on recent test failures and CI results" \
112+
--output strategy-updated.yaml
113+
114+
# Create PR for strategy update
115+
git config --local user.email "action@github.com"
116+
git config --local user.name "GitHub Action"
117+
git checkout -b strategy-update-${{ github.run_number }}
118+
git add strategy-updated.yaml
119+
git commit -m "ci: Update strategy based on CI results"
120+
git push origin strategy-update-${{ github.run_number }}
121+
gh pr create --title "Auto-update strategy" --body "Strategy updated based on CI results"
122+
env:
123+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
124+
125+
- name: Upload artifacts
126+
uses: actions/upload-artifact@v3
127+
if: always()
128+
with:
129+
name: ci-results
130+
path: |
131+
ci-results.json
132+
test-results.xml
133+
coverage.json
134+
htmlcov/
135+
136+
- name: Coverage badge
137+
uses: tj-actions/coverage-badge-py@v2
138+
if: github.ref == 'refs/heads/main'
139+
with:
140+
output: coverage.svg
141+
142+
- name: Deploy coverage reports
143+
if: github.ref == 'refs/heads/main'
144+
uses: peaceiris/actions-gh-pages@v3
145+
with:
146+
github_token: ${{ secrets.GITHUB_TOKEN }}
147+
publish_dir: ./htmlcov
148+
destination_dir: coverage
149+
150+
notify:
151+
runs-on: ubuntu-latest
152+
needs: ci-loop
153+
if: always()
154+
155+
steps:
156+
- name: Notify Slack
157+
if: env.SLACK_WEBHOOK_URL != ''
158+
run: |
159+
curl -X POST -H 'Content-type: application/json' \
160+
--data '{"text":"CI/CD ${{ needs.ci-loop.result }}: ${{ github.repository }} - ${{ github.sha }}"}' \
161+
${{ env.SLACK_WEBHOOK_URL }}
162+
env:
163+
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

.gitlab-ci.yml

Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
# GitLab CI/CD with Auto Bug-Fix Loop
2+
stages:
3+
- test
4+
- analyze
5+
- ticket
6+
- fix
7+
- review
8+
9+
variables:
10+
PYTHON_VERSION: "3.11"
11+
AUTO_FIX: "false" # Set to "true" to enable auto-fix
12+
13+
# Cache pip dependencies
14+
cache:
15+
paths:
16+
- .cache/pip
17+
- .venv/
18+
19+
before_script:
20+
- python -m venv .venv
21+
- source .venv/bin/activate
22+
- pip install --upgrade pip
23+
- pip install strategy-pm[jira] pytest pytest-cov
24+
- pip install llx
25+
26+
# Test stage
27+
run_tests:
28+
stage: test
29+
script:
30+
- echo "🧪 Running tests..."
31+
- pytest --cov=src --cov-report=json --cov-report=html --junit-xml=test-results.xml -v
32+
artifacts:
33+
reports:
34+
junit: test-results.xml
35+
paths:
36+
- coverage.json
37+
- htmlcov/
38+
expire_in: 1 week
39+
coverage: '/TOTAL.+?(\d+\%)$/'
40+
only:
41+
- main
42+
- develop
43+
- merge_requests
44+
45+
# Code analysis stage
46+
code_analysis:
47+
stage: analyze
48+
script:
49+
- echo "🔍 Running code analysis..."
50+
# Run llx analysis
51+
- llx analyze --run --json > llx-analysis.json || true
52+
# Run vallm if available
53+
- vallm validate --json > vallm-report.json || true
54+
artifacts:
55+
paths:
56+
- llx-analysis.json
57+
- vallm-report.json
58+
expire_in: 1 week
59+
only:
60+
- main
61+
- develop
62+
- merge_requests
63+
allow_failure: true
64+
65+
# Ticket creation stage
66+
create_tickets:
67+
stage: ticket
68+
script:
69+
- echo "🎫 Creating tickets for failures..."
70+
- |
71+
if [ ! -f coverage.json ] || [ "$(jq '.totals.percent_covered' coverage.json)" -lt 80 ]; then
72+
echo "Coverage below threshold, creating tickets..."
73+
strategy-pm auto loop \
74+
--strategy ./strategy.yaml \
75+
--project . \
76+
--backend jira \
77+
--max-iterations 1 \
78+
--output ci-results.json
79+
else
80+
echo "Tests passed, no tickets needed"
81+
fi
82+
artifacts:
83+
paths:
84+
- ci-results.json
85+
expire_in: 1 week
86+
dependencies:
87+
- run_tests
88+
- code_analysis
89+
only:
90+
- main
91+
- develop
92+
93+
# Auto-fix stage (optional)
94+
auto_fix:
95+
stage: fix
96+
script:
97+
- echo "🔧 Attempting auto-fix..."
98+
- strategy-pm auto loop \
99+
--strategy ./strategy.yaml \
100+
--project . \
101+
--backend jira \
102+
--max-iterations 3 \
103+
--auto-fix \
104+
--output fix-results.json
105+
artifacts:
106+
paths:
107+
- fix-results.json
108+
expire_in: 1 week
109+
dependencies:
110+
- create_tickets
111+
only:
112+
- main
113+
- develop
114+
when: manual
115+
allow_failure: true
116+
117+
# Strategy review
118+
review_strategy:
119+
stage: review
120+
script:
121+
- echo "📊 Reviewing strategy..."
122+
- |
123+
# Check if strategy is complete
124+
strategy-pm strategy review \
125+
--strategy ./strategy.yaml \
126+
--project . \
127+
--backend jira \
128+
--output review-results.json
129+
130+
# Update Jira with status
131+
python - <<'EOF'
132+
import os
133+
import json
134+
from strategy.integrations.jira import JiraBackend
135+
136+
if os.path.exists('review-results.json'):
137+
with open('review-results.json') as f:
138+
results = json.load(f)
139+
140+
jira = JiraBackend(
141+
base_url=os.environ['JIRA_URL'],
142+
email=os.environ['JIRA_EMAIL'],
143+
token=os.environ['JIRA_TOKEN'],
144+
project=os.environ['JIRA_PROJECT']
145+
)
146+
147+
# Find or create sprint ticket
148+
summary = f"Sprint Review - {os.environ['CI_COMMIT_REF_NAME']}"
149+
description = f"""
150+
Pipeline: {os.environ['CI_PIPELINE_URL']}
151+
Commit: {os.environ['CI_COMMIT_SHA']}
152+
153+
Results:
154+
- Status: {results.get('summary', {}).get('status', 'Unknown')}
155+
- Completed: {results.get('summary', {}).get('completed', 0)}
156+
- In Progress: {results.get('summary', {}).get('in_progress', 0)}
157+
- Blocked: {results.get('summary', {}).get('blocked', 0)}
158+
"""
159+
160+
# Update or create ticket
161+
tickets = jira.search_tickets(f"summary~'{summary}'")
162+
if tickets:
163+
jira.update_ticket(tickets[0].id, description=description)
164+
else:
165+
jira.create_ticket(title=summary, description=description, labels=["sprint-review"])
166+
EOF
167+
artifacts:
168+
paths:
169+
- review-results.json
170+
expire_in: 1 week
171+
dependencies:
172+
- auto_fix
173+
- create_tickets
174+
only:
175+
- main
176+
- develop
177+
178+
# Notify on failure
179+
notify_failure:
180+
stage: review
181+
script:
182+
- echo "📧 Sending failure notification..."
183+
- |
184+
if [ -f ci-results.json ]; then
185+
# Send Slack notification
186+
curl -X POST -H 'Content-type: application/json' \
187+
--data "{
188+
\"text\": \"❌ Pipeline failed on $CI_PROJECT_NAME\nBranch: $CI_COMMIT_REF_NAME\nPipeline: $CI_PIPELINE_URL\"
189+
}" \
190+
$SLACK_WEBHOOK_URL || true
191+
192+
# Send email notification
193+
python - <<'EOF'
194+
import smtplib
195+
import os
196+
from email.mime.text import MIMEText
197+
198+
if os.environ.get('SMTP_HOST'):
199+
msg = MIMEText(f"""
200+
Pipeline failed on {os.environ['CI_PROJECT_NAME']}
201+
202+
Branch: {os.environ['CI_COMMIT_REF_NAME']}
203+
Commit: {os.environ['CI_COMMIT_SHA']}
204+
Pipeline: {os.environ['CI_PIPELINE_URL']}
205+
206+
Check the logs for details.
207+
""")
208+
209+
msg['Subject'] = f"CI/CD Failure: {os.environ['CI_PROJECT_NAME']}"
210+
msg['From'] = os.environ['SMTP_FROM']
211+
msg['To'] = os.environ['SMTP_TO']
212+
213+
server = smtplib.SMTP(os.environ['SMTP_HOST'])
214+
server.send_message(msg)
215+
server.quit()
216+
EOF
217+
fi
218+
when: on_failure
219+
only:
220+
- main
221+
- develop
222+
223+
# Deploy on success
224+
deploy:
225+
stage: review
226+
script:
227+
- echo "🚀 Deploying..."
228+
# Add your deployment commands here
229+
when: on_success
230+
only:
231+
- main
232+
environment:
233+
name: production
234+
url: https://your-app.com

0 commit comments

Comments
 (0)