From bb25c8338761212a9d4f2362987b184a6f346801 Mon Sep 17 00:00:00 2001 From: Zander Kotze Date: Sun, 22 Jun 2025 03:27:43 +0200 Subject: [PATCH] notification and improvements --- .../deployment-notification/action.yml | 180 ++++++++++++++++++ .github/actions/rollback-version/action.yml | 81 ++++++++ .github/actions/version-management/action.yml | 64 ++++++- .github/workflows/NOTIFICATION_SETUP.md | 176 +++++++++++++++++ .github/workflows/develop_workflow.yml | 36 +++- .github/workflows/production_workflow.yml | 44 ++++- .github/workflows/staging_workflow.yml | 36 +++- 7 files changed, 598 insertions(+), 19 deletions(-) create mode 100644 .github/actions/deployment-notification/action.yml create mode 100644 .github/actions/rollback-version/action.yml create mode 100644 .github/workflows/NOTIFICATION_SETUP.md diff --git a/.github/actions/deployment-notification/action.yml b/.github/actions/deployment-notification/action.yml new file mode 100644 index 00000000..e446d1fa --- /dev/null +++ b/.github/actions/deployment-notification/action.yml @@ -0,0 +1,180 @@ +name: "Deployment Notification" +description: "Sends deployment status notifications" + +inputs: + deployment_status: + description: "Status of deployment (success, failure, cancelled)" + required: true + environment: + description: "Environment being deployed to (develop, staging, production)" + required: true + version: + description: "Version being deployed" + required: true + branch: + description: "Branch being deployed from" + required: true + commit_sha: + description: "Commit SHA being deployed" + required: false + default: "${{ github.sha }}" + commit_message: + description: "Commit message" + required: false + default: "${{ github.event.head_commit.message || 'No commit message' }}" + author: + description: "Author of the commit" + required: false + default: "${{ github.actor }}" + pr_number: + description: "Pull request number" + required: false + default: "${{ github.event.pull_request.number || '' }}" + pr_title: + description: "Pull request title" + required: false + default: "${{ github.event.pull_request.title || '' }}" + webhook_url: + description: "Webhook URL for notifications (Slack, Discord, etc.)" + required: false + email_recipients: + description: "Comma-separated list of email recipients" + required: false + +runs: + using: "composite" + steps: + - name: Generate Notification Message + id: generate_message + shell: bash + run: | + status="${{ inputs.deployment_status }}" + environment="${{ inputs.environment }}" + version="${{ inputs.version }}" + branch="${{ inputs.branch }}" + commit_sha="${{ inputs.commit_sha }}" + commit_message="${{ inputs.commit_message }}" + author="${{ inputs.author }}" + pr_number="${{ inputs.pr_number }}" + pr_title="${{ inputs.pr_title }}" + + # Set emoji based on status + case "$status" in + "success") status_emoji="✅" ;; + "failure") status_emoji="❌" ;; + "cancelled") status_emoji="⚠️" ;; + *) status_emoji="ℹ️" ;; + esac + + # Set environment emoji + case "$environment" in + "develop") env_emoji="🔧" ;; + "staging") env_emoji="🚀" ;; + "production") env_emoji="🎯" ;; + *) env_emoji="🌍" ;; + esac + + # Build message + message="" + message+="$status_emoji **Deployment $status**\n" + message+="$env_emoji **Environment:** $environment\n" + message+="📦 **Version:** $version\n" + message+="🌿 **Branch:** $branch\n" + message+="👤 **Author:** $author\n" + + if [[ -n "$pr_number" ]]; then + message+="🔗 **PR:** #$pr_number - $pr_title\n" + fi + + message+="📝 **Commit:** \`${commit_sha:0:8}\`\n" + message+="💬 **Message:** $commit_message\n" + message+="⏰ **Time:** $(date -u +'%Y-%m-%d %H:%M:%S UTC')\n" + + # Add repository link + message+="🔗 **Repository:** https://github.com/${{ github.repository }}\n" + + if [[ -n "$pr_number" ]]; then + message+="🔗 **PR Link:** https://github.com/${{ github.repository }}/pull/$pr_number\n" + fi + + echo "message<> $GITHUB_OUTPUT + echo "$message" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + + echo "Generated notification message" + + - name: Send Webhook Notification + if: inputs.webhook_url != '' + shell: bash + run: | + webhook_url="${{ inputs.webhook_url }}" + message="${{ steps.generate_message.outputs.message }}" + + # Prepare payload + payload=$(cat < "$latest_tag" ]]; then echo "Version in pubspec.yaml ($current_version) is ahead of latest tag ($latest_tag). Proceeding." @@ -133,7 +168,13 @@ runs: sed -i "s/version: .*/version: $new_version/" ${{ inputs.pubspec_path }} git add ${{ inputs.pubspec_path }} git commit -m "Add $version_suffix suffix to version $new_version [skip ci]" - git push origin HEAD:${{ inputs.branch_name }} + + # Try to push, handle conflicts + if ! git push origin HEAD:${{ inputs.branch_name }}; then + echo "Push failed, attempting to resolve version conflict..." + handle_version_conflict + fi + current_version="$new_version" current_version_part="$new_version_part" fi @@ -222,10 +263,15 @@ runs: exit 1 } git remote set-url origin https://x-access-token:${GH_TOKEN}@github.com/${REPO}.git - git push origin HEAD:${{ inputs.branch_name }} || { - echo "::error::Failed to push version bump to ${{ inputs.branch_name }}" - exit 1 - } + + # Try to push, handle conflicts + if ! git push origin HEAD:${{ inputs.branch_name }}; then + echo "Push failed, attempting to resolve version conflict..." + handle_version_conflict + # Re-run version bumping logic with updated version + echo "Re-running version bumping with updated version: $current_version" + exit 1 # This will trigger a retry of the action + fi echo "version_part=$new_version" >> $GITHUB_OUTPUT echo "build_number=$new_build_number" >> $GITHUB_OUTPUT diff --git a/.github/workflows/NOTIFICATION_SETUP.md b/.github/workflows/NOTIFICATION_SETUP.md new file mode 100644 index 00000000..0afb4b43 --- /dev/null +++ b/.github/workflows/NOTIFICATION_SETUP.md @@ -0,0 +1,176 @@ +# Notification System Setup + +## New Features Added + +### 1. Enhanced Concurrency Management + +- Specific concurrency groups for each workflow +- Version management isolation +- PR-specific concurrency handling + +### 2. Version Conflict Resolution + +- Automatic retry mechanism (3 attempts) +- Smart conflict detection and resolution +- Improved version comparison logic + +### 3. Rollback Mechanism + +- Automatic version rollback on failures +- Manual rollback action available +- Audit trail for rollback operations + +### 4. Comprehensive Notification System + +- Multi-channel notifications (Slack, Discord, Email, GitHub Issues) +- Rich deployment information with formatting +- Automatic issue creation for failed deployments + +## Required Secrets + +Add these to your GitHub repository secrets: + +```bash +DEPLOYMENT_WEBHOOK_URL=https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK +DEPLOYMENT_EMAIL_RECIPIENTS=dev-team@company.com,ops@company.com +``` + +## Webhook Setup + +### Slack + +1. Create Slack app → Incoming Webhooks +2. Copy webhook URL to `DEPLOYMENT_WEBHOOK_URL` + +### Discord + +1. Server Settings → Integrations → Webhooks +2. Copy webhook URL to `DEPLOYMENT_WEBHOOK_URL` + +## Usage + +The notification system automatically: +- Sends success/failure notifications for all environments +- Creates GitHub issues for failed deployments +- Provides rich deployment information +- Handles version conflicts automatically + +## Troubleshooting Notification + +- Check webhook URL format and permissions +- Verify secrets are properly configured +- Review workflow logs for detailed error messages + +## Notification Message Format + +The notification system generates rich, formatted messages: + +```sh +✅ **Deployment success** +🎯 **Environment:** production +📦 **Version:** 1.2.3 +🌿 **Branch:** main +👤 **Author:** john-doe +🔗 **PR:** #123 - Add new feature +📝 **Commit:** a1b2c3d4 +💬 **Message:** feat: add new feature +⏰ **Time:** 2024-01-15 10:30:00 UTC +🔗 **Repository:** https://github.com/owner/repo +🔗 **PR Link:** https://github.com/owner/repo/pull/123 +``` + +## Environment-Specific Features + +### Develop Environment + +- Notifications for successful builds and Firebase distribution +- Automatic tag creation +- Version bumping with build number increment + +### Staging Environment + +- Notifications for Google Play internal track releases +- RC version handling +- Pre-production validation + +### Production Environment + +- Notifications for Google Play production releases +- GitHub release creation +- APK artifact upload +- Critical deployment tracking + +## Troubleshooting + +### Common Issues + +1. **Webhook Not Sending** + - Check webhook URL format + - Verify webhook permissions + - Check network connectivity + +2. **Version Conflicts** + - The system will automatically retry up to 3 times + - Check logs for conflict resolution attempts + - Manual intervention may be required for complex conflicts + +3. **Email Notifications Not Working** + - Verify email service configuration + - Check API keys and permissions + - Review email service logs + +### Debug Mode + +Enable debug logging by adding this to your workflow: + +```yaml +env: + ACTIONS_STEP_DEBUG: true + ACTIONS_RUNNER_DEBUG: true +``` + +## Best Practices + +1. **Webhook Security** + - Use HTTPS URLs only + - Rotate webhook URLs regularly + - Monitor webhook usage + +2. **Notification Management** + - Don't send too many notifications + - Use appropriate channels for different environments + - Include relevant stakeholders + +3. **Version Management** + - Review version bumps before merging + - Use appropriate labels for version types + - Monitor version conflicts + +4. **Rollback Strategy** + - Have a clear rollback procedure + - Test rollback mechanisms regularly + - Document rollback decisions + +## Monitoring and Analytics + +The notification system provides: +- Deployment success/failure rates +- Environment-specific metrics +- Response times for notifications +- Version conflict frequency + +## Future Enhancements + +1. **Advanced Analytics Dashboard** +2. **SMS Notifications** +3. **Custom Notification Templates** +4. **Integration with Monitoring Tools** +5. **Automated Rollback Triggers** + +## Support + +For issues or questions: +1. Check the workflow logs +2. Review this documentation +3. Create an issue in the repository +4. Contact the DevOps team diff --git a/.github/workflows/develop_workflow.yml b/.github/workflows/develop_workflow.yml index b73296ef..6c97d146 100644 --- a/.github/workflows/develop_workflow.yml +++ b/.github/workflows/develop_workflow.yml @@ -19,7 +19,7 @@ on: workflow_dispatch: concurrency: - group: ${{ github.workflow }}-${{ github.ref }} + group: develop-workflow-${{ github.event.pull_request.number || github.run_id }} cancel-in-progress: true jobs: @@ -28,7 +28,7 @@ jobs: if: github.event.pull_request.merged == true && contains(github.event.pull_request.labels.*.name, 'no-build') == false runs-on: ubuntu-latest concurrency: - group: build-group + group: version-management-develop cancel-in-progress: false outputs: version_number: ${{ steps.version_management.outputs.version_number }} @@ -197,3 +197,35 @@ jobs: version_number: ${{ needs.preBuild.outputs.version_number }} tag_strategy: "full" allowed_formats: "both" + + ############################################## + # Send Success Notification + ############################################## + - name: Send Success Notification + uses: ./.github/actions/deployment-notification + with: + deployment_status: success + environment: develop + version: ${{ needs.preBuild.outputs.version_number }} + branch: develop + webhook_url: ${{ secrets.DEPLOYMENT_WEBHOOK_URL }} + email_recipients: ${{ secrets.DEPLOYMENT_EMAIL_RECIPIENTS }} + + notify-failure: + name: Notify Deployment Failure + needs: [preBuild] + runs-on: ubuntu-latest + if: failure() && needs.preBuild.result != 'skipped' + steps: + ############################################## + # Send Failure Notification + ############################################## + - name: Send Failure Notification + uses: ./.github/actions/deployment-notification + with: + deployment_status: failure + environment: develop + version: ${{ needs.preBuild.outputs.version_number }} + branch: develop + webhook_url: ${{ secrets.DEPLOYMENT_WEBHOOK_URL }} + email_recipients: ${{ secrets.DEPLOYMENT_EMAIL_RECIPIENTS }} diff --git a/.github/workflows/production_workflow.yml b/.github/workflows/production_workflow.yml index 2f08846b..b510442a 100644 --- a/.github/workflows/production_workflow.yml +++ b/.github/workflows/production_workflow.yml @@ -18,7 +18,7 @@ on: workflow_dispatch: concurrency: - group: ${{ github.workflow }}-${{ github.ref }} + group: production-workflow-${{ github.event.pull_request.number || github.run_id }} cancel-in-progress: true jobs: @@ -27,7 +27,7 @@ jobs: if: github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'main' && (github.event.pull_request.head.ref == 'rc' || contains(github.event.pull_request.labels.*.name, 'prod')) runs-on: ubuntu-latest concurrency: - group: build-group + group: version-management-production cancel-in-progress: false outputs: version_number: ${{ steps.get_current_version.outputs.version_with_build }} @@ -283,17 +283,17 @@ jobs: release_name: Release v${{ env.VERSION }} body: | ## What's New in v${{ env.VERSION }} - + This release includes the latest features and improvements for MultiChoice. - + ### 📱 Download - **APK**: Available for direct download below - **Google Play**: Available on the [Google Play Store](https://play.google.com/store/apps/details?id=co.za.zanderkotze.multichoice) - + ### 🔧 Technical Details - Build Number: ${{ needs.preBuild.outputs.build_number }} - Platform: Android - + ### 📋 Release Notes For detailed release notes, please check the [CHANGELOG.md](https://github.com/${{ github.repository }}/blob/main/CHANGELOG.md) file. draft: false @@ -311,3 +311,35 @@ jobs: asset_path: ./artifacts/app-release.apk asset_name: multichoice-v${{ needs.build.outputs.tag_version }}.apk asset_content_type: application/vnd.android.package-archive + + ############################################## + # Send Success Notification + ############################################## + - name: Send Success Notification + uses: ./.github/actions/deployment-notification + with: + deployment_status: success + environment: production + version: ${{ needs.build.outputs.tag_version }} + branch: main + webhook_url: ${{ secrets.DEPLOYMENT_WEBHOOK_URL }} + email_recipients: ${{ secrets.DEPLOYMENT_EMAIL_RECIPIENTS }} + + notify-failure: + name: Notify Deployment Failure + needs: [preBuild] + runs-on: ubuntu-latest + if: failure() && needs.preBuild.result != 'skipped' + steps: + ############################################## + # Send Failure Notification + ############################################## + - name: Send Failure Notification + uses: ./.github/actions/deployment-notification + with: + deployment_status: failure + environment: production + version: ${{ needs.preBuild.outputs.version_number }} + branch: main + webhook_url: ${{ secrets.DEPLOYMENT_WEBHOOK_URL }} + email_recipients: ${{ secrets.DEPLOYMENT_EMAIL_RECIPIENTS }} diff --git a/.github/workflows/staging_workflow.yml b/.github/workflows/staging_workflow.yml index 9dd99694..398cf3f8 100644 --- a/.github/workflows/staging_workflow.yml +++ b/.github/workflows/staging_workflow.yml @@ -19,7 +19,7 @@ on: workflow_dispatch: concurrency: - group: ${{ github.workflow }}-${{ github.ref }} + group: staging-workflow-${{ github.event.pull_request.number || github.run_id }} cancel-in-progress: true jobs: @@ -28,7 +28,7 @@ jobs: if: github.event.pull_request.merged == true && contains(github.event.pull_request.labels.*.name, 'no-build') == false runs-on: ubuntu-latest concurrency: - group: build-group + group: version-management-staging cancel-in-progress: false outputs: version_number: ${{ steps.version_management.outputs.version_number }} @@ -179,3 +179,35 @@ jobs: version_number: ${{ needs.preBuild.outputs.version_number }} tag_strategy: "full" allowed_formats: "rc" + + ############################################## + # Send Success Notification + ############################################## + - name: Send Success Notification + uses: ./.github/actions/deployment-notification + with: + deployment_status: success + environment: staging + version: ${{ needs.preBuild.outputs.version_number }} + branch: rc + webhook_url: ${{ secrets.DEPLOYMENT_WEBHOOK_URL }} + email_recipients: ${{ secrets.DEPLOYMENT_EMAIL_RECIPIENTS }} + + notify-failure: + name: Notify Deployment Failure + needs: [preBuild] + runs-on: ubuntu-latest + if: failure() && needs.preBuild.result != 'skipped' + steps: + ############################################## + # Send Failure Notification + ############################################## + - name: Send Failure Notification + uses: ./.github/actions/deployment-notification + with: + deployment_status: failure + environment: staging + version: ${{ needs.preBuild.outputs.version_number }} + branch: rc + webhook_url: ${{ secrets.DEPLOYMENT_WEBHOOK_URL }} + email_recipients: ${{ secrets.DEPLOYMENT_EMAIL_RECIPIENTS }}