Add startup smoke tests for Linux binary and Docker image#147
Conversation
Adds two shell scripts and a CI workflow that verify the compiled Linux binary and Docker image can start successfully against an in-memory SQLite database, then checks that /health returns OK and /ui/ serves HTML. - scripts/test-startup-binary.sh: stages plexus-linux in packages/backend/ so ../frontend/dist resolves correctly, polls for the "Server starting on port" log line, then validates /health and /ui/. - scripts/test-startup-docker.sh: runs the image with DATABASE_URL=sqlite://:memory: and ADMIN_KEY, polls container logs for readiness, then validates the same endpoints. - .github/workflows/startup-tests.yml: CI workflow triggered on every push and pull_request. Runs unit tests first, then binary-startup and docker-startup in parallel (both gated on unit tests passing). https://claude.ai/code/session_01JmEoawVn7YLRDiTsGeZSxY
Merges startup-tests.yml into dev-release.yml to avoid running unit
tests, binary compilation, and Docker builds twice on main.
The combined workflow triggers on push to main (with path filter),
pull_request, and workflow_dispatch. Job flow:
unit-tests
├── binary-startup (compile:linux + smoke test)
└── docker-startup (docker build + smoke test)
└── dev-release [main / workflow_dispatch only]
(compile all platforms, push Docker, create release)
PRs and feature branches get unit + startup tests without triggering a
release. The dev-release job only runs after both startup tests pass.
https://claude.ai/code/session_01JmEoawVn7YLRDiTsGeZSxY
There was a problem hiding this comment.
Pull request overview
Adds CI-level smoke coverage to ensure both the compiled Linux binary and the Docker image can start successfully and serve key endpoints (/health, /ui/) using an in-memory SQLite database.
Changes:
- Added
scripts/test-startup-binary.shto boot the compiledplexus-linuxand validate readiness + HTTP endpoints. - Added
scripts/test-startup-docker.shto run the Docker image and validate readiness + HTTP endpoints. - Expanded
.github/workflows/dev-release.ymlto run unit tests first, then run binary/docker startup tests before the dev release job.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 7 comments.
| File | Description |
|---|---|
| scripts/test-startup-docker.sh | New Docker image startup smoke test (logs readiness + curls /health and /ui/). |
| scripts/test-startup-binary.sh | New compiled-binary startup smoke test (stages binary in backend dir, checks readiness + endpoints). |
| .github/workflows/dev-release.yml | Adds PR CI and startup smoke jobs, gates dev release on successful startup tests. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
scripts/test-startup-binary.sh
Outdated
| ( | ||
| cd "${BINARY_WORKDIR}" | ||
| DATABASE_URL="sqlite://:memory:" \ | ||
| ADMIN_KEY="${ADMIN_KEY}" \ | ||
| PORT="${PORT}" \ | ||
| LOG_LEVEL="info" \ | ||
| "./${BINARY_NAME}" | ||
| ) > "${LOG_FILE}" 2>&1 & | ||
| PID=$! |
There was a problem hiding this comment.
The background PID captured here is for the subshell, not necessarily the actual server process. In cleanup, sending kill $PID may terminate only the subshell while leaving the compiled server running (orphaned), which can make the test flaky and leak processes on self-hosted runners. Start the binary directly in the background from the intended working directory and capture/kill the real process PID (or kill the whole process group).
| ( | |
| cd "${BINARY_WORKDIR}" | |
| DATABASE_URL="sqlite://:memory:" \ | |
| ADMIN_KEY="${ADMIN_KEY}" \ | |
| PORT="${PORT}" \ | |
| LOG_LEVEL="info" \ | |
| "./${BINARY_NAME}" | |
| ) > "${LOG_FILE}" 2>&1 & | |
| PID=$! | |
| pushd "${BINARY_WORKDIR}" >/dev/null | |
| DATABASE_URL="sqlite://:memory:" \ | |
| ADMIN_KEY="${ADMIN_KEY}" \ | |
| PORT="${PORT}" \ | |
| LOG_LEVEL="info" \ | |
| "./${BINARY_NAME}" > "${LOG_FILE}" 2>&1 & | |
| PID=$! | |
| popd >/dev/null |
There was a problem hiding this comment.
Done in ff2ad6c. Replaced the subshell ( cd ... ) & with pushd/popd so PID=$! now captures the actual binary process. This ensures kill $PID in cleanup correctly terminates the server rather than just the subshell wrapper.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Agent-Logs-Url: https://github.com/mcowger/plexus/sessions/8862f886-ec2a-479f-a336-b9eee1c39235 Co-authored-by: mcowger <1929548+mcowger@users.noreply.github.com>
( cd ... ) &withpushd/popdsoPID=$!refers to the compiled binary process itself, not the subshell wrapper — prevents orphaned server processes whencleanuprunskill $PID⚡ Quickly spin up Copilot coding agent tasks from anywhere on your macOS or Windows machine with Raycast.