3434
3535 cp log_parser.py requirements.txt ${DEB_ROOT}/usr/lib/log-explainer/
3636
37- cat > ${DEB_ROOT}/usr/bin/log-explainer << 'EOF'
38- #!/bin/bash
39- exec python3 /usr/lib/log-explainer/log_parser.py "$@"
40- EOF
37+ printf '#!/bin/bash\nexec python3 /usr/lib/log-explainer/log_parser.py "$@"\n' \
38+ > ${DEB_ROOT}/usr/bin/log-explainer
4139 chmod +x ${DEB_ROOT}/usr/bin/log-explainer
4240
4341 cat > ${DEB_ROOT}/DEBIAN/control << EOF
5553 Ollama must be installed separately: https://ollama.com/download
5654 EOF
5755
58- cat > ${DEB_ROOT}/DEBIAN/postinst << 'EOF'
59- #!/bin/bash
60- set -e
61- pip3 install requests --break-system-packages --quiet 2>/dev/null || \
62- pip3 install requests --quiet 2>/dev/null || true
63- if ! command -v ollama &>/dev/null; then
64- echo "NOTE: Ollama is not installed. Install from https://ollama.com/download"
65- echo " Then pull a model: ollama pull qwen2.5-coder:1.5b"
66- fi
67- EOF
56+ printf '#!/bin/bash\nset -e\npip3 install requests --break-system-packages --quiet 2>/dev/null || pip3 install requests --quiet 2>/dev/null || true\nif ! command -v ollama &>/dev/null; then\n echo "NOTE: Ollama not installed. See https://ollama.com/download"\nfi\n' \
57+ > ${DEB_ROOT}/DEBIAN/postinst
6858 chmod 755 ${DEB_ROOT}/DEBIAN/postinst
6959
7060 dpkg-deb --build --root-owner-group ${DEB_ROOT}
8070 cp log_parser.py requirements.txt \
8171 /tmp/log-explainer-${VERSION}/usr/lib/log-explainer/
8272
83- cat > /tmp/log-explainer-${VERSION}/usr/bin/log-explainer << 'EOF'
84- #!/bin/bash
85- exec python3 /usr/lib/log-explainer/log_parser.py "$@"
86- EOF
73+ printf '#!/bin/bash\nexec python3 /usr/lib/log-explainer/log_parser.py "$@"\n' \
74+ > /tmp/log-explainer-${VERSION}/usr/bin/log-explainer
8775 chmod +x /tmp/log-explainer-${VERSION}/usr/bin/log-explainer
8876
8977 cd /tmp && tar czf \
@@ -103,10 +91,7 @@ jobs:
10391
10492 %description
10593 Tails a live log file and uses a local LLM (via Ollama) to explain each
106- line in plain English in real time. Features severity classification,
107- pattern spike detection, and incident summarization. No API keys needed.
108-
109- Ollama must be installed separately: https://ollama.com/download
94+ line in plain English in real time. No API keys needed.
11095
11196 %prep
11297 %autosetup
@@ -120,10 +105,6 @@ jobs:
120105
121106 %post
122107 pip3 install requests --quiet 2>/dev/null || true
123- if ! command -v ollama &>/dev/null; then
124- echo "NOTE: Ollama is not installed. Install from https://ollama.com/download"
125- echo " Then pull a model: ollama pull qwen2.5-coder:1.5b"
126- fi
127108
128109 %files
129110 /usr/bin/log-explainer
@@ -167,26 +148,16 @@ jobs:
167148
168149 mkdir -p ${PAYLOAD}/usr/local/lib/log-explainer
169150 mkdir -p ${PAYLOAD}/usr/local/bin
151+ mkdir -p pkg/macos/scripts
170152
171153 cp log_parser.py requirements.txt ${PAYLOAD}/usr/local/lib/log-explainer/
172154
173- cat > ${PAYLOAD}/usr/local/bin/log-explainer << 'EOF'
174- #!/bin/bash
175- exec python3 /usr/local/lib/log-explainer/log_parser.py "$@"
176- EOF
155+ printf '#!/bin/bash\nexec python3 /usr/local/lib/log-explainer/log_parser.py "$@"\n' \
156+ > ${PAYLOAD}/usr/local/bin/log-explainer
177157 chmod +x ${PAYLOAD}/usr/local/bin/log-explainer
178158
179- mkdir -p pkg/macos/scripts
180- cat > pkg/macos/scripts/postinstall << 'EOF'
181- #!/bin/bash
182- set -e
183- pip3 install requests --quiet 2>/dev/null || \
184- pip3 install requests --break-system-packages --quiet 2>/dev/null || true
185- if ! command -v ollama &>/dev/null; then
186- echo "NOTE: Ollama is not installed. Install from https://ollama.com/download"
187- echo " Then pull a model: ollama pull qwen2.5-coder:1.5b"
188- fi
189- EOF
159+ printf '#!/bin/bash\nset -e\npip3 install requests --quiet 2>/dev/null || pip3 install requests --break-system-packages --quiet 2>/dev/null || true\nif ! command -v ollama &>/dev/null; then\n echo "NOTE: Ollama not installed. See https://ollama.com/download"\nfi\n' \
160+ > pkg/macos/scripts/postinstall
190161 chmod +x pkg/macos/scripts/postinstall
191162
192163 pkgbuild \
@@ -222,39 +193,34 @@ jobs:
222193 run : echo "VERSION=${GITHUB_REF_NAME#v}" >> $GITHUB_OUTPUT
223194
224195 - name : Find WiX Toolset
225- # WiX v3 is pre-installed on windows-latest — just locate it
226- shell : bash
196+ shell : pwsh
227197 run : |
228- WIX_BIN=$(find "C:/Program Files (x86)/WiX Toolset"* -name "candle.exe" 2>/dev/null | head -1 | xargs dirname)
229- echo "WIX_BIN=${WIX_BIN}" >> $GITHUB_ENV
230- echo "Found WiX at: ${WIX_BIN}"
198+ $candle = Get-ChildItem "C:\Program Files (x86)\WiX Toolset*\bin\candle.exe" -ErrorAction SilentlyContinue | Select-Object -First 1
199+ if (-not $candle) { throw "candle.exe not found — WiX Toolset is not installed" }
200+ $wixBin = $candle.DirectoryName
201+ Write-Output "Found WiX at: $wixBin"
202+ Add-Content -Path $env:GITHUB_ENV -Value "WIX_BIN=$wixBin"
231203
232204 - name : Stage payload
233205 shell : bash
234206 run : |
235- VERSION=${{ steps.version.outputs.VERSION }}
236207 mkdir -p pkg/windows/payload
237208 cp log_parser.py requirements.txt pkg/windows/payload/
238-
239- cat > pkg/windows/payload/log-explainer.cmd << 'EOF'
240- @echo off
241- python "%~dp0log_parser.py" %*
242- EOF
209+ printf '@echo off\npython "%%~dp0log_parser.py" %%*\n' \
210+ > pkg/windows/payload/log-explainer.cmd
243211
244212 - name : Write WiX source
245213 shell : bash
246214 run : |
247215 VERSION=${{ steps.version.outputs.VERSION }}
248- # WiX requires a 4-part version: major.minor.patch.0
249- WIX_VERSION="${VERSION}.0"
250-
216+ mkdir -p pkg/windows
251217 cat > pkg/windows/log-explainer.wxs << EOF
252218 <?xml version="1.0" encoding="UTF-8"?>
253219 <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
254220 <Product
255221 Id="*"
256222 Name="Log Explainer"
257- Version="${WIX_VERSION} "
223+ Version="${VERSION}.0 "
258224 Manufacturer="Sharan CH"
259225 UpgradeCode="4A8B3C2D-1E5F-6A7B-8C9D-0E1F2A3B4C5D"
260226 Language="1033"
@@ -305,11 +271,14 @@ jobs:
305271 EOF
306272
307273 - name : Build .msi
308- shell : bash
274+ shell : pwsh
309275 run : |
310- VERSION=${{ steps.version.outputs.VERSION }}
311- "${WIX_BIN}/candle.exe" pkg/windows/log-explainer.wxs -out pkg/windows/log-explainer.wixobj
312- "${WIX_BIN}/light.exe" pkg/windows/log-explainer.wixobj -out pkg/windows/log-explainer-${VERSION}.msi
276+ $version = "${{ steps.version.outputs.VERSION }}"
277+ $wixBin = $env:WIX_BIN
278+ & "$wixBin\candle.exe" pkg/windows/log-explainer.wxs -out pkg/windows/log-explainer.wixobj
279+ if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
280+ & "$wixBin\light.exe" pkg/windows/log-explainer.wixobj -out "pkg/windows/log-explainer-$version.msi"
281+ if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
313282
314283 - name : Upload Windows package
315284 uses : actions/upload-artifact@v4
@@ -353,21 +322,15 @@ jobs:
353322 ```
354323
355324 **macOS**
356- ```
357- Open log-explainer-${{ steps.version.outputs.VERSION }}.pkg and follow the installer.
358- ```
325+ Open `log-explainer-${{ steps.version.outputs.VERSION }}.pkg` and follow the installer.
359326
360327 **Windows**
361- ```
362- Run log-explainer-${{ steps.version.outputs.VERSION }}.msi and follow the installer.
363- ```
328+ Run `log-explainer-${{ steps.version.outputs.VERSION }}.msi` and follow the installer.
364329
365330 **After install**
366331 ```bash
367- # Local log file
368332 log-explainer /var/log/app.log --model qwen2.5-coder:1.5b
369333
370- # Remote via SSH (Linux/macOS)
371334 ssh user@server "tail -f /var/log/app.log" | log-explainer /dev/stdin --model qwen2.5-coder:1.5b
372335 ```
373336
0 commit comments