# This is a GitHub Actions workflow file for building and deploying a Reliable Web App (RWA) pattern to an Azure environment.
#
# Usage: 
#   - To trigger the workflow manually, click the "Run workflow" button in the Actions tab of your GitHub repository.
#   - To schedule the workflow, uncomment the "schedule" section and specify a cron expression.
#
# Inputs:
#   - environment: The target environment for the deployment (dev or prod).
#   - run_tear_down: Whether to delete resources after a run (true or false).
#
# Permissions:
#   - id-token: write
#   - contents: read
#
# Environment variables:
#   - APP_ENVIRONMENT: The target environment for the deployment (dev or prod).
#   - AZURE_APP_NAME: The name used to seed resource names generated by this deployment.
#   - AZURE_CLIENT_ID: The client ID of the Azure AD App Registration.
#   - AZURE_CLIENT_SECRET: The client secret of the Azure AD App Registration.
#   - AZURE_CREDENTIALS: The json used to authenticate with the Azure CLI.
#   - AZURE_LOCATION: The Azure region string where resources are provisioned.
#   - AZURE_SUBSCRIPTION_ID: The subscription where Azure resource will be provisioned.
#   - AZURE_TENANT_ID: The Azure AD tenant hosting the App Registration used for authentication by the web app.
#   - POSTGRES_DATABASE_PASSWORD: A password used by the Postgres Database. # should be a secret for production workloads
#
# For more information, see https://learn.microsoft.com/en-us/azure/developer/github/connect-from-azure?tabs=azure-portal%2Clinux#set-up-azure-login-with-openid-connect-authentication

name: 'RWA: Scheduled Build & Deploy'

on:
  workflow_dispatch:
    inputs:
      environment:
        description: 'App environment'
        required: true
        default: 'dev'
        type: choice
        options:
        - dev
        - prod
  pull_request:
    types: [opened, synchronize, ready_for_review, reopened]
  schedule:
    - cron: '0 14 1 * *' # Run at 14:00 on the 1st day of the month
        
# https://learn.microsoft.com/en-us/azure/developer/github/connect-from-azure?tabs=azure-portal%2Clinux#set-up-azure-login-with-openid-connect-authentication
permissions:
  id-token: write
  contents: read

jobs:
  terraform:
    env:
      APP_NAME: ${{ vars.AZURE_APP_NAME }}${{ github.run_number }}v${{ github.run_attempt }}
      APP_ENVIRONMENT: ${{ inputs.environment || 'dev' }}
      AZURE_CLIENT_ID: ${{ vars.AZURE_CLIENT_ID }}
      AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }}
      AZURE_ENV_NAME: ${{ vars.AZURE_APP_NAME }}${{ github.run_number }}v${{ github.run_attempt }}
      AZURE_TENANT_ID: ${{ vars.AZURE_TENANT_ID }}
      ENABLE_TELEMETRY: true
      PRINCIPAL_TYPE: ServicePrincipal
      TRAININGS_DIR: $PROJECT_ROOT/videos
      
    name: 'Build & deploy infra'
    runs-on: ubuntu-latest
    environment: production

    # Use the Bash shell regardless whether the GitHub Actions runner is ubuntu-latest, macos-latest, or windows-latest
    defaults:
      run:
        shell: bash

    steps:
    - uses: actions/checkout@v3
    - uses: actions/setup-java@v3
      with:
        java-version: '17'
        distribution: 'microsoft'
        cache: 'maven'

    - name: Set env
      # the script that uploads training videos requires an environment variable
      # named PROJECT_ROOT to be set to the path of the project root
      run: echo "PROJECT_ROOT=$(pwd)" >> $GITHUB_ENV

    - name: Describe Java version
      run: mvn -v
      
    - name: Add AZD
      run: curl -fsSL https://aka.ms/install-azd.sh | bash

    - name: print input env variables
      run: |
        echo $APP_NAME
        echo $APP_ENVIRONMENT
        echo $PROJECT_ROOT
        az --version

    # Install the az cli with login using service principal created on az subscription
    - name: Azure CLI Login
      uses: azure/login@v1
      with:
        creds: ${{ secrets.AZURE_CREDENTIALS }}

    - name: AZD Login
      run: |
        $info = $Env:AZURE_CREDENTIALS | ConvertFrom-Json -AsHashtable;
        Write-Host "::add-mask::$($info.clientSecret)"

        azd auth login `
          --client-id "$($info.clientId)" `
          --client-secret "$($info.clientSecret)" `
          --tenant-id "$($info.tenantId)"
      shell: pwsh
      env:
        AZURE_CREDENTIALS: ${{ secrets.AZURE_CREDENTIALS }}

    - name: Enable terraform alpha feature
      run: |
        azd config set alpha.terraform on

    - name: AZD set vars
      run: |
        azd env new $APP_NAME
        azd env set DATABASE_PASSWORD ${{ secrets.POSTGRES_DATABASE_PASSWORD }}
        azd env set AZURE_LOCATION ${{ vars.AZURE_LOCATION }}
        azd env set AZURE_SUBSCRIPTION_ID ${{ secrets.AZURE_SUBSCRIPTION_ID }}

    - name: AZD Provision Infrastructure
      id: azd_provision
      continue-on-error: true
      run: |
        export ARM_CLIENT_ID=${{ vars.TERRAFORM_CLIENT_ID }}
        export ARM_CLIENT_SECRET=${{ secrets.TERRAFORM_CLIENT_SECRET }}
        export ARM_TENANT_ID=$AZURE_TENANT_ID
        azd provision --no-prompt

    - name: AZD Deploy Application
      id: azd_deploy
      if: steps.azd_provision.outcome == 'success'
      continue-on-error: true
      run: azd deploy --no-prompt

    - name: Delete Resources
      run: |
        export ARM_CLIENT_ID=${{ vars.TERRAFORM_CLIENT_ID }}
        export ARM_CLIENT_SECRET=${{ secrets.TERRAFORM_CLIENT_SECRET }}
        export ARM_TENANT_ID=$AZURE_TENANT_ID
        azd down --force --purge --no-prompt

    - name: Check for success
      run: |
        green='\033[0;32m'
        red='\e[1;31m'
        clear='\033[0m'

        if [[ "${{ steps.azd_provision.outcome }}" == 'success' ]]; then
          printf "AZD provision ${green}success${clear}\n"
        else
          printf "AZD provision ${red}failed${clear}\n"
          exit 1
        fi

        if [[ "${{ steps.azd_deploy.outcome }}" == 'success' ]]; then
          printf "AZD deploy ${green}success${clear}\n"
        else
          printf "AZD deploy ${red}failed${clear}\n"
          exit 1
        fi