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
295 lines
10 KiB
YAML
295 lines
10 KiB
YAML
name: Release - Northern Thailand Ping River Monitor
|
||
|
||
on:
|
||
push:
|
||
tags:
|
||
- "v*.*.*"
|
||
workflow_dispatch:
|
||
inputs:
|
||
version:
|
||
description: "Release version (e.g., v3.1.3)"
|
||
required: true
|
||
type: string
|
||
|
||
env:
|
||
PYTHON_VERSION: "3.11"
|
||
REGISTRY: git.b4l.co.th
|
||
IMAGE_NAME: b4l/northern-thailand-ping-river-monitor
|
||
# GitHub token for better rate limits and authentication
|
||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||
|
||
jobs:
|
||
# Create release
|
||
create-release:
|
||
name: Create Release
|
||
runs-on: ubuntu-latest
|
||
outputs:
|
||
version: ${{ steps.version.outputs.version }}
|
||
|
||
steps:
|
||
- name: Checkout code
|
||
uses: actions/checkout@v4
|
||
with:
|
||
token: ${{ secrets.GITEA_TOKEN }}
|
||
fetch-depth: 0
|
||
|
||
- name: Get version
|
||
id: version
|
||
run: |
|
||
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
||
echo "version=${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT
|
||
else
|
||
echo "version=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
|
||
fi
|
||
|
||
- name: Generate changelog
|
||
id: changelog
|
||
run: |
|
||
# Generate changelog from git commits
|
||
echo "## Changes" > 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 "## Docker Images" >> CHANGELOG.md
|
||
echo "- \`${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.version }}\`" >> CHANGELOG.md
|
||
echo "- \`${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest\`" >> CHANGELOG.md
|
||
|
||
- name: Create Release
|
||
uses: actions/create-release@v1
|
||
env:
|
||
GITHUB_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||
with:
|
||
tag_name: ${{ steps.version.outputs.version }}
|
||
release_name: Northern Thailand Ping River Monitor ${{ steps.version.outputs.version }}
|
||
body_path: CHANGELOG.md
|
||
draft: false
|
||
prerelease: false
|
||
|
||
# Build and test for release
|
||
test-release:
|
||
name: Test Release Build
|
||
runs-on: ubuntu-latest
|
||
needs: create-release
|
||
strategy:
|
||
matrix:
|
||
python-version: ["3.9", "3.10", "3.11", "3.12"]
|
||
|
||
steps:
|
||
- name: Checkout code
|
||
uses: actions/checkout@v4
|
||
with:
|
||
token: ${{ secrets.GITEA_TOKEN }}
|
||
|
||
- name: Set up Python ${{ matrix.python-version }}
|
||
uses: actions/setup-python@v4
|
||
with:
|
||
python-version: ${{ matrix.python-version }}
|
||
|
||
- name: Install dependencies
|
||
run: |
|
||
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-dev.txt
|
||
|
||
- name: Run full test suite
|
||
run: |
|
||
python tests/test_integration.py
|
||
python tests/test_station_management.py
|
||
python run.py --test
|
||
|
||
- name: Build Python package
|
||
run: |
|
||
pip install --root-user-action=ignore build
|
||
python -m build
|
||
|
||
- name: Upload Python package
|
||
uses: actions/upload-artifact@v3
|
||
with:
|
||
name: python-package-${{ matrix.python-version }}
|
||
path: dist/
|
||
|
||
# Build release Docker images
|
||
build-release:
|
||
name: Build Release Images
|
||
runs-on: ubuntu-latest
|
||
needs: [create-release, test-release]
|
||
|
||
steps:
|
||
- name: Checkout code
|
||
uses: actions/checkout@v4
|
||
with:
|
||
token: ${{ secrets.GITEA_TOKEN }}
|
||
|
||
- name: Set up Docker Buildx
|
||
uses: docker/setup-buildx-action@v3
|
||
|
||
- 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: Build and push release images
|
||
uses: docker/build-push-action@v5
|
||
with:
|
||
context: .
|
||
platforms: linux/amd64,linux/arm64
|
||
push: true
|
||
tags: |
|
||
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.create-release.outputs.version }}
|
||
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
|
||
labels: |
|
||
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.version=${{ needs.create-release.outputs.version }}
|
||
org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}
|
||
org.opencontainers.image.revision=${{ github.sha }}
|
||
cache-from: type=gha
|
||
cache-to: type=gha,mode=max
|
||
env:
|
||
GITHUB_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||
|
||
# Security scan for release
|
||
security-scan:
|
||
name: Security Scan
|
||
runs-on: ubuntu-latest
|
||
needs: build-release
|
||
|
||
steps:
|
||
- name: Checkout code
|
||
uses: actions/checkout@v4
|
||
with:
|
||
token: ${{ secrets.GITEA_TOKEN}}
|
||
|
||
# Test release deployment locally
|
||
deploy-release:
|
||
name: Test Release Deployment
|
||
runs-on: ubuntu-latest
|
||
needs: [create-release, build-release, security-scan]
|
||
environment:
|
||
name: testing
|
||
url: http://localhost:8080
|
||
|
||
steps:
|
||
- name: Checkout code
|
||
uses: actions/checkout@v4
|
||
with:
|
||
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..."
|
||
|
||
# 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:
|
||
name: Notify Release
|
||
runs-on: ubuntu-latest
|
||
needs: [create-release, deploy-release]
|
||
if: always()
|
||
|
||
steps:
|
||
- name: Notify success
|
||
if: needs.deploy-release.result == 'success'
|
||
run: |
|
||
echo "🎉 Release ${{ needs.create-release.outputs.version }} tested successfully!"
|
||
echo "🧪 Local Test: Passed all health checks"
|
||
echo "<22> GDocker Image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.create-release.outputs.version }}"
|
||
echo "✅ Ready for production deployment"
|
||
|
||
# Add notification to Slack, Discord, email, etc.
|
||
# 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!"}' \
|
||
# ${{ secrets.SLACK_WEBHOOK_URL }}
|
||
|
||
- name: Notify failure
|
||
if: needs.deploy-release.result == 'failure'
|
||
run: |
|
||
echo "❌ Release ${{ needs.create-release.outputs.version }} testing failed!"
|
||
echo "Please check the logs and fix issues before production deployment."
|
||
|
||
# Add failure notification
|
||
# curl -X POST -H 'Content-type: application/json' \
|
||
# --data '{"text":"❌ Northern Thailand Ping River Monitor ${{ needs.create-release.outputs.version }} testing failed!"}' \
|
||
# ${{ secrets.SLACK_WEBHOOK_URL }}
|