Compare commits
26 Commits
Author | SHA1 | Date | |
---|---|---|---|
6141140beb | |||
c62ee5f699 | |||
cd59236473 | |||
18f77530ec | |||
f21d05f404 | |||
ff447292f0 | |||
da4545c6d8 | |||
e0ff8c89fb | |||
5579637995 | |||
1816b6e14a | |||
8dedc9303b | |||
94c6db9b72 | |||
0afb57789b | |||
02a0f479dc | |||
841a5a492c | |||
17a716fcd0 | |||
7c04871fdd | |||
af53f68d2c | |||
985f9754c4 | |||
4ed5f2ccad | |||
123ec13896 | |||
4a30af60e8 | |||
e5d5284ee3 | |||
cd74cd6d10 | |||
9c6fedc149 | |||
40aef686af |
@@ -28,6 +28,8 @@ jobs:
|
||||
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
|
||||
@@ -98,6 +100,8 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ secrets.GITEA_TOKEN }}
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
@@ -134,6 +138,8 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ secrets.GITEA_TOKEN }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
@@ -193,6 +199,8 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ secrets.GITEA_TOKEN }}
|
||||
|
||||
- name: Wait for VictoriaMetrics
|
||||
run: |
|
||||
@@ -244,6 +252,8 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ secrets.GITEA_TOKEN }}
|
||||
|
||||
- name: Deploy to staging
|
||||
run: |
|
||||
@@ -269,6 +279,8 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ secrets.GITEA_TOKEN }}
|
||||
|
||||
- name: Deploy to production
|
||||
run: |
|
||||
@@ -296,6 +308,8 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ secrets.GITEA_TOKEN }}
|
||||
|
||||
- name: Install Apache Bench
|
||||
run: |
|
||||
|
@@ -27,6 +27,8 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ secrets.GITEA_TOKEN }}
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
@@ -127,6 +129,8 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ secrets.GITEA_TOKEN }}
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
@@ -224,6 +228,8 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ secrets.GITEA_TOKEN }}
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
@@ -248,8 +254,8 @@ jobs:
|
||||
project = 'Northern Thailand Ping River Monitor'
|
||||
copyright = '2025, Ping River Monitor Team'
|
||||
author = 'Ping River Monitor Team'
|
||||
version = '3.1.1'
|
||||
release = '3.1.1'
|
||||
version = '3.1.3'
|
||||
release = '3.1.3'
|
||||
|
||||
extensions = [
|
||||
'sphinx.ext.autodoc',
|
||||
|
@@ -3,16 +3,16 @@ name: Release - Northern Thailand Ping River Monitor
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*.*.*'
|
||||
- "v*.*.*"
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: 'Release version (e.g., v3.1.1)'
|
||||
description: "Release version (e.g., v3.1.3)"
|
||||
required: true
|
||||
type: string
|
||||
|
||||
env:
|
||||
PYTHON_VERSION: '3.11'
|
||||
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
|
||||
@@ -25,43 +25,44 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
version: ${{ steps.version.outputs.version }}
|
||||
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
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
|
||||
- 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:
|
||||
@@ -70,227 +71,224 @@ jobs:
|
||||
needs: create-release
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ['3.9', '3.10', '3.11', '3.12']
|
||||
|
||||
python-version: ["3.9", "3.10", "3.11", "3.12"]
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- 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/
|
||||
- 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
|
||||
|
||||
- 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: ${{ github.actor }}
|
||||
password: ${{ secrets.GITEA_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.GITHUB_TOKEN }}
|
||||
- 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
|
||||
|
||||
- name: Run Trivy vulnerability scanner
|
||||
uses: aquasecurity/trivy-action@master
|
||||
with:
|
||||
image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.create-release.outputs.version }}
|
||||
format: 'sarif'
|
||||
output: 'trivy-results.sarif'
|
||||
github-token: ${{ secrets.GH_TOKEN }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
|
||||
- name: Upload Trivy scan results
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: security-scan-results
|
||||
path: trivy-results.sarif
|
||||
|
||||
# Deploy release to production
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ secrets.GITEA_TOKEN}}
|
||||
|
||||
# Test release deployment locally
|
||||
deploy-release:
|
||||
name: Deploy Release
|
||||
name: Test Release Deployment
|
||||
runs-on: ubuntu-latest
|
||||
needs: [create-release, build-release, security-scan]
|
||||
environment:
|
||||
name: production
|
||||
url: https://ping-river-monitor.b4l.co.th
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Deploy to production
|
||||
run: |
|
||||
echo "🚀 Deploying ${{ needs.create-release.outputs.version }} to production..."
|
||||
|
||||
# Example deployment commands (customize for your infrastructure)
|
||||
# kubectl set image deployment/ping-river-monitor app=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.create-release.outputs.version }}
|
||||
# docker-compose pull && docker-compose up -d
|
||||
# Or webhook call to your deployment system
|
||||
|
||||
echo "✅ Deployment initiated"
|
||||
|
||||
- name: Health check after deployment
|
||||
run: |
|
||||
echo "⏳ Waiting for deployment to stabilize..."
|
||||
sleep 60
|
||||
|
||||
echo "🔍 Running health checks..."
|
||||
curl -f https://ping-river-monitor.b4l.co.th/health
|
||||
curl -f https://ping-river-monitor.b4l.co.th/stations
|
||||
|
||||
echo "✅ Health checks passed!"
|
||||
|
||||
- name: Update deployment status
|
||||
run: |
|
||||
echo "📊 Deployment Summary:"
|
||||
echo "Version: ${{ needs.create-release.outputs.version }}"
|
||||
echo "Image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.create-release.outputs.version }}"
|
||||
echo "URL: https://ping-river-monitor.b4l.co.th"
|
||||
echo "Grafana: https://grafana.ping-river-monitor.b4l.co.th"
|
||||
echo "API Docs: https://ping-river-monitor.b4l.co.th/docs"
|
||||
name: testing
|
||||
url: http://localhost:8080
|
||||
|
||||
# Post-release validation
|
||||
validate-release:
|
||||
name: Validate Release
|
||||
runs-on: ubuntu-latest
|
||||
needs: deploy-release
|
||||
|
||||
steps:
|
||||
- name: Comprehensive API test
|
||||
run: |
|
||||
echo "🧪 Running comprehensive API tests..."
|
||||
|
||||
# Test all major endpoints
|
||||
curl -f https://ping-river-monitor.b4l.co.th/health
|
||||
curl -f https://ping-river-monitor.b4l.co.th/metrics
|
||||
curl -f https://ping-river-monitor.b4l.co.th/stations
|
||||
curl -f https://ping-river-monitor.b4l.co.th/measurements/latest?limit=5
|
||||
curl -f https://ping-river-monitor.b4l.co.th/scraping/status
|
||||
|
||||
echo "✅ All API endpoints responding correctly"
|
||||
|
||||
- name: Performance validation
|
||||
run: |
|
||||
echo "⚡ Running performance validation..."
|
||||
|
||||
# Install Apache Bench
|
||||
sudo apt-get update && sudo apt-get install -y apache2-utils
|
||||
|
||||
# Test response times
|
||||
ab -n 10 -c 2 https://ping-river-monitor.b4l.co.th/health
|
||||
ab -n 10 -c 2 https://ping-river-monitor.b4l.co.th/stations
|
||||
|
||||
echo "✅ Performance validation completed"
|
||||
|
||||
- name: Data validation
|
||||
run: |
|
||||
echo "📊 Validating data collection..."
|
||||
|
||||
# Check if recent data is available
|
||||
response=$(curl -s https://ping-river-monitor.b4l.co.th/measurements/latest?limit=1)
|
||||
echo "Latest measurement: $response"
|
||||
|
||||
# Validate data structure (basic check)
|
||||
if echo "$response" | grep -q "water_level"; then
|
||||
echo "✅ Data structure validation passed"
|
||||
else
|
||||
echo "❌ Data structure validation failed"
|
||||
exit 1
|
||||
fi
|
||||
- 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, validate-release]
|
||||
needs: [create-release, deploy-release]
|
||||
if: always()
|
||||
|
||||
|
||||
steps:
|
||||
- name: Notify success
|
||||
if: needs.validate-release.result == 'success'
|
||||
run: |
|
||||
echo "🎉 Release ${{ needs.create-release.outputs.version }} deployed successfully!"
|
||||
echo "🌐 Production URL: https://ping-river-monitor.b4l.co.th"
|
||||
echo "📊 Grafana: https://grafana.ping-river-monitor.b4l.co.th"
|
||||
echo "📚 API Docs: https://ping-river-monitor.b4l.co.th/docs"
|
||||
|
||||
# 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 }} deployed successfully!"}' \
|
||||
# ${{ secrets.SLACK_WEBHOOK_URL }}
|
||||
|
||||
- name: Notify failure
|
||||
if: needs.validate-release.result == 'failure'
|
||||
run: |
|
||||
echo "❌ Release ${{ needs.create-release.outputs.version }} deployment failed!"
|
||||
echo "Please check the logs and take corrective action."
|
||||
|
||||
# Add failure notification
|
||||
# curl -X POST -H 'Content-type: application/json' \
|
||||
# --data '{"text":"❌ Northern Thailand Ping River Monitor ${{ needs.create-release.outputs.version }} deployment failed!"}' \
|
||||
# ${{ secrets.SLACK_WEBHOOK_URL }}
|
||||
- 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 "<EFBFBD> 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 }}
|
||||
|
@@ -25,6 +25,8 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ secrets.GITEA_TOKEN }}
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
@@ -61,16 +63,16 @@ jobs:
|
||||
|
||||
- name: Check for critical vulnerabilities
|
||||
run: |
|
||||
echo "🔍 Checking for critical vulnerabilities..."
|
||||
echo "Checking for critical vulnerabilities..."
|
||||
|
||||
# Check Safety results
|
||||
if [ -f safety-report.json ]; then
|
||||
critical_count=$(jq '.vulnerabilities | length' safety-report.json 2>/dev/null || echo "0")
|
||||
if [ "$critical_count" -gt 0 ]; then
|
||||
echo "⚠️ Found $critical_count dependency vulnerabilities"
|
||||
echo "Found $critical_count dependency vulnerabilities"
|
||||
jq '.vulnerabilities[] | "- \(.package_name) \(.installed_version): \(.vulnerability_id)"' safety-report.json
|
||||
else
|
||||
echo "✅ No dependency vulnerabilities found"
|
||||
echo "No dependency vulnerabilities found"
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -78,86 +80,9 @@ jobs:
|
||||
if [ -f bandit-report.json ]; then
|
||||
high_severity=$(jq '.results[] | select(.issue_severity == "HIGH") | length' bandit-report.json 2>/dev/null | wc -l)
|
||||
if [ "$high_severity" -gt 0 ]; then
|
||||
echo "⚠️ Found $high_severity high-severity security issues"
|
||||
echo "Found $high_severity high-severity security issues"
|
||||
else
|
||||
echo "✅ No high-severity security issues found"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Docker image security scan
|
||||
docker-security-scan:
|
||||
name: Docker Security Scan
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Check GitHub token availability
|
||||
run: |
|
||||
if [ -z "${{ secrets.GH_TOKEN }}" ]; then
|
||||
echo "⚠️ GH_TOKEN not configured. Trivy scans may fail due to rate limits."
|
||||
echo "💡 To fix: Add GH_TOKEN secret in repository settings"
|
||||
else
|
||||
echo "✅ GH_TOKEN is configured"
|
||||
fi
|
||||
|
||||
- name: Build Docker image for scanning
|
||||
run: |
|
||||
docker build -t ping-river-monitor:scan .
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
|
||||
- name: Run Trivy vulnerability scanner
|
||||
uses: aquasecurity/trivy-action@master
|
||||
with:
|
||||
image-ref: "ping-river-monitor:scan"
|
||||
format: "json"
|
||||
output: "trivy-report.json"
|
||||
github-token: ${{ secrets.GH_TOKEN }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
continue-on-error: true
|
||||
|
||||
- name: Run Trivy filesystem scan
|
||||
uses: aquasecurity/trivy-action@master
|
||||
with:
|
||||
scan-type: "fs"
|
||||
scan-ref: "."
|
||||
format: "json"
|
||||
output: "trivy-fs-report.json"
|
||||
github-token: ${{ secrets.GH_TOKEN }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
continue-on-error: true
|
||||
|
||||
- name: Upload Trivy reports
|
||||
uses: actions/upload-artifact@v3
|
||||
if: always()
|
||||
with:
|
||||
name: trivy-reports-${{ github.run_number }}
|
||||
path: |
|
||||
trivy-report.json
|
||||
trivy-fs-report.json
|
||||
|
||||
- name: Check Trivy results
|
||||
run: |
|
||||
echo "🔍 Analyzing Docker security scan results..."
|
||||
|
||||
if [ -f trivy-report.json ]; then
|
||||
critical_vulns=$(jq '.Results[]?.Vulnerabilities[]? | select(.Severity == "CRITICAL") | length' trivy-report.json 2>/dev/null | wc -l)
|
||||
high_vulns=$(jq '.Results[]?.Vulnerabilities[]? | select(.Severity == "HIGH") | length' trivy-report.json 2>/dev/null | wc -l)
|
||||
|
||||
echo "Critical vulnerabilities: $critical_vulns"
|
||||
echo "High vulnerabilities: $high_vulns"
|
||||
|
||||
if [ "$critical_vulns" -gt 0 ]; then
|
||||
echo "❌ Critical vulnerabilities found in Docker image!"
|
||||
exit 1
|
||||
elif [ "$high_vulns" -gt 5 ]; then
|
||||
echo "⚠️ Many high-severity vulnerabilities found"
|
||||
else
|
||||
echo "✅ Docker image security scan passed"
|
||||
echo "No high-severity security issues found"
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -169,6 +94,8 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ secrets.GITEA_TOKEN }}
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
@@ -183,7 +110,7 @@ jobs:
|
||||
|
||||
- name: Check licenses
|
||||
run: |
|
||||
echo "📄 Checking dependency licenses..."
|
||||
echo "Checking dependency licenses..."
|
||||
pip-licenses --format=json --output-file=licenses.json
|
||||
pip-licenses --format=markdown --output-file=licenses.md
|
||||
|
||||
@@ -192,11 +119,11 @@ jobs:
|
||||
|
||||
for license in "${problematic_licenses[@]}"; do
|
||||
if grep -i "$license" licenses.json; then
|
||||
echo "⚠️ Found potentially problematic license: $license"
|
||||
echo "Found potentially problematic license: $license"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "✅ License check completed"
|
||||
echo "License check completed"
|
||||
|
||||
- name: Upload license report
|
||||
uses: actions/upload-artifact@v3
|
||||
@@ -214,6 +141,8 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ secrets.GITEA_TOKEN }}
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
@@ -227,56 +156,15 @@ jobs:
|
||||
|
||||
- name: Check for outdated packages
|
||||
run: |
|
||||
echo "📦 Checking for outdated packages..."
|
||||
echo "Checking for outdated packages..."
|
||||
pip install --root-user-action=ignore -r requirements.txt
|
||||
pip list --outdated --format=json > outdated-packages.json || true
|
||||
|
||||
if [ -s outdated-packages.json ]; then
|
||||
echo "📋 Outdated packages found:"
|
||||
echo "Outdated packages found:"
|
||||
cat outdated-packages.json | jq -r '.[] | "- \(.name): \(.version) -> \(.latest_version)"'
|
||||
else
|
||||
echo "✅ All packages are up to date"
|
||||
fi
|
||||
|
||||
- name: Create dependency update issue
|
||||
if: github.event_name == 'schedule'
|
||||
run: |
|
||||
if [ -s outdated-packages.json ] && [ "$(cat outdated-packages.json)" != "[]" ]; then
|
||||
echo "📝 Creating dependency update issue..."
|
||||
|
||||
# Create issue body
|
||||
cat > issue-body.md << 'EOF'
|
||||
## 📦 Dependency Updates Available
|
||||
|
||||
The following packages have updates available:
|
||||
|
||||
EOF
|
||||
|
||||
cat outdated-packages.json | jq -r '.[] | "- **\(.name)**: \(.version) → \(.latest_version)"' >> issue-body.md
|
||||
|
||||
cat >> issue-body.md << 'EOF'
|
||||
|
||||
## 🔍 Security Impact
|
||||
|
||||
Please review each update for:
|
||||
- Security fixes
|
||||
- Breaking changes
|
||||
- Compatibility issues
|
||||
|
||||
## ✅ Action Items
|
||||
|
||||
- [ ] Review changelog for each package
|
||||
- [ ] Test updates in development environment
|
||||
- [ ] Update requirements.txt
|
||||
- [ ] Run full test suite
|
||||
- [ ] Deploy to staging for validation
|
||||
|
||||
---
|
||||
*This issue was automatically created by the security workflow.*
|
||||
EOF
|
||||
|
||||
echo "Issue body created. In a real implementation, you would create a Gitea issue here."
|
||||
cat issue-body.md
|
||||
echo "All packages are up to date"
|
||||
fi
|
||||
|
||||
- name: Upload dependency reports
|
||||
@@ -285,7 +173,6 @@ jobs:
|
||||
name: dependency-reports-${{ github.run_number }}
|
||||
path: |
|
||||
outdated-packages.json
|
||||
issue-body.md
|
||||
|
||||
# Code quality metrics
|
||||
code-quality:
|
||||
@@ -295,6 +182,8 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ secrets.GITEA_TOKEN }}
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
@@ -309,24 +198,24 @@ jobs:
|
||||
|
||||
- name: Calculate code complexity
|
||||
run: |
|
||||
echo "📊 Calculating code complexity..."
|
||||
echo "Calculating code complexity..."
|
||||
radon cc src/ --json > complexity-report.json
|
||||
radon mi src/ --json > maintainability-report.json
|
||||
|
||||
echo "🔍 Complexity Summary:"
|
||||
echo "Complexity Summary:"
|
||||
radon cc src/ --average
|
||||
|
||||
echo "🔧 Maintainability Summary:"
|
||||
echo "Maintainability Summary:"
|
||||
radon mi src/
|
||||
|
||||
- name: Find dead code
|
||||
run: |
|
||||
echo "🧹 Checking for dead code..."
|
||||
echo "Checking for dead code..."
|
||||
vulture src/ --json > dead-code-report.json || true
|
||||
|
||||
- name: Check for code smells
|
||||
run: |
|
||||
echo "👃 Checking for code smells..."
|
||||
echo "Checking for code smells..."
|
||||
xenon --max-absolute B --max-modules A --max-average A src/ || true
|
||||
|
||||
- name: Upload quality reports
|
||||
@@ -342,7 +231,7 @@ jobs:
|
||||
security-summary:
|
||||
name: Security Summary
|
||||
runs-on: ubuntu-latest
|
||||
needs: [dependency-scan, docker-security-scan, license-check, code-quality]
|
||||
needs: [dependency-scan, license-check, code-quality]
|
||||
if: always()
|
||||
|
||||
steps:
|
||||
@@ -351,51 +240,47 @@ jobs:
|
||||
|
||||
- name: Generate security summary
|
||||
run: |
|
||||
echo "# 🔒 Security Scan Summary" > security-summary.md
|
||||
echo "# Security Scan Summary" > security-summary.md
|
||||
echo "" >> security-summary.md
|
||||
echo "**Scan Date:** $(date -u)" >> security-summary.md
|
||||
echo "**Repository:** ${{ github.repository }}" >> security-summary.md
|
||||
echo "**Commit:** ${{ github.sha }}" >> security-summary.md
|
||||
echo "" >> security-summary.md
|
||||
|
||||
echo "## 📊 Results" >> security-summary.md
|
||||
echo "## Results" >> security-summary.md
|
||||
echo "" >> security-summary.md
|
||||
|
||||
# Dependency scan results
|
||||
if [ -f security-reports-*/safety-report.json ]; then
|
||||
vuln_count=$(jq '.vulnerabilities | length' security-reports-*/safety-report.json 2>/dev/null || echo "0")
|
||||
if [ "$vuln_count" -eq 0 ]; then
|
||||
echo "- ✅ **Dependency Scan**: No vulnerabilities found" >> security-summary.md
|
||||
echo "- Dependency Scan: No vulnerabilities found" >> security-summary.md
|
||||
else
|
||||
echo "- ⚠️ **Dependency Scan**: $vuln_count vulnerabilities found" >> security-summary.md
|
||||
echo "- Dependency Scan: $vuln_count vulnerabilities found" >> security-summary.md
|
||||
fi
|
||||
else
|
||||
echo "- ❓ **Dependency Scan**: Results not available" >> security-summary.md
|
||||
echo "- Dependency Scan: Results not available" >> security-summary.md
|
||||
fi
|
||||
|
||||
# Docker scan results
|
||||
if [ -f trivy-reports-*/trivy-report.json ]; then
|
||||
echo "- ✅ **Docker Scan**: Completed" >> security-summary.md
|
||||
else
|
||||
echo "- ❓ **Docker Scan**: Results not available" >> security-summary.md
|
||||
fi
|
||||
# Docker scan results (removed Trivy)
|
||||
echo "- Docker Scan: Skipped (Trivy removed)" >> security-summary.md
|
||||
|
||||
# License check results
|
||||
if [ -f license-report-*/licenses.json ]; then
|
||||
echo "- ✅ **License Check**: Completed" >> security-summary.md
|
||||
echo "- License Check: Completed" >> security-summary.md
|
||||
else
|
||||
echo "- ❓ **License Check**: Results not available" >> security-summary.md
|
||||
echo "- License Check: Results not available" >> security-summary.md
|
||||
fi
|
||||
|
||||
# Code quality results
|
||||
if [ -f code-quality-reports-*/complexity-report.json ]; then
|
||||
echo "- ✅ **Code Quality**: Analyzed" >> security-summary.md
|
||||
echo "- Code Quality: Analyzed" >> security-summary.md
|
||||
else
|
||||
echo "- ❓ **Code Quality**: Results not available" >> security-summary.md
|
||||
echo "- Code Quality: Results not available" >> security-summary.md
|
||||
fi
|
||||
|
||||
echo "" >> security-summary.md
|
||||
echo "## 🔗 Detailed Reports" >> security-summary.md
|
||||
echo "## Detailed Reports" >> security-summary.md
|
||||
echo "" >> security-summary.md
|
||||
echo "Detailed reports are available in the workflow artifacts." >> security-summary.md
|
||||
|
||||
@@ -405,4 +290,4 @@ jobs:
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: security-summary-${{ github.run_number }}
|
||||
path: security-summary.md
|
||||
path: security-summary.md
|
@@ -259,7 +259,7 @@ make health-check
|
||||
|
||||
**Deployment Date**: ___________
|
||||
**Deployed By**: ___________
|
||||
**Version**: v3.1.1
|
||||
**Version**: v3.1.3
|
||||
**Environment**: ___________
|
||||
|
||||
**Sign-off**:
|
||||
|
11
Dockerfile
11
Dockerfile
@@ -22,26 +22,27 @@ FROM python:3.11-slim
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
|
||||
# Install runtime dependencies
|
||||
# Install runtime dependencies and create user
|
||||
RUN apt-get update && apt-get install -y \
|
||||
wget \
|
||||
curl \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& groupadd -r appuser && useradd -r -g appuser appuser
|
||||
&& groupadd -r appuser && useradd -r -g appuser appuser \
|
||||
&& mkdir -p /home/appuser/.local
|
||||
|
||||
# Copy Python packages from builder stage
|
||||
COPY --from=builder /root/.local /root/.local
|
||||
COPY --from=builder /root/.local /home/appuser/.local
|
||||
|
||||
# Copy application code
|
||||
COPY . .
|
||||
|
||||
# Create logs directory and set permissions
|
||||
RUN mkdir -p logs && chown -R appuser:appuser /app
|
||||
RUN mkdir -p logs && chown -R appuser:appuser /app /home/appuser/.local
|
||||
|
||||
# Set environment variables
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
ENV TZ=Asia/Bangkok
|
||||
ENV PATH=/root/.local/bin:$PATH
|
||||
ENV PATH=/home/appuser/.local/bin:$PATH
|
||||
|
||||
# Switch to non-root user
|
||||
USER appuser
|
||||
|
@@ -222,12 +222,12 @@ Your repository is now equipped with:
|
||||
2. **Configure deployment environments** (staging/production)
|
||||
3. **Set up monitoring dashboards** for workflow metrics
|
||||
4. **Configure notifications** for team collaboration
|
||||
5. **Create your first release** with `git tag v3.1.1`
|
||||
5. **Create your first release** with `git tag v3.1.3`
|
||||
|
||||
Your **Northern Thailand Ping River Monitor** is now ready for professional development and deployment! 🎊
|
||||
|
||||
---
|
||||
|
||||
**Workflow Version**: v3.1.1
|
||||
**Workflow Version**: v3.1.3
|
||||
**Setup Date**: 2025-08-12
|
||||
**Repository**: https://git.b4l.co.th/grabowski/Northern-Thailand-Ping-River-Monitor
|
@@ -2,7 +2,7 @@
|
||||
|
||||
A comprehensive real-time water level monitoring system for the Ping River Basin in Northern Thailand, covering Royal Irrigation Department (RID) stations from Chiang Dao to Nakhon Sawan with advanced data collection, storage, and visualization capabilities.
|
||||
|
||||
[](https://git.b4l.co.th/B4L/Northern-Thailand-Ping-River-Monitor/actions) [](https://git.b4l.co.th/B4L/Northern-Thailand-Ping-River-Monitor/actions) [](https://git.b4l.co.th/B4L/Northern-Thailand-Ping-River-Monitor/actions) [](https://python.org) [](https://fastapi.tiangolo.com) [](https://docker.com) [](LICENSE) [](https://git.b4l.co.th/B4L/Northern-Thailand-Ping-River-Monitor/releases)
|
||||
[](https://git.b4l.co.th/B4L/Northern-Thailand-Ping-River-Monitor/actions) [](https://git.b4l.co.th/B4L/Northern-Thailand-Ping-River-Monitor/actions) [](https://git.b4l.co.th/B4L/Northern-Thailand-Ping-River-Monitor/actions) [](https://python.org) [](https://fastapi.tiangolo.com) [](https://docker.com) [](LICENSE) [](https://git.b4l.co.th/B4L/Northern-Thailand-Ping-River-Monitor/releases)
|
||||
|
||||
## 🌟 Features
|
||||
|
||||
|
@@ -297,6 +297,6 @@ make validate-workflows
|
||||
|
||||
---
|
||||
|
||||
**Workflow Version**: v3.1.1
|
||||
**Workflow Version**: v3.1.3
|
||||
**Last Updated**: 2025-08-12
|
||||
**Maintained By**: Ping River Monitor Team
|
@@ -29,7 +29,7 @@ def main():
|
||||
"FastAPI": generate_badge_url("FastAPI", "0.104%2B", "green"),
|
||||
"Docker": generate_badge_url("Docker", "Ready", "blue"),
|
||||
"License": generate_badge_url("License", "MIT", "green"),
|
||||
"Version": generate_badge_url("Version", "v3.1.1", "blue"),
|
||||
"Version": generate_badge_url("Version", "v3.1.3", "blue"),
|
||||
}
|
||||
|
||||
print("# Status Badges")
|
||||
|
@@ -13,7 +13,7 @@ REM Add all files
|
||||
git add .
|
||||
|
||||
REM Initial commit
|
||||
git commit -m "Initial commit: Northern Thailand Ping River Monitor v3.1.1
|
||||
git commit -m "Initial commit: Northern Thailand Ping River Monitor v3.1.3
|
||||
|
||||
Features:
|
||||
- Real-time water level monitoring for Ping River Basin
|
||||
|
@@ -66,7 +66,7 @@ fi
|
||||
git add .
|
||||
|
||||
# Initial commit
|
||||
git commit -m "Initial commit: Northern Thailand Ping River Monitor v3.1.1
|
||||
git commit -m "Initial commit: Northern Thailand Ping River Monitor v3.1.3
|
||||
|
||||
Features:
|
||||
- Real-time water level monitoring for Ping River Basin
|
||||
|
16
setup.py
16
setup.py
@@ -11,8 +11,18 @@ with open("README.md", "r", encoding="utf-8") as fh:
|
||||
long_description = fh.read()
|
||||
|
||||
# Read requirements
|
||||
with open("requirements.txt", "r", encoding="utf-8") as fh:
|
||||
requirements = [line.strip() for line in fh if line.strip() and not line.startswith("#")]
|
||||
try:
|
||||
with open("requirements.txt", "r", encoding="utf-8") as fh:
|
||||
requirements = [line.strip() for line in fh if line.strip() and not line.startswith("#")]
|
||||
except FileNotFoundError:
|
||||
# Fallback to minimal requirements if file not found
|
||||
requirements = [
|
||||
"requests>=2.31.0",
|
||||
"schedule>=1.2.0",
|
||||
"pandas>=2.1.0",
|
||||
"fastapi>=0.104.0",
|
||||
"uvicorn>=0.24.0",
|
||||
]
|
||||
|
||||
# Extract core requirements (exclude dev dependencies)
|
||||
core_requirements = []
|
||||
@@ -22,7 +32,7 @@ for req in requirements:
|
||||
|
||||
setup(
|
||||
name="northern-thailand-ping-river-monitor",
|
||||
version="3.1.1",
|
||||
version="3.1.3",
|
||||
author="Ping River Monitor Team",
|
||||
author_email="contact@example.com",
|
||||
description="Real-time water level monitoring system for the Ping River Basin in Northern Thailand",
|
||||
|
@@ -6,7 +6,7 @@ A comprehensive real-time water level monitoring system for the Ping River Basin
|
||||
in Northern Thailand, covering Royal Irrigation Department (RID) stations.
|
||||
"""
|
||||
|
||||
__version__ = "3.1.1"
|
||||
__version__ = "3.1.3"
|
||||
__author__ = "Ping River Monitor Team"
|
||||
__description__ = "Northern Thailand Ping River Monitoring System"
|
||||
|
||||
|
@@ -297,7 +297,7 @@ Examples:
|
||||
)
|
||||
|
||||
logger.info("🏔️ Northern Thailand Ping River Monitor starting...")
|
||||
logger.info(f"Version: 3.1.1")
|
||||
logger.info(f"Version: 3.1.3")
|
||||
logger.info(f"Log level: {args.log_level}")
|
||||
|
||||
try:
|
||||
|
@@ -143,7 +143,7 @@ async def lifespan(app: FastAPI):
|
||||
app = FastAPI(
|
||||
title="Northern Thailand Ping River Monitor API",
|
||||
description="Real-time water level monitoring system for Northern Thailand's Ping River Basin stations",
|
||||
version="3.1.1",
|
||||
version="3.1.3",
|
||||
lifespan=lifespan
|
||||
)
|
||||
|
||||
|
@@ -165,7 +165,7 @@ def test_logging():
|
||||
|
||||
def main():
|
||||
"""Run all tests"""
|
||||
print("🧪 Running integration tests for Northern Thailand Ping River Monitor v3.1.1")
|
||||
print("🧪 Running integration tests for Northern Thailand Ping River Monitor v3.1.3")
|
||||
print("=" * 60)
|
||||
|
||||
tests = [
|
||||
|
Reference in New Issue
Block a user