Implement Clean Architecture and enhance documentation #1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build and Deploy to Azure App Service | |
| # =================================================================== | |
| # WORKFLOW TRIGGER CONFIGURATION | |
| # =================================================================== | |
| # This workflow triggers on: | |
| # 1. Push to Master: Builds, tests, and DEPLOYS to Azure (Production) | |
| # 2. Push to Dev: Builds and tests only (NO deployment) | |
| # 3. Pull Requests to Master/Dev: Builds, tests, and runs security scan (NO deployment) | |
| # 4. For more details, see the JOB comments below and visit documentation at: Docs/Deployment/AzureAppService/DEPLOYMENT_GUIDE.md and Docs/CICD/CICD_PIPELINE_GUIDE.md | |
| on: | |
| push: | |
| branches: | |
| - Master # Production deployment | |
| - Dev # Build/test only, no deployment | |
| pull_request: | |
| branches: | |
| - Master | |
| - Dev | |
| env: | |
| DOTNET_VERSION: '8.0.x' | |
| AZURE_WEBAPP_PACKAGE_PATH: './publish' | |
| # =================================================================== | |
| # JOB 1: BUILD AND TEST | |
| # =================================================================== | |
| # Purpose: Compiles the application and runs tests | |
| # Runs on: All branches (Master, Dev) and all pull requests | |
| # Output: Build artifact uploaded for deployment job | |
| jobs: | |
| build: | |
| name: Build and Test | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: ${{ env.DOTNET_VERSION }} | |
| # ===== Cache NuGet packages for faster builds ===== | |
| # Caches packages to reduce build time from ~3min to ~1.5min (50% faster) | |
| - name: Cache NuGet packages | |
| uses: actions/cache@v3 | |
| with: | |
| path: ~/.nuget/packages | |
| key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }} | |
| restore-keys: | | |
| ${{ runner.os }}-nuget- | |
| - name: Restore dependencies | |
| run: dotnet restore | |
| - name: Build | |
| run: dotnet build --configuration Release --no-restore | |
| # ===== Run tests only if test projects exist ===== | |
| # continue-on-error: true allows workflow to succeed even without test projects | |
| # Remove this flag once unit tests are added to make tests required | |
| - name: Test | |
| run: dotnet test --no-build --verbosity normal --configuration Release | |
| continue-on-error: true | |
| - name: Publish | |
| run: dotnet publish -c Release -o ${{ env.AZURE_WEBAPP_PACKAGE_PATH }} | |
| # ===== Upload build artifacts for debugging ===== | |
| # Artifacts can be downloaded from GitHub Actions UI for troubleshooting | |
| - name: Upload artifact for deployment job | |
| uses: actions/upload-artifact@v3 | |
| with: | |
| name: dotnet-app | |
| path: ${{ env.AZURE_WEBAPP_PACKAGE_PATH }} | |
| # =================================================================== | |
| # JOB 2: DEPLOY TO AZURE | |
| # =================================================================== | |
| # Purpose: Deploys the application to Azure App Service (Production) | |
| # | |
| # *** 1. DEPLOY JOB CONDITION *** | |
| # This job ONLY runs when: | |
| # - Event is a 'push' (not a pull request) | |
| # - AND branch is 'Master' (production branch) | |
| # | |
| # Result: | |
| # ✅ Master push → Deploys to Azure | |
| # ❌ Dev push → Builds only, NO deployment | |
| # ❌ Pull Request → Builds only, NO deployment | |
| # | |
| # This ensures only production-ready code from Master reaches Azure. | |
| deploy: | |
| name: Deploy to Azure | |
| runs-on: ubuntu-latest | |
| needs: build # Waits for build job to succeed | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/Master' # Deploy ONLY on push to Master | |
| # *** 2. ENVIRONMENT CONFIGURATION *** | |
| # GitHub Environment: 'production' | |
| # - Can be configured in GitHub repo settings to require manual approval | |
| # - Provides deployment history and protection rules | |
| # - URL displays the deployed application URL in GitHub Actions UI | |
| environment: | |
| name: 'production' | |
| url: ${{ steps.deploy-to-webapp.outputs.webapp-url }} | |
| steps: | |
| - name: Download artifact from build job | |
| uses: actions/download-artifact@v3 | |
| with: | |
| name: dotnet-app | |
| path: ${{ env.AZURE_WEBAPP_PACKAGE_PATH }} | |
| - name: Deploy to Azure Web App | |
| id: deploy-to-webapp | |
| uses: azure/webapps-deploy@v3 | |
| with: | |
| app-name: ${{ secrets.AZURE_WEBAPP_NAME }} | |
| publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }} | |
| package: ${{ env.AZURE_WEBAPP_PACKAGE_PATH }} | |
| # ===== Configure App Settings in Azure ===== | |
| # Sets configuration values directly in Azure App Service | |
| # These persist across deployments and override appsettings.json | |
| - name: Azure Login | |
| uses: azure/login@v1 | |
| with: | |
| creds: ${{ secrets.AZURE_CREDENTIALS }} | |
| continue-on-error: true # Optional: if service principal not configured yet | |
| # *** 3. ASPNETCORE_ENVIRONMENT CONFIGURATION *** | |
| # Sets ASPNETCORE_ENVIRONMENT to "Production" in Azure App Service | |
| # This determines which appsettings file is loaded: | |
| # - appsettings.json (base) | |
| # - appsettings.Production.json (overrides for production) | |
| # | |
| # Effects in application: | |
| # - Production: Uses Azure Key Vault for secrets, production logging | |
| # - Development: Uses local appsettings.Development.json | |
| # | |
| # Since only Master deploys, this is always "Production" | |
| - name: Set Azure App Settings | |
| uses: azure/appservice-settings@v1 | |
| with: | |
| app-name: ${{ secrets.AZURE_WEBAPP_NAME }} | |
| app-settings-json: | | |
| [ | |
| { | |
| "name": "ThirdPartyApi__BaseUrl", | |
| "value": "${{ secrets.THIRDPARTY_API_BASEURL }}", | |
| "slotSetting": false | |
| }, | |
| { | |
| "name": "ASPNETCORE_ENVIRONMENT", | |
| "value": "Production", | |
| "slotSetting": false | |
| } | |
| ] | |
| continue-on-error: true # Optional: if service principal not configured yet | |
| # ===== Health Check ===== | |
| # Verifies the deployed application is running by calling /health endpoint | |
| # Waits 30 seconds for application startup before checking | |
| - name: Health Check | |
| run: | | |
| echo "Waiting 30 seconds for app to start..." | |
| sleep 30 | |
| curl -f https://${{ secrets.AZURE_WEBAPP_NAME }}.azurewebsites.net/health || echo "Health check failed, but deployment completed" | |
| continue-on-error: true | |
| # =================================================================== | |
| # JOB 3: SECURITY SCAN (OPTIONAL) | |
| # =================================================================== | |
| # Purpose: Scans for security vulnerabilities using Trivy | |
| # Runs on: Pull requests only (not on direct pushes) | |
| # Output: Security report uploaded to GitHub Security tab | |
| security-scan: | |
| name: Security Scan | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'pull_request' # Only run on PRs | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Run Trivy vulnerability scanner | |
| uses: aquasecurity/trivy-action@master | |
| with: | |
| scan-type: 'fs' | |
| scan-ref: '.' | |
| format: 'sarif' | |
| output: 'trivy-results.sarif' | |
| continue-on-error: true | |
| - name: Upload Trivy results to GitHub Security tab | |
| uses: github/codeql-action/upload-sarif@v2 | |
| with: | |
| sarif_file: 'trivy-results.sarif' | |
| continue-on-error: true | |
| # =================================================================== | |
| # *** WORKFLOW BEHAVIOR SUMMARY *** | |
| # =================================================================== | |
| # | |
| # ┌─────────────────┬───────┬───────┬────────┬─────────────┐ | |
| # │ Trigger │ Build │ Test │ Deploy │ Environment │ | |
| # ├─────────────────┼───────┼───────┼────────┼─────────────┤ | |
| # │ Push to Master │ ✅ │ ✅ │ ✅ │ Production │ | |
| # │ Push to Dev │ ✅ │ ✅ │ ❌ │ N/A │ | |
| # │ PR to Master │ ✅ │ ✅ │ ❌ │ N/A │ | |
| # │ PR to Dev │ ✅ │ ✅ │ ❌ │ N/A │ | |
| # └─────────────────┴───────┴───────┴────────┴─────────────┘ | |
| # | |
| # DEPLOYMENT FLOW (Master branch only): | |
| # 1. Developer pushes to Master | |
| # 2. Build job: Restore → Build → Test → Publish → Upload artifact | |
| # 3. Deploy job: Download artifact → Deploy to Azure → Configure settings | |
| # 4. Health check verifies deployment success | |
| # 5. Application runs with ASPNETCORE_ENVIRONMENT=Production | |
| # | |
| # DEVELOPMENT FLOW (Dev branch): | |
| # 1. Developer pushes to Dev | |
| # 2. Build job: Restore → Build → Test → Publish → Upload artifact | |
| # 3. Deploy job: SKIPPED (does not run) | |
| # 4. Artifact available for manual inspection if needed | |
| # | |
| # PULL REQUEST FLOW: | |
| # 1. Developer opens PR | |
| # 2. Build job: Restore → Build → Test → Publish | |
| # 3. Security scan job: Runs Trivy vulnerability scanner | |
| # 4. Deploy job: SKIPPED (does not run) | |
| # 5. Results available for review before merging | |
| # | |
| # =================================================================== |