# This workflow implements continuous delivery with automated testing and fully
# autonomous deploys to staging and production.
#
# If executed on a pull request, this will trigger a "staging" deploy to a
# non-primary app engine version named "pr<number>" for the current pull
# request number IFF tests pass.
#
# If executed on a push to master, this will trigger a "production" deploy IFF
# tests pass.
#
# A separate "Cleanup" workflow (cleanup.yaml) runs when pull requests are
# closed to remove the staging deploy for that pull request.
name: CD

# Translated: "Execute this workflow on pushes to master OR on pull requests
# opened against master"
#
# See this question and answer for what we're solving here:
# https://github.community/t5/GitHub-Actions/How-to-trigger-an-action-on-push-or-pull-request-but-not-both/m-p/36155#M2460
on:
  push:
    branches: [master]
  pull_request:
    branches: [master]

jobs:
  lint:
    name: Lint
    runs-on: ubuntu-latest
    steps:
    - name: Setup
      uses: actions/setup-go@v2

    - name: Checkout
      uses: actions/checkout@v2

    - name: Lint
      run: make lint

  test:
    name: Test
    runs-on: ubuntu-latest
    steps:
    - name: Setup
      uses: actions/setup-go@v2

    - name: Checkout
      uses: actions/checkout@v2

    - name: Build
      run: make build

    - name: Test
      run: make testci

    - name: Code coverage
      uses: codecov/codecov-action@v1
      with:
        file: ./coverage.txt

  regression_test:
    name: Regression Tests
    runs-on: ubuntu-latest
    strategy:
      matrix:
        go_version:
        - '1.13'
        - '1.14'
    steps:
    - name: Setup
      uses: actions/setup-go@v2
      with:
        go-version: ${{matrix.go_version}}

    - name: Checkout
      uses: actions/checkout@v2

    - name: Build
      run: make build

    - name: Test
      run: make test

  staging_deploy:
    name: Staging Deploy
    if: github.ref != 'refs/heads/master'
    runs-on: ubuntu-latest
    needs: [lint, test]
    steps:
    - name: Checkout
      uses: actions/checkout@v2

    - name: Setup gcloud CLI
      uses: GoogleCloudPlatform/github-actions/setup-gcloud@master
      with:
        version: '285.0.0'
        project_id: ${{ secrets.GCP_PROJECT_ID }}
        service_account_email: ${{ secrets.GCP_SA_EMAIL }}
        service_account_key: ${{ secrets.GCP_SA_KEY }}
        export_default_credentials: true

    - name: Setup deployment parameters
      id: deployment_params
      run: |
        pr_number=$(jq -r .pull_request.number "$GITHUB_EVENT_PATH")
        echo "::set-output name=version::pr${pr_number}"

    - name: Notify start
      id: deployment
      uses: bobheadxi/deployments@v0.4.0
      with:
        env: staging
        ref: ${{ github.head_ref }}
        step: start
        token: ${{ secrets.GITHUB_TOKEN }}

    - name: Deploy
      run: gcloud app deploy --quiet --no-promote --project="${{ secrets.GCP_PROJECT_ID }}" --version="${{ steps.deployment_params.outputs.version }}"

    - name: Notify finish
      uses: bobheadxi/deployments@v0.4.0
      with:
        step: finish
        deployment_id: ${{ steps.deployment.outputs.deployment_id }}
        token: ${{ secrets.GITHUB_TOKEN }}
        env: staging
        status: ${{ job.status }}
        env_url: 'https://${{ steps.deployment_params.outputs.version }}-dot-httpbingo.uc.r.appspot.com'
        logs: 'https://console.cloud.google.com/logs/viewer?project=${{ secrets.GCP_PROJECT_ID }}&resource=gae_app%2Fmodule_id%2Fdefault%2Fversion_id%2F${{ steps.deployment_params.outputs.version }}'

  production_deploy:
    name: Production Deploy
    if: github.ref == 'refs/heads/master'
    runs-on: ubuntu-latest
    needs: [lint, test]
    steps:
    - name: Checkout
      uses: actions/checkout@v2

    - name: Setup gcloud CLI
      uses: GoogleCloudPlatform/github-actions/setup-gcloud@master
      with:
        version: '285.0.0'
        project_id: ${{ secrets.GCP_PROJECT_ID }}
        service_account_email: ${{ secrets.GCP_SA_EMAIL }}
        service_account_key: ${{ secrets.GCP_SA_KEY }}
        export_default_credentials: true

    - name: Setup deployment parameters
      id: deployment_params
      run: |
        version=$(echo "${GITHUB_SHA}" | head -c 8)
        echo "::set-output name=version::${version}"

    - name: Notify start
      id: deployment
      uses: bobheadxi/deployments@v0.4.0
      with:
        step: start
        token: ${{ secrets.GITHUB_TOKEN }}
        env: staging

    - name: Deploy
      run: gcloud app deploy --quiet --project="${{ secrets.GCP_PROJECT_ID }}" --version="${{ steps.deployment_params.outputs.version }}"

    - name: Notify finish
      uses: bobheadxi/deployments@v0.4.0
      with:
        step: finish
        deployment_id: ${{ steps.deployment.outputs.deployment_id }}
        token: ${{ secrets.GITHUB_TOKEN }}
        env: staging
        status: ${{ job.status }}
        env_url: 'https://${{ steps.deployment_params.outputs.version }}-dot-httpbingo.uc.r.appspot.com'
        logs: 'https://console.cloud.google.com/logs/viewer?project=${{ secrets.GCP_PROJECT_ID }}&resource=gae_app%2Fmodule_id%2Fdefault%2Fversion_id%2F${{ steps.deployment_params.outputs.version }}'
