trigger:
  batch: true
  branches:
    include:
      - master
      - next
      - version-*

resources:
  - repo: self

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

stages:
  - stage: Lint_and_test
    jobs:
      - job: pylint
        pool:
          vmImage: 'ubuntu-latest'
        steps:
          - task: UsePythonVersion@0
            inputs:
              versionSpec: '3.9'
          - task: DockerCompose@0
            displayName: Run services
            inputs:
              dockerComposeFile: 'scripts/ci.docker-compose.yml'
              action: 'Run services'
              buildImages: false
          - task: CmdLine@2
            inputs:
              script: |
                sudo apt update
                sudo apt install -y libxmlsec1-dev pkg-config
                sudo pip install -U wheel pipenv
                pipenv install --dev
          - task: CmdLine@2
            inputs:
              script: |
                pipenv run python -m scripts.generate_ci_config
                pipenv run pylint authentik tests lifecycle
      - job: black
        pool:
          vmImage: 'ubuntu-latest'
        steps:
          - task: UsePythonVersion@0
            inputs:
              versionSpec: '3.9'
          - task: CmdLine@2
            inputs:
              script: |
                sudo apt update
                sudo apt install -y libxmlsec1-dev pkg-config
                sudo pip install -U wheel pipenv
                pipenv install --dev
          - task: CmdLine@2
            inputs:
              script: pipenv run black --check authentik tests lifecycle
      - job: isort
        pool:
          vmImage: 'ubuntu-latest'
        steps:
          - task: UsePythonVersion@0
            inputs:
              versionSpec: '3.9'
          - task: CmdLine@2
            inputs:
              script: |
                sudo apt update
                sudo apt install -y libxmlsec1-dev pkg-config
                sudo pip install -U wheel pipenv
                pipenv install --dev
          - task: CmdLine@2
            inputs:
              script: pipenv run isort --check authentik tests lifecycle
      - job: bandit
        pool:
          vmImage: 'ubuntu-latest'
        steps:
          - task: UsePythonVersion@0
            inputs:
              versionSpec: '3.9'
          - task: CmdLine@2
            inputs:
              script: |
                sudo apt update
                sudo apt install -y libxmlsec1-dev pkg-config
                sudo pip install -U wheel pipenv
                pipenv install --dev
          - task: CmdLine@2
            inputs:
              script: pipenv run bandit -r authentik tests lifecycle
      - job: pyright
        pool:
          vmImage: ubuntu-latest
        steps:
          - task: UseNode@1
            inputs:
              version: '12.x'
          - task: UsePythonVersion@0
            inputs:
              versionSpec: '3.9'
          - task: CmdLine@2
            inputs:
              script: npm install -g pyright@1.1.136
          - task: CmdLine@2
            inputs:
              script: |
                sudo apt update
                sudo apt install -y libxmlsec1-dev pkg-config
                sudo pip install -U wheel pipenv
                pipenv install --dev
          - task: CmdLine@2
            inputs:
              script: pipenv run pyright e2e lifecycle
      - job: migrations
        pool:
          vmImage: 'ubuntu-latest'
        steps:
          - task: UsePythonVersion@0
            inputs:
              versionSpec: '3.9'
          - task: DockerCompose@0
            displayName: Run services
            inputs:
              dockerComposeFile: 'scripts/ci.docker-compose.yml'
              action: 'Run services'
              buildImages: false
          - task: CmdLine@2
            inputs:
              script: |
                sudo apt update
                sudo apt install -y libxmlsec1-dev pkg-config
                sudo pip install -U wheel pipenv
                pipenv install --dev
          - task: CmdLine@2
            inputs:
              script: |
                pipenv run python -m scripts.generate_ci_config
                pipenv run ./manage.py migrate
      - job: migrations_from_previous_release
        pool:
          vmImage: 'ubuntu-latest'
        steps:
          - task: UsePythonVersion@0
            inputs:
              versionSpec: '3.8'
          - task: UsePythonVersion@0
            inputs:
              versionSpec: '3.9'
          - 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: |
                # Copy current, latest config to local
                cp authentik/lib/default.yml local.env.yml
                git checkout $(git describe --abbrev=0 --match 'version/*')
                sudo apt update
                sudo apt install -y libxmlsec1-dev pkg-config
                sudo pip install -U wheel pipenv
                pipenv install --dev
          - task: CmdLine@2
            displayName: Migrate to last tagged release
            inputs:
              script: |
                pipenv run python -m scripts.generate_ci_config
                pipenv run python -m lifecycle.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 python -m scripts.generate_ci_config
                pipenv run python -m lifecycle.migrate
      - job: coverage_unittest
        pool:
          vmImage: 'ubuntu-latest'
        steps:
          - task: UsePythonVersion@0
            inputs:
              versionSpec: '3.9'
          - task: DockerCompose@0
            displayName: Run services
            inputs:
              dockerComposeFile: 'scripts/ci.docker-compose.yml'
              action: 'Run services'
              buildImages: false
          - task: CmdLine@2
            inputs:
              script: |
                sudo apt update
                sudo apt install -y libxmlsec1-dev pkg-config
                sudo pip install -U wheel pipenv
                pipenv install --dev
          - task: CmdLine@2
            displayName: Run full test suite
            inputs:
              script: |
                pipenv run python -m scripts.generate_ci_config
                pipenv run make test
          - task: CmdLine@2
            inputs:
              script: |
                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_integration
        pool:
          vmImage: 'ubuntu-latest'
        steps:
          - task: UsePythonVersion@0
            inputs:
              versionSpec: '3.9'
          - task: DockerCompose@0
            displayName: Run services
            inputs:
              dockerComposeFile: 'scripts/ci.docker-compose.yml'
              action: 'Run services'
              buildImages: false
          - task: CmdLine@2
            inputs:
              script: |
                sudo apt update
                sudo apt install -y libxmlsec1-dev pkg-config
                sudo pip install -U wheel pipenv
                pipenv install --dev
          - task: CmdLine@2
            displayName: Install K3d and prepare
            inputs:
              script: |
                wget -q -O - https://raw.githubusercontent.com/rancher/k3d/main/install.sh | bash
                k3d cluster create
                k3d kubeconfig write -o ~/.kube/config --overwrite
          - task: CmdLine@2
            displayName: Run full test suite
            inputs:
              script: |
                pipenv run python -m scripts.generate_ci_config
                pipenv run make test-integration
          - task: CmdLine@2
            inputs:
              script: |
                mkdir output-integration
                mv unittest.xml output-integration/unittest.xml
                mv .coverage output-integration/coverage
          - task: PublishPipelineArtifact@1
            inputs:
              targetPath: 'output-integration/'
              artifact: 'coverage-integration'
              publishLocation: 'pipeline'
      - job: coverage_e2e
        pool:
          vmImage: 'ubuntu-latest'
        steps:
          - task: UsePythonVersion@0
            inputs:
              versionSpec: '3.9'
          - task: NodeTool@0
            inputs:
              versionSpec: '16.x'
          - task: DockerCompose@0
            displayName: Run services
            inputs:
              dockerComposeFile: 'scripts/ci.docker-compose.yml'
              action: 'Run services'
              buildImages: false
          - task: CmdLine@2
            inputs:
              script: |
                sudo apt update
                sudo apt install -y libxmlsec1-dev pkg-config
                sudo pip install -U wheel pipenv
                pipenv install --dev --python python3.9
          - task: DockerCompose@0
            displayName: Run ChromeDriver
            inputs:
              dockerComposeFile: 'tests/e2e/ci.docker-compose.yml'
              action: 'Run a specific service'
              serviceName: 'chrome'
          - task: CmdLine@2
            displayName: Build static files for e2e
            inputs:
              script: |
                docker run --rm -v $(pwd):/local openapitools/openapi-generator-cli generate -i /local/swagger.yaml -g typescript-fetch -o /local/web/api --additional-properties=typescriptThreePlus=true,supportsES6=true,npmName=authentik-api,npmVersion=1.0.0
                sudo chmod 777 -R web/api/
                cd web
                cd api && npm i && cd ..
                npm i
                npm run build
          - task: CmdLine@2
            displayName: Run full test suite
            inputs:
              script: |
                pipenv run python -m scripts.generate_ci_config
                pipenv run make test-e2e
          - task: CmdLine@2
            condition: always()
            displayName: Cleanup
            inputs:
              script: |
                docker stop $(docker ps -aq)
                docker container prune -f
          - 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-integration'
              path: "coverage-integration/"
          - task: DownloadPipelineArtifact@2
            inputs:
              buildType: 'current'
              artifactName: 'coverage-unittest'
              path: "coverage-unittest/"
          - task: UsePythonVersion@0
            inputs:
              versionSpec: '3.9'
          - task: CmdLine@2
            inputs:
              script: |
                sudo apt update
                sudo apt install -y libxmlsec1-dev pkg-config
                sudo pip install -U wheel pipenv
                pipenv install --dev
                pipenv run coverage combine coverage-e2e/coverage coverage-unittest/coverage coverage-integration/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-integration/unittest.xml
                coverage-unittest/unittest.xml
              mergeTestResults: true
          - task: CmdLine@2
            inputs:
              script: bash <(curl -s https://codecov.io/bash)
  - stage: generate
    jobs:
      - job: swagger_generate
        pool:
          vmImage: 'ubuntu-latest'
        steps:
          - task: NodeTool@0
            inputs:
              versionSpec: '16.x'
            displayName: 'Install Node.js'
          - task: CmdLine@2
            inputs:
              script: |
                docker run --rm -v $(pwd):/local openapitools/openapi-generator-cli generate -i /local/swagger.yaml -g typescript-fetch -o /local/web/api --additional-properties=typescriptThreePlus=true,supportsES6=true,npmName=authentik-api,npmVersion=1.0.0
          - task: PublishPipelineArtifact@1
            inputs:
              targetPath: 'web/api/'
              artifact: 'ts_swagger_client'
              publishLocation: 'pipeline'
  - stage: Build
    jobs:
      - job: build_server
        pool:
          vmImage: 'ubuntu-latest'
        steps:
        - task: DownloadPipelineArtifact@2
          inputs:
            buildType: 'current'
            artifactName: 'ts_swagger_client'
            path: "web/api/"
        - task: Bash@3
          inputs:
            targetType: 'inline'
            script: |
              python ./scripts/az_do_set_branch.py
        - task: Docker@2
          inputs:
            containerRegistry: 'beryjuorg-harbor'
            repository: 'authentik/server'
            command: 'build'
            Dockerfile: 'Dockerfile'
            tags: 'gh-$(branchName)'
            arguments: '--build-arg GIT_BUILD_HASH=$(Build.SourceVersion)'
        - task: Docker@2
          inputs:
            containerRegistry: 'beryjuorg-harbor'
            repository: 'authentik/server'
            command: 'push'
            tags: 'gh-$(branchName)'