name: CI on: push: branches: [ main ] pull_request: branches: [ main ] permissions: contents: read jobs: build-and-test: runs-on: ${{ matrix.os }} strategy: matrix: os: [ubuntu-latest, macos-latest] steps: - uses: actions/checkout@v4 - name: Install dependencies (Ubuntu) if: runner.os == 'Linux' run: | sudo apt-get update sudo apt-get install -y expect libssh-dev - name: Install dependencies (macOS) if: runner.os == 'macOS' run: | brew install libssh coreutils - name: Build run: make - name: Build with AddressSanitizer run: make asan - name: Run comprehensive tests run: make ci-test - name: Run release preflight run: make release-check - name: Check for memory leaks if: runner.os == 'Linux' run: | set -eu sudo apt-get install -y valgrind STATE_DIR=$(mktemp -d) SERVER_LOG="$STATE_DIR/server.log" VALGRIND_LOG="$STATE_DIR/valgrind.log" PORT=13990 SERVER_PID="" cleanup() { if [ -n "$SERVER_PID" ] && kill -0 "$SERVER_PID" 2>/dev/null; then kill "$SERVER_PID" 2>/dev/null || true wait "$SERVER_PID" 2>/dev/null || true fi rm -rf "$STATE_DIR" } trap cleanup EXIT ssh-keygen -q -t rsa -b 4096 -m PEM -N "" -f "$STATE_DIR/host_key" chmod 600 "$STATE_DIR/host_key" TNT_RATE_LIMIT=0 valgrind --leak-check=full --error-exitcode=99 --log-file="$VALGRIND_LOG" \ ./tnt -p "$PORT" -d "$STATE_DIR" >"$SERVER_LOG" 2>&1 & SERVER_PID=$! READY=0 for _ in $(seq 1 60); do if ! kill -0 "$SERVER_PID" 2>/dev/null; then break fi OUT=$(ssh -n -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \ -o BatchMode=yes -p "$PORT" localhost health 2>/dev/null || true) if [ "$OUT" = "ok" ]; then READY=1 break fi sleep 1 done if [ "$READY" -ne 1 ]; then echo "::group::server log" cat "$SERVER_LOG" || true echo "::endgroup::" echo "::group::valgrind log" cat "$VALGRIND_LOG" || true echo "::endgroup::" exit 1 fi kill "$SERVER_PID" 2>/dev/null || true wait "$SERVER_PID" 2>/dev/null || true SERVER_PID="" if ! grep -q "ERROR SUMMARY: 0 errors" "$VALGRIND_LOG"; then cat "$VALGRIND_LOG" exit 1 fi