-
Notifications
You must be signed in to change notification settings - Fork 0
Fix API contract validation workflow backend startup race condition #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -74,13 +74,32 @@ jobs: | |||||||||||||
| - name: Start FastAPI backend | ||||||||||||||
| run: | | ||||||||||||||
| cd backend | ||||||||||||||
| python -m uvicorn app:app --host 0.0.0.0 --port 8000 & | ||||||||||||||
| BACKEND_LOG="${{ github.workspace }}/backend.log" | ||||||||||||||
|
|
||||||||||||||
| # Start backend with logging | ||||||||||||||
| python -m uvicorn app:app --host 0.0.0.0 --port 8000 > "$BACKEND_LOG" 2>&1 & | ||||||||||||||
| BACKEND_PID=$! | ||||||||||||||
| echo "Backend started with PID: $BACKEND_PID" | ||||||||||||||
|
|
||||||||||||||
| # Wait for backend to be ready | ||||||||||||||
| echo "Waiting for backend to start..." | ||||||||||||||
| sleep 15 | ||||||||||||||
| # Verify backend is responding | ||||||||||||||
| curl --retry 5 --retry-delay 2 --retry-connrefused http://localhost:8000/health || exit 1 | ||||||||||||||
| echo "Backend is ready!" | ||||||||||||||
| sleep 30 | ||||||||||||||
|
|
||||||||||||||
| # Check if process is still running | ||||||||||||||
| if ! ps -p $BACKEND_PID > /dev/null; then | ||||||||||||||
| echo "❌ Backend process died! Logs:" | ||||||||||||||
| cat "$BACKEND_LOG" | ||||||||||||||
| exit 1 | ||||||||||||||
| fi | ||||||||||||||
|
|
||||||||||||||
| # Verify backend is responding with more retries | ||||||||||||||
| echo "Checking backend health..." | ||||||||||||||
| curl --retry 10 --retry-delay 3 --retry-connrefused http://localhost:8000/health || { | ||||||||||||||
|
||||||||||||||
| curl --retry 10 --retry-delay 3 --retry-connrefused http://localhost:8000/health || { | |
| curl --fail --retry 10 --retry-delay 3 --retry-connrefused http://localhost:8000/health || { |
Copilot
AI
Jan 26, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The curl command uses 'localhost' which can resolve to either IPv4 (127.0.0.1) or IPv6 (::1). The original error message showed connection refused to ::1:8000 (IPv6). While the backend binds to 0.0.0.0, consider explicitly using http://127.0.0.1:8000/health instead of localhost to avoid any IPv6 resolution issues and ensure consistent IPv4 connection attempts.
| curl --retry 10 --retry-delay 3 --retry-connrefused http://localhost:8000/health || { | |
| curl --retry 10 --retry-delay 3 --retry-connrefused http://127.0.0.1:8000/health || { |
Copilot
AI
Jan 26, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding the --max-time flag to curl to prevent indefinite hangs if the backend responds but doesn't complete the request. For example: curl --retry 10 --retry-delay 3 --retry-connrefused --max-time 5 http://localhost:8000/health. This ensures each individual attempt times out after 5 seconds, preventing the health check from hanging indefinitely on a partially responsive backend.
| curl --retry 10 --retry-delay 3 --retry-connrefused http://localhost:8000/health || { | |
| curl --retry 10 --retry-delay 3 --retry-connrefused --max-time 5 http://localhost:8000/health || { |
Copilot
AI
Jan 26, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The backend logs are printed to the console on failure, but they are not uploaded as a GitHub Actions artifact. Consider adding a separate step with if: failure() to upload the backend.log file as an artifact, similar to how generated types are uploaded on lines 160-168. This would preserve logs even if the console output is truncated and make debugging easier. The step should use actions/upload-artifact@v4 with the backend.log path and should be added after this "Start FastAPI backend" step.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fixed 30-second sleep always waits the full duration even if the backend becomes ready sooner. Consider using a polling loop instead that checks the backend health every few seconds and breaks early when ready. This would make the workflow faster when the backend starts quickly while still handling slow starts. The current approach guarantees a minimum 30-second delay regardless of actual startup time.