-
Notifications
You must be signed in to change notification settings - Fork 0
195 lines (154 loc) · 6.56 KB
/
Copy pathsetup_test.yml
File metadata and controls
195 lines (154 loc) · 6.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
name: Test setup.sh
on:
push:
branches: ["main"]
pull_request:
branches: ["main"]
workflow_dispatch:
permissions:
issues: write
contents: read
env:
ERROR_LOG: /tmp/charvim_setup_errors.log
jobs:
test-setup:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install dependencies
run: sudo apt-get install -y git curl jq 2>/dev/null
- name: Make setup.sh executable
run: chmod +x setup.sh
# ── Test 1: fresh install ──────────────────────────────────────────────
- name: Test fresh installation
run: |
OUTPUT=$(./setup.sh 2>&1)
echo "$OUTPUT"
if [ ! -L "$HOME/.config/nvim" ]; then
printf "\n=== Fresh install FAILED: symlink not created ===\n%s\n" "$OUTPUT" >> "$ERROR_LOG"
exit 1
fi
TARGET=$(readlink "$HOME/.config/nvim")
EXPECTED="$(pwd)/nvim"
echo "Symlink: $TARGET"
if [ "$TARGET" != "$EXPECTED" ]; then
printf "\n=== Fresh install FAILED: wrong symlink target ===\nExpected: %s\nGot: %s\n" \
"$EXPECTED" "$TARGET" >> "$ERROR_LOG"
exit 1
fi
[ -d "$HOME/.config/nvim" ] || {
echo "ERROR: config dir not accessible via symlink" | tee -a "$ERROR_LOG"
exit 1
}
echo "Fresh install OK"
# ── Test 2: backup of existing config ─────────────────────────────────
- name: Test backup of existing config
run: |
rm -f "$HOME/.config/nvim"
rm -rf "$HOME/.config/nvim.bak."*
mkdir -p "$HOME/.config/nvim"
echo "old config" > "$HOME/.config/nvim/init.lua"
./setup.sh 2>&1
BACKUP=$(ls -d "$HOME/.config"/nvim.bak.* 2>/dev/null | head -1)
if [ -z "$BACKUP" ]; then
echo "ERROR: backup not created" | tee -a "$ERROR_LOG"
exit 1
fi
CONTENT=$(cat "$BACKUP/init.lua" 2>/dev/null)
if [ "$CONTENT" != "old config" ]; then
printf "ERROR: backup content wrong. Got: %s\n" "$CONTENT" | tee -a "$ERROR_LOG"
exit 1
fi
if [ ! -L "$HOME/.config/nvim" ]; then
echo "ERROR: symlink not recreated after backup" | tee -a "$ERROR_LOG"
exit 1
fi
echo "Backup test OK"
# ── Test 3: idempotent re-run ──────────────────────────────────────────
- name: Test idempotent re-run
run: |
./setup.sh 2>&1
if [ ! -L "$HOME/.config/nvim" ]; then
echo "ERROR: symlink missing after re-run" | tee -a "$ERROR_LOG"
exit 1
fi
echo "Re-run OK"
# ── AI error reporting ─────────────────────────────────────────────────
- name: Install Ollama
if: failure()
run: |
curl -fsSL https://ollama.com/install.sh | sh
ollama serve &>/dev/null &
echo "Waiting for Ollama..."
for i in $(seq 1 20); do
curl -sf http://localhost:11434/ && break || sleep 2
done
- name: Pull Gemma model
if: failure()
run: ollama pull gemma3:1b
- name: Generate error report with Gemma
if: failure()
id: ai_report
run: |
ERROR_CONTENT=$(cat "$ERROR_LOG" 2>/dev/null | tail -200 || echo "No error log captured")
PROMPT="You are a CI assistant for the CharVim Neovim configuration project. \
Analyze this setup.sh test failure and produce a structured GitHub issue report. \
Include: 1) A short title (max 80 chars, no markdown), 2) What step failed and why, \
3) The most likely root cause, 4) Steps to fix it. Use Markdown.\n\n\
Repository: CharVim (Neovim config), Workflow: Test setup.sh\n\
Error output:\n\`\`\`\n${ERROR_CONTENT}\n\`\`\`"
RESPONSE=$(curl -s --max-time 180 http://localhost:11434/api/generate \
-H "Content-Type: application/json" \
-d "$(jq -n \
--arg model "gemma3:1b" \
--arg prompt "$PROMPT" \
'{model: $model, prompt: $prompt, stream: false}')" \
| jq -r '.response // "AI analysis unavailable — see raw output below."')
TITLE=$(echo "$RESPONSE" | grep -m1 -v '^[[:space:]]*$' \
| sed 's/^[#*[:space:]]*//' | cut -c1-80)
[ -z "$TITLE" ] && TITLE="setup.sh test failure on $(date +%Y-%m-%d)"
echo "issue_title=$TITLE" >> "$GITHUB_OUTPUT"
cat > /tmp/issue_body.md << 'BODYEOF'
## CI Failure — Test setup.sh
BODYEOF
cat >> /tmp/issue_body.md << BODYEOF
| | |
|---|---|
| **Workflow** | \`${{ github.workflow }}\` |
| **Run** | [${{ github.run_id }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) |
| **Commit** | \`${{ github.sha }}\` |
| **Branch** | \`${{ github.ref_name }}\` |
| **Triggered by** | ${{ github.actor }} |
---
## Gemma Analysis
${RESPONSE}
---
<details>
<summary>Raw CI error output</summary>
\`\`\`
$(cat "$ERROR_LOG" 2>/dev/null | tail -200 || echo "No log captured")
\`\`\`
</details>
BODYEOF
- name: Create GitHub issue
if: failure() && github.event_name != 'pull_request'
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const fs = require('fs');
let body;
try {
body = fs.readFileSync('/tmp/issue_body.md', 'utf8');
} catch {
body = 'setup.sh test failed. See run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}';
}
const title = 'CI: ${{ steps.ai_report.outputs.issue_title }}' || 'CI: setup.sh test failure';
await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: title.substring(0, 256),
body: body,
labels: ['bug', 'ci'],
});
console.log('Issue created.');