trigger:
  - master

resources:
  - repo: self

variables:
  POSTGRES_DB: passbook
  POSTGRES_USER: passbook
  POSTGRES_PASSWORD: "EK-5jnKfjrGRm<77"
  ${{ if startsWith(variables['Build.SourceBranch'], 'refs/heads/') }}:
    branchName: ${{ replace(variables['Build.SourceBranchName'], 'refs/heads/', '') }}
  ${{ if startsWith(variables['Build.SourceBranch'], 'refs/pull/') }}:
    branchName: ${{ replace(variables['System.PullRequest.SourceBranch'], 'refs/heads/', '') }}

stages:
  - stage: Lint
    jobs:
      - job: pylint
        pool:
          vmImage: 'ubuntu-latest'
        steps:
          - task: UsePythonVersion@0
            inputs:
              versionSpec: '3.8'
          - task: CmdLine@2
            inputs:
              script: |
                sudo pip install -U wheel pipenv
                pipenv install --dev
          - task: CmdLine@2
            inputs:
              script: pipenv run pylint passbook
      - job: black
        pool:
          vmImage: 'ubuntu-latest'
        steps:
          - task: UsePythonVersion@0
            inputs:
              versionSpec: '3.8'
          - task: CmdLine@2
            inputs:
              script: |
                sudo pip install -U wheel pipenv
                pipenv install --dev
          - task: CmdLine@2
            inputs:
              script: pipenv run black --check passbook
      - job: prospector
        pool:
          vmImage: 'ubuntu-latest'
        steps:
          - task: UsePythonVersion@0
            inputs:
              versionSpec: '3.8'
          - task: CmdLine@2
            inputs:
              script: |
                sudo pip install -U wheel pipenv
                pipenv install --dev
                pipenv install --dev prospector --skip-lock
          - task: CmdLine@2
            inputs:
              script: pipenv run prospector passbook
      - job: bandit
        pool:
          vmImage: 'ubuntu-latest'
        steps:
          - task: UsePythonVersion@0
            inputs:
              versionSpec: '3.8'
          - task: CmdLine@2
            inputs:
              script: |
                sudo pip install -U wheel pipenv
                pipenv install --dev
          - task: CmdLine@2
            inputs:
              script: pipenv run bandit -r passbook
      - job: pyright
        pool:
          vmImage: ubuntu-latest
        steps:
          - task: UseNode@1
            inputs:
              version: '12.x'
          - task: UsePythonVersion@0
            inputs:
              versionSpec: '3.8'
          - task: CmdLine@2
            inputs:
              script: npm install -g pyright
          - task: CmdLine@2
            inputs:
              script: |
                sudo pip install -U wheel pipenv
                pipenv install --dev
          - task: CmdLine@2
            inputs:
              script: pipenv run pyright
  - stage: Test
    jobs:
      - job: migrations
        pool:
          vmImage: 'ubuntu-latest'
        steps:
          - task: UsePythonVersion@0
            inputs:
              versionSpec: '3.8'
          - task: DockerCompose@0
            displayName: Run services
            inputs:
              dockerComposeFile: 'scripts/ci.docker-compose.yml'
              action: 'Run services'
              buildImages: false
          - task: CmdLine@2
            inputs:
              script: |
                sudo pip install -U wheel pipenv
                pipenv install --dev
          - task: CmdLine@2
            inputs:
              script: pipenv run ./manage.py migrate
      - job: migrations_from_previous_release
        pool:
          vmImage: 'ubuntu-latest'
        steps:
          - task: UsePythonVersion@0
            inputs:
              versionSpec: '3.8'
          - task: DockerCompose@0
            displayName: Run services
            inputs:
              dockerComposeFile: 'scripts/ci.docker-compose.yml'
              action: 'Run services'
              buildImages: false
          - task: CmdLine@2
            displayName: Prepare Last tagged release
            inputs:
              script: |
                git checkout $(git describe --abbrev=0 --match 'version/*')
                sudo pip install -U wheel pipenv
                pipenv install --dev
          - task: CmdLine@2
            displayName: Migrate to last tagged release
            inputs:
              script: pipenv run ./manage.py migrate
          - task: CmdLine@2
            displayName: Install current branch
            inputs:
              script: |
                set -x
                git checkout ${{ variables.branchName }}
                pipenv sync --dev
          - task: CmdLine@2
            displayName: Migrate to current branch
            inputs:
              script: pipenv run ./manage.py migrate
      - job: coverage_unittest
        pool:
          vmImage: 'ubuntu-latest'
        steps:
          - task: UsePythonVersion@0
            inputs:
              versionSpec: '3.8'
          - task: DockerCompose@0
            displayName: Run services
            inputs:
              dockerComposeFile: 'scripts/ci.docker-compose.yml'
              action: 'Run services'
              buildImages: false
          - task: CmdLine@2
            inputs:
              script: |
                sudo pip install -U wheel pipenv
                pipenv install --dev
          - task: CmdLine@2
            displayName: Run full test suite
            inputs:
              script: |
                pipenv run coverage run ./manage.py test passbook -v 3
                mkdir output-unittest
                mv unittest.xml output-unittest/unittest.xml
                mv .coverage output-unittest/coverage
          - task: PublishPipelineArtifact@1
            inputs:
              targetPath: 'output-unittest/'
              artifact: 'coverage-unittest'
              publishLocation: 'pipeline'
      - job: coverage_e2e
        pool:
          name: coventry
        steps:
          - task: UsePythonVersion@0
            inputs:
              versionSpec: '3.8'
          - task: DockerCompose@0
            displayName: Run services
            inputs:
              dockerComposeFile: 'scripts/ci.docker-compose.yml'
              action: 'Run services'
              buildImages: false
          - task: CmdLine@2
            inputs:
              script: |
                sudo pip install -U wheel pipenv
                pipenv install --dev
          - task: DockerCompose@0
            displayName: Run ChromeDriver
            inputs:
              dockerComposeFile: 'e2e/ci.docker-compose.yml'
              action: 'Run a specific service'
              serviceName: 'chrome'
          - task: CmdLine@2
            displayName: Build static files for e2e
            inputs:
              script: |
                cd passbook/static/static
                yarn
          - task: CmdLine@2
            displayName: Run full test suite
            inputs:
              script: |
                pipenv run coverage run ./manage.py test e2e -v 3
          - task: CmdLine@2
            condition: always()
            displayName: Cleanup
            inputs:
              script: |
                docker stop $(docker ps -aq)
          - task: CmdLine@2
            displayName: Prepare unittests and coverage for upload
            inputs:
              script: |
                mkdir output-e2e
                mv unittest.xml output-e2e/unittest.xml
                mv .coverage output-e2e/coverage
          - task: PublishPipelineArtifact@1
            condition: failed()
            displayName: Upload screenshots if selenium tests fail
            inputs:
              targetPath: 'selenium_screenshots/'
              artifact: 'selenium screenshots'
              publishLocation: 'pipeline'
          - task: PublishPipelineArtifact@1
            inputs:
              targetPath: 'output-e2e/'
              artifact: 'coverage-e2e'
              publishLocation: 'pipeline'
  - stage: test_combine
    jobs:
      - job: test_coverage_combine
        pool:
          vmImage: 'ubuntu-latest'
        steps:
          - task: DownloadPipelineArtifact@2
            inputs:
              buildType: 'current'
              artifactName: 'coverage-e2e'
              path: "coverage-e2e/"
          - task: DownloadPipelineArtifact@2
            inputs:
              buildType: 'current'
              artifactName: 'coverage-unittest'
              path: "coverage-unittest/"
          - task: UsePythonVersion@0
            inputs:
              versionSpec: '3.8'
          - task: CmdLine@2
            inputs:
              script: |
                sudo pip install -U wheel pipenv
                pipenv install --dev
                pipenv run coverage combine coverage-e2e/coverage coverage-unittest/coverage
                pipenv run coverage xml
                pipenv run coverage html
          - task: PublishCodeCoverageResults@1
            inputs:
              codeCoverageTool: 'Cobertura'
              summaryFileLocation: 'coverage.xml'
              pathToSources: '$(System.DefaultWorkingDirectory)'
          - task: PublishTestResults@2
            condition: succeededOrFailed()
            inputs:
              testResultsFormat: 'JUnit'
              testResultsFiles: |
                coverage-e2e/unittest.xml
                coverage-unittest/unittest.xml
              mergeTestResults: true
          - task: CmdLine@2
            env:
              CODECOV_TOKEN: $(CODECOV_TOKEN)
            inputs:
              script: bash <(curl -s https://codecov.io/bash)
  - stage: Build
    jobs:
      - job: build_server
        pool:
          vmImage: 'ubuntu-latest'
        steps:
        - task: Docker@2
          inputs:
            containerRegistry: 'dockerhub'
            repository: 'beryju/passbook'
            command: 'buildAndPush'
            Dockerfile: 'Dockerfile'
            tags: "gh-${{ variables.branchName }}"
      - job: build_static
        pool:
          vmImage: 'ubuntu-latest'
        steps:
        - task: DockerCompose@0
          displayName: Run services
          inputs:
            dockerComposeFile: 'scripts/ci.docker-compose.yml'
            action: 'Run services'
            buildImages: false
        - task: Docker@2
          inputs:
            containerRegistry: 'dockerhub'
            repository: 'beryju/passbook-static'
            command: 'build'
            Dockerfile: 'static.Dockerfile'
            tags: "gh-${{ variables.branchName }}"
            arguments: "--network=beryjupassbook_default"
        - task: Docker@2
          inputs:
            containerRegistry: 'dockerhub'
            repository: 'beryju/passbook-static'
            command: 'push'
            tags: "gh-${{ variables.branchName }}"
  - stage: Deploy
    jobs:
      - job: deploy_dev
        pool:
          vmImage: 'ubuntu-latest'
          steps:
          - task: HelmDeploy@0
            inputs:
              connectionType: 'Kubernetes Service Connection'
              kubernetesServiceConnection: 'k8s-beryjuorg-prd'
              namespace: 'passbook-dev'
              command: 'upgrade'
              chartType: 'FilePath'
              chartPath: 'helm/'
              releaseName: 'passbook-dev'
              recreate: true