name: Release - Northern Thailand Ping River Monitor on: push: tags: - 'v*.*.*' workflow_dispatch: inputs: version: description: 'Release version (e.g., v3.1.0)' required: true type: string env: PYTHON_VERSION: '3.11' REGISTRY: git.b4l.co.th IMAGE_NAME: b4l/northern-thailand-ping-river-monitor 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: 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 - 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 pip install -r requirements.txt pip install -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 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 # 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' - name: Upload Trivy scan results uses: actions/upload-artifact@v3 with: name: security-scan-results path: trivy-results.sarif # Deploy release to production deploy-release: name: Deploy Release 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" # 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 # Notify stakeholders notify: name: Notify Release runs-on: ubuntu-latest needs: [create-release, validate-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 }}