3 Commits

Author SHA1 Message Date
6141140beb 🔧 Improve health check robustness and timing
Some checks failed
Release - Northern Thailand Ping River Monitor / Create Release (push) Successful in 5s
Security & Dependency Updates / Dependency Security Scan (push) Successful in 26s
Security & Dependency Updates / License Compliance (push) Successful in 11s
Security & Dependency Updates / Check for Dependency Updates (push) Successful in 19s
Security & Dependency Updates / Security Summary (push) Has been cancelled
Security & Dependency Updates / Code Quality Metrics (push) Has been cancelled
Release - Northern Thailand Ping River Monitor / Test Release Build (3.11) (push) Has been cancelled
Release - Northern Thailand Ping River Monitor / Test Release Build (3.12) (push) Has been cancelled
Release - Northern Thailand Ping River Monitor / Test Release Build (3.9) (push) Has been cancelled
Release - Northern Thailand Ping River Monitor / Build Release Images (push) Has been cancelled
Release - Northern Thailand Ping River Monitor / Security Scan (push) Has been cancelled
Release - Northern Thailand Ping River Monitor / Test Release Deployment (push) Has been cancelled
Release - Northern Thailand Ping River Monitor / Notify Release (push) Has been cancelled
Release - Northern Thailand Ping River Monitor / Test Release Build (3.10) (push) Has been cancelled
🕐 Enhanced Timing:
- Increase attempts from 12 to 15
- Increase wait time from 10 to 15 seconds between attempts
- Add longer curl timeouts (10s max, 5s connect)

🔍 Better Debugging:
- More verbose health check logging
- Show container status on each failed attempt
- Clearer success/failure messages
- Track attempt progress (X/15)

🌐 Improved Curl Options:
- --max-time 10: Overall timeout
- --connect-timeout 5: Connection timeout
- -s: Silent mode (less noise)
- -f: Fail on HTTP errors

🎯 Addresses Race Condition:
- Container shows as healthy but curl fails immediately
- Longer waits allow application full startup
- Better visibility into what's happening during checks

 Should resolve timing issues with container startup
2025-08-13 13:34:44 +07:00
c62ee5f699 🔧 Fix health checks: Use IPv4 address + Add debugging
Some checks failed
Release - Northern Thailand Ping River Monitor / Create Release (push) Successful in 6s
Security & Dependency Updates / License Compliance (push) Successful in 16s
Release - Northern Thailand Ping River Monitor / Test Release Build (3.12) (push) Successful in 22s
Release - Northern Thailand Ping River Monitor / Test Release Build (3.9) (push) Successful in 24s
Security & Dependency Updates / Dependency Security Scan (push) Successful in 32s
Security & Dependency Updates / Check for Dependency Updates (push) Successful in 27s
Security & Dependency Updates / Code Quality Metrics (push) Successful in 26s
Release - Northern Thailand Ping River Monitor / Test Release Build (3.10) (push) Successful in 23s
Release - Northern Thailand Ping River Monitor / Test Release Build (3.11) (push) Successful in 19s
Security & Dependency Updates / Security Summary (push) Successful in 8s
Release - Northern Thailand Ping River Monitor / Build Release Images (push) Successful in 7m46s
Release - Northern Thailand Ping River Monitor / Security Scan (push) Successful in 4s
Release - Northern Thailand Ping River Monitor / Test Release Deployment (push) Failing after 3m24s
Release - Northern Thailand Ping River Monitor / Notify Release (push) Successful in 1s
🌐 Network Fix:
- Change localhost to 127.0.0.1 for all health check URLs
- Prevents IPv6 resolution issues in CI environment
- Ensures consistent IPv4 connectivity to container

🔍 Debugging Improvements:
- Check if container is running with docker ps
- Show recent container logs before health checks
- Better troubleshooting information for failures

📋 Updated Endpoints:
- http://127.0.0.1:8080/health
- http://127.0.0.1:8080/docs
- http://127.0.0.1:8080/stations
- http://127.0.0.1:8080/metrics

 Should resolve curl connection failures to localhost
2025-08-13 12:16:13 +07:00
cd59236473 🔧 Fix health checks: Use IPv4 address + Add debugging
🌐 Network Fix:
- Change localhost to 127.0.0.1 for all health check URLs
- Prevents IPv6 resolution issues in CI environment
- Ensures consistent IPv4 connectivity to container

🔍 Debugging Improvements:
- Check if container is running with docker ps
- Show recent container logs before health checks
- Better troubleshooting information for failures

📋 Updated Endpoints:
- http://127.0.0.1:8080/health
- http://127.0.0.1:8080/docs
- http://127.0.0.1:8080/stations
- http://127.0.0.1:8080/metrics

 Should resolve curl connection failures to localhost
2025-08-13 12:15:36 +07:00

View File

@@ -3,16 +3,16 @@ name: Release - Northern Thailand Ping River Monitor
on: on:
push: push:
tags: tags:
- 'v*.*.*' - "v*.*.*"
workflow_dispatch: workflow_dispatch:
inputs: inputs:
version: version:
description: 'Release version (e.g., v3.1.3)' description: "Release version (e.g., v3.1.3)"
required: true required: true
type: string type: string
env: env:
PYTHON_VERSION: '3.11' PYTHON_VERSION: "3.11"
REGISTRY: git.b4l.co.th REGISTRY: git.b4l.co.th
IMAGE_NAME: b4l/northern-thailand-ping-river-monitor IMAGE_NAME: b4l/northern-thailand-ping-river-monitor
# GitHub token for better rate limits and authentication # GitHub token for better rate limits and authentication
@@ -25,44 +25,44 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
outputs: outputs:
version: ${{ steps.version.outputs.version }} version: ${{ steps.version.outputs.version }}
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
token: ${{ secrets.GITEA_TOKEN }} token: ${{ secrets.GITEA_TOKEN }}
fetch-depth: 0 fetch-depth: 0
- name: Get version - name: Get version
id: version id: version
run: | run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
echo "version=${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT echo "version=${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT
else else
echo "version=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT echo "version=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
fi fi
- name: Generate changelog - name: Generate changelog
id: changelog id: changelog
run: | run: |
# Generate changelog from git commits # Generate changelog from git commits
echo "## Changes" > CHANGELOG.md echo "## Changes" > CHANGELOG.md
git log --pretty=format:"- %s" $(git describe --tags --abbrev=0 HEAD^)..HEAD >> CHANGELOG.md || echo "- Initial release" >> CHANGELOG.md git log --pretty=format:"- %s" $(git describe --tags --abbrev=0 HEAD^)..HEAD >> CHANGELOG.md || echo "- Initial release" >> CHANGELOG.md
echo "" >> CHANGELOG.md echo "" >> CHANGELOG.md
echo "## Docker Images" >> CHANGELOG.md echo "## Docker Images" >> CHANGELOG.md
echo "- \`${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.version }}\`" >> CHANGELOG.md echo "- \`${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.version }}\`" >> CHANGELOG.md
echo "- \`${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest\`" >> CHANGELOG.md echo "- \`${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest\`" >> CHANGELOG.md
- name: Create Release - name: Create Release
uses: actions/create-release@v1 uses: actions/create-release@v1
env: env:
GITHUB_TOKEN: ${{ secrets.GITEA_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITEA_TOKEN }}
with: with:
tag_name: ${{ steps.version.outputs.version }} tag_name: ${{ steps.version.outputs.version }}
release_name: Northern Thailand Ping River Monitor ${{ steps.version.outputs.version }} release_name: Northern Thailand Ping River Monitor ${{ steps.version.outputs.version }}
body_path: CHANGELOG.md body_path: CHANGELOG.md
draft: false draft: false
prerelease: false prerelease: false
# Build and test for release # Build and test for release
test-release: test-release:
@@ -71,97 +71,95 @@ jobs:
needs: create-release needs: create-release
strategy: strategy:
matrix: matrix:
python-version: ['3.9', '3.10', '3.11', '3.12'] python-version: ["3.9", "3.10", "3.11", "3.12"]
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
token: ${{ secrets.GITEA_TOKEN }} token: ${{ secrets.GITEA_TOKEN }}
- name: Set up Python ${{ matrix.python-version }} - name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4 uses: actions/setup-python@v4
with: with:
python-version: ${{ matrix.python-version }} python-version: ${{ matrix.python-version }}
- name: Install dependencies - name: Install dependencies
run: | run: |
python -m pip install --upgrade pip --root-user-action=ignore python -m pip install --upgrade pip --root-user-action=ignore
pip install --root-user-action=ignore -r requirements.txt pip install --root-user-action=ignore -r requirements.txt
pip install --root-user-action=ignore -r requirements-dev.txt pip install --root-user-action=ignore -r requirements-dev.txt
- name: Run full test suite - name: Run full test suite
run: | run: |
python tests/test_integration.py python tests/test_integration.py
python tests/test_station_management.py python tests/test_station_management.py
python run.py --test python run.py --test
- name: Build Python package - name: Build Python package
run: | run: |
pip install --root-user-action=ignore build pip install --root-user-action=ignore build
python -m build python -m build
- name: Upload Python package - name: Upload Python package
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
with: with:
name: python-package-${{ matrix.python-version }} name: python-package-${{ matrix.python-version }}
path: dist/ path: dist/
# Build release Docker images # Build release Docker images
build-release: build-release:
name: Build Release Images name: Build Release Images
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: [create-release, test-release] needs: [create-release, test-release]
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
token: ${{ secrets.GITEA_TOKEN }} token: ${{ secrets.GITEA_TOKEN }}
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v3
- name: Log in to Container Registry - name: Log in to Container Registry
uses: docker/login-action@v3 uses: docker/login-action@v3
with: with:
registry: ${{ env.REGISTRY }} registry: ${{ env.REGISTRY }}
username: ${{ vars.WORKER_USERNAME}} username: ${{ vars.WORKER_USERNAME}}
password: ${{ secrets.CI_BOT_TOKEN }} password: ${{ secrets.CI_BOT_TOKEN }}
- name: Build and push release images - name: Build and push release images
uses: docker/build-push-action@v5 uses: docker/build-push-action@v5
with: with:
context: . context: .
platforms: linux/amd64,linux/arm64 platforms: linux/amd64,linux/arm64
push: true push: true
tags: | tags: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.create-release.outputs.version }} ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.create-release.outputs.version }}
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
labels: | labels: |
org.opencontainers.image.title=Northern Thailand Ping River Monitor org.opencontainers.image.title=Northern Thailand Ping River Monitor
org.opencontainers.image.description=Real-time water level monitoring for Ping River Basin org.opencontainers.image.description=Real-time water level monitoring for Ping River Basin
org.opencontainers.image.version=${{ needs.create-release.outputs.version }} org.opencontainers.image.version=${{ needs.create-release.outputs.version }}
org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }} org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}
org.opencontainers.image.revision=${{ github.sha }} org.opencontainers.image.revision=${{ github.sha }}
cache-from: type=gha cache-from: type=gha
cache-to: type=gha,mode=max cache-to: type=gha,mode=max
env: env:
GITHUB_TOKEN: ${{ secrets.GITEA_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITEA_TOKEN }}
# Security scan for release # Security scan for release
security-scan: security-scan:
name: Security Scan name: Security Scan
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: build-release needs: build-release
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
token: ${{ secrets.GITEA_TOKEN}}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
token: ${{ secrets.GITEA_TOKEN}}
# Test release deployment locally # Test release deployment locally
deploy-release: deploy-release:
@@ -171,85 +169,97 @@ jobs:
environment: environment:
name: testing name: testing
url: http://localhost:8080 url: http://localhost:8080
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
token: ${{ secrets.GITEA_TOKEN }} token: ${{ secrets.GITEA_TOKEN }}
- name: Log in to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ vars.WORKER_USERNAME}}
password: ${{ secrets.CI_BOT_TOKEN }}
- name: Deploy to production (Local Test)
run: |
echo "🚀 Testing ${{ needs.create-release.outputs.version }} deployment locally..."
# Pull the built image
docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.create-release.outputs.version }}
# Stop any existing containers
docker stop ping-river-monitor-test || true
docker rm ping-river-monitor-test || true
# Start the container for testing
docker run -d \
--name ping-river-monitor-test \
-p 8080:8000 \
-e LOG_LEVEL=INFO \
-e DB_TYPE=sqlite \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.create-release.outputs.version }}
echo "✅ Container started for testing"
- name: Health check after deployment
run: |
echo "⏳ Waiting for application to start..."
sleep 30
echo "🔍 Running health checks against local container..."
# Wait for the application to be ready
for i in {1..12}; do
if curl -f http://localhost:8080/health; then
echo "✅ Health endpoint responding"
break
else
echo "⏳ Waiting for health endpoint... (attempt $i/12)"
sleep 10
fi
done
# Test API endpoints
echo "🧪 Testing API endpoints..."
curl -f http://localhost:8080/health || exit 1
curl -f http://localhost:8080/docs || exit 1
curl -f http://localhost:8080/stations || exit 1
curl -f http://localhost:8080/metrics || exit 1
echo "✅ All health checks passed!"
- name: Container logs and cleanup
if: always()
run: |
echo "📋 Container logs:"
docker logs ping-river-monitor-test || true
echo "🧹 Cleaning up test container..."
docker stop ping-river-monitor-test || true
docker rm ping-river-monitor-test || true
echo "📊 Deployment Test Summary:"
echo "Version: ${{ needs.create-release.outputs.version }}"
echo "Image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.create-release.outputs.version }}"
echo "Status: Container tested successfully"
echo "Ready for production deployment"
- name: Log in to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ vars.WORKER_USERNAME}}
password: ${{ secrets.CI_BOT_TOKEN }}
- name: Deploy to production (Local Test)
run: |
echo "🚀 Testing ${{ needs.create-release.outputs.version }} deployment locally..."
# Pull the built image
docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.create-release.outputs.version }}
# Stop any existing containers
docker stop ping-river-monitor-test || true
docker rm ping-river-monitor-test || true
# Start the container for testing
docker run -d \
--name ping-river-monitor-test \
-p 8080:8000 \
-e LOG_LEVEL=INFO \
-e DB_TYPE=sqlite \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.create-release.outputs.version }}
echo "✅ Container started for testing"
- name: Health check after deployment
run: |
echo "⏳ Waiting for application to start..."
sleep 30
echo "🔍 Running health checks against local container..."
# Check if container is running
docker ps | grep ping-river-monitor-test || echo "⚠️ Container not found in docker ps"
# Check container logs for any startup issues
echo "📋 Recent container logs:"
docker logs --tail 10 ping-river-monitor-test || true
# Wait for the application to be ready with more robust checking
echo "🔍 Testing application readiness..."
for i in {1..15}; do
echo "⏳ Attempt $i/15: Testing health endpoint..."
# Use curl with more verbose output and longer timeout
if curl -f -s --max-time 10 --connect-timeout 5 http://127.0.0.1:8080/health; then
echo "✅ Health endpoint responding successfully!"
break
else
echo "❌ Health check failed, waiting 15 seconds..."
# Show what's happening with the container
echo "Container status:"
docker ps | grep ping-river-monitor-test || echo "Container not found"
sleep 15
fi
done
# Test API endpoints
echo "🧪 Testing API endpoints..."
curl -f http://127.0.0.1:8080/health || exit 1
curl -f http://127.0.0.1:8080/docs || exit 1
curl -f http://127.0.0.1:8080/stations || exit 1
curl -f http://127.0.0.1:8080/metrics || exit 1
echo "✅ All health checks passed!"
- name: Container logs and cleanup
if: always()
run: |
echo "📋 Container logs:"
docker logs ping-river-monitor-test || true
echo "🧹 Cleaning up test container..."
docker stop ping-river-monitor-test || true
docker rm ping-river-monitor-test || true
echo "📊 Deployment Test Summary:"
echo "Version: ${{ needs.create-release.outputs.version }}"
echo "Image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.create-release.outputs.version }}"
echo "Status: Container tested successfully"
echo "Ready for production deployment"
# Notify stakeholders # Notify stakeholders
notify: notify:
@@ -257,28 +267,28 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: [create-release, deploy-release] needs: [create-release, deploy-release]
if: always() if: always()
steps: steps:
- name: Notify success - name: Notify success
if: needs.deploy-release.result == 'success' if: needs.deploy-release.result == 'success'
run: | run: |
echo "🎉 Release ${{ needs.create-release.outputs.version }} tested successfully!" echo "🎉 Release ${{ needs.create-release.outputs.version }} tested successfully!"
echo "🧪 Local Test: Passed all health checks" echo "🧪 Local Test: Passed all health checks"
echo "<22> GDocker Image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.create-release.outputs.version }}" echo "<22> GDocker Image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.create-release.outputs.version }}"
echo "✅ Ready for production deployment" echo "✅ Ready for production deployment"
# Add notification to Slack, Discord, email, etc. # Add notification to Slack, Discord, email, etc.
# curl -X POST -H 'Content-type: application/json' \ # curl -X POST -H 'Content-type: application/json' \
# --data '{"text":"🎉 Northern Thailand Ping River Monitor ${{ needs.create-release.outputs.version }} tested and ready for deployment!"}' \ # --data '{"text":"🎉 Northern Thailand Ping River Monitor ${{ needs.create-release.outputs.version }} tested and ready for deployment!"}' \
# ${{ secrets.SLACK_WEBHOOK_URL }} # ${{ secrets.SLACK_WEBHOOK_URL }}
- name: Notify failure - name: Notify failure
if: needs.deploy-release.result == 'failure' if: needs.deploy-release.result == 'failure'
run: | run: |
echo "❌ Release ${{ needs.create-release.outputs.version }} testing failed!" echo "❌ Release ${{ needs.create-release.outputs.version }} testing failed!"
echo "Please check the logs and fix issues before production deployment." echo "Please check the logs and fix issues before production deployment."
# Add failure notification # Add failure notification
# curl -X POST -H 'Content-type: application/json' \ # curl -X POST -H 'Content-type: application/json' \
# --data '{"text":"❌ Northern Thailand Ping River Monitor ${{ needs.create-release.outputs.version }} testing failed!"}' \ # --data '{"text":"❌ Northern Thailand Ping River Monitor ${{ needs.create-release.outputs.version }} testing failed!"}' \
# ${{ secrets.SLACK_WEBHOOK_URL }} # ${{ secrets.SLACK_WEBHOOK_URL }}