Skip to content

Smoke Tests

Smoke Tests #151

Workflow file for this run

name: Smoke Tests
on:
schedule:
- cron: "0 6 * * *"
workflow_dispatch:
permissions:
contents: read
jobs:
smoke:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Get latest release tag
id: release
shell: bash
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
TAG=$(gh release view --json tagName -q .tagName)
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
echo "Latest release: $TAG"
- name: Map runner to archive name
id: archive
shell: bash
run: |
set -euo pipefail
case "$RUNNER_OS" in
Linux) OS=linux ;;
macOS) OS=darwin ;;
Windows) OS=windows ;;
*) echo "Unsupported OS: $RUNNER_OS"; exit 1 ;;
esac
case "$RUNNER_ARCH" in
X64) ARCH=amd64 ;;
ARM64) ARCH=arm64 ;;
*) echo "Unsupported arch: $RUNNER_ARCH"; exit 1 ;;
esac
if [ "$OS" = "windows" ]; then
NAME="aitutor_${OS}_${ARCH}.zip"
else
NAME="aitutor_${OS}_${ARCH}.tar.gz"
fi
echo "name=$NAME" >> "$GITHUB_OUTPUT"
echo "os=$OS" >> "$GITHUB_OUTPUT"
echo "Archive: $NAME"
- name: Download release archive
shell: bash
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: gh release download ${{ steps.release.outputs.tag }} -p "${{ steps.archive.outputs.name }}"
- name: Extract binary (Linux/macOS)
if: runner.os != 'Windows'
run: tar xzf ${{ steps.archive.outputs.name }}
- name: Extract binary (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: Expand-Archive -Path ${{ steps.archive.outputs.name }} -DestinationPath . -Force
- name: Smoke test (Linux)
if: runner.os == 'Linux'
run: |
chmod +x ./aitutor
timeout 5 script -qec "./aitutor" output.txt || true
# Strip ANSI escape sequences (CSI, private modes, mode sets)
perl -pe 's/\e[\[\(][?]?[0-9;]*[a-zA-Z~]//g; s/\e[=>]//g; s/\r//g' output.txt > clean.txt
echo "--- Captured output ---"
cat clean.txt
echo "--- Checking content ---"
grep -q "Beginner" clean.txt
grep -qi "theory" clean.txt
grep -q "quit" clean.txt
echo "All checks passed"
- name: Smoke test (macOS)
if: runner.os == 'macOS'
run: |
chmod +x ./aitutor
# Run app inside script session with internal timeout so PTY is allocated properly
script -q output.txt bash -c './aitutor & PID=$!; sleep 5; kill $PID 2>/dev/null; exit 0' || true
# Strip ANSI escape sequences (CSI, private modes, mode sets)
perl -pe 's/\e[\[\(][?]?[0-9;]*[a-zA-Z~]//g; s/\e[=>]//g; s/\r//g' output.txt > clean.txt
echo "--- Captured output ---"
cat clean.txt
echo "--- Checking content ---"
grep -q "Beginner" clean.txt
grep -qi "theory" clean.txt
grep -q "quit" clean.txt
echo "All checks passed"
- name: Smoke test (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
$proc = Start-Process -FilePath .\aitutor.exe -PassThru -NoNewWindow -RedirectStandardOutput output.txt -RedirectStandardError stderr.txt
Start-Sleep -Seconds 5
if ($proc.HasExited -and $proc.ExitCode -ne 0) {
Write-Error "Binary crashed with exit code $($proc.ExitCode)"
exit 1
}
if (-not $proc.HasExited) {
Stop-Process -Id $proc.Id -Force
}
Write-Output "Binary started successfully without crashing"
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Smoke test npm package (Linux)
if: runner.os == 'Linux'
run: |
npm install -g @aitutor/cli
BINARY=$(which aitutor)
echo "npm binary: $BINARY"
timeout 5 script -qec "$BINARY" npm_output.txt || true
perl -pe 's/\e[\[\(][?]?[0-9;]*[a-zA-Z~]//g; s/\e[=>]//g; s/\r//g' npm_output.txt > npm_clean.txt
grep -q "Beginner" npm_clean.txt
grep -q "quit" npm_clean.txt
echo "npm smoke test passed"
- name: Smoke test npm package (macOS)
if: runner.os == 'macOS'
run: |
npm install -g @aitutor/cli
BINARY=$(which aitutor)
echo "npm binary: $BINARY"
export AITUTOR_BIN="$BINARY"
script -q npm_output.txt bash -c '$AITUTOR_BIN & PID=$!; sleep 5; kill $PID 2>/dev/null; exit 0' || true
perl -pe 's/\e[\[\(][?]?[0-9;]*[a-zA-Z~]//g; s/\e[=>]//g; s/\r//g' npm_output.txt > npm_clean.txt
grep -q "Beginner" npm_clean.txt
grep -q "quit" npm_clean.txt
echo "npm smoke test passed"
- name: Smoke test npm package (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
npm install -g @aitutor/cli
# Get-Command returns the .ps1 wrapper; find the actual .exe in the package dir
$npmRoot = (npm root -g)
$binary = Join-Path $npmRoot "@aitutor\cli\aitutor.exe"
Write-Output "npm binary: $binary"
$proc = Start-Process -FilePath $binary -PassThru -NoNewWindow
Start-Sleep -Seconds 5
if ($proc.HasExited -and $proc.ExitCode -ne 0) {
Write-Error "npm binary crashed with exit code $($proc.ExitCode)"
exit 1
}
if (-not $proc.HasExited) {
Stop-Process -Id $proc.Id -Force
}
Write-Output "npm smoke test passed"