@Library('flexo-libs')_
pipeline {
  // Some steps hang forever. Rather than take an agent, we are good Jenkins denizens and explicitly say when we want
  // a jenkins worker
  agent none
  options {
    timestamps()
    ansiColor('xterm')
  }
  parameters {
    // Used to deploy a non-master branch to Autohost Server's staging environment.
    booleanParam(name: 'DEPLOY_NON_MASTER_TO_STAGING_AUTOHOST_SERVER', defaultValue: false, description: 'Deploy a non-master branch to Autohost Server\'s staging. Use this to test a branch in staging.')

    booleanParam(name: 'DEPLOY_MASTER_TO_PRODUCTION_AUTOHOST_SERVER', defaultValue: false, description: 'Deploy master to Autohost Server\'s production environment')

    booleanParam(name: 'DEPLOY_MASTER_TO_PRODUCTION_AUTOHOST_WORKER', defaultValue: false, description: 'Deploy master to Autohost Worker\'s production environment')

    booleanParam(name: 'SKIP_STAGING_AUTOHOST_SERVER_SMOKE_TEST', defaultValue: false, description: 'Skip running smoke tests against Autohost Server\'s staging environment. Use this to deploy when the smoke tests are flaky.')

    booleanParam(name: 'SKIP_LINT_AND_TEST', defaultValue: false, description: 'Skip running integration tests and the linter. Use this to speed up testing the build script, and to deploy more quickly during emergencies.')
  }

  stages {
    stage("Set up") {
      agent any
      steps {
        script {
          // Put the short git SHA in the build name so we can find a build by SHA on the UI
          currentBuild.displayName = env.GIT_COMMIT[0..6] + " #" + env.BUILD_NUMBER
        }
      }
    }

    stage("Lint and test") {
      agent any
      when {
        not {
          expression { params.SKIP_LINT_AND_TEST }
        }
      }
      environment {
        SONAR_TOKEN = credentials('autohost-sonar-token')
      }
      steps {
        sh 'docker --version'
        withAgentAWS(role: 'Jenkins', roleAccount: '038504843107', region: 'us-west-2') {
          sh './scripts/jenkins/lint-and-test.sh'
        }
      }
    }

    stage("Build and push Docker images to Staging") {
      agent any
      when {
        anyOf {
          branch 'master'
          expression { params.DEPLOY_NON_MASTER_TO_STAGING_AUTOHOST_SERVER }
        }
      }
      steps {
        withAgentAWS(role: 'Jenkins', roleAccount: '038504843107', region: 'us-west-2') {
          sh './scripts/jenkins/build-docker-staging.sh'
        }
      }
    }

    stage("Deploy Autohost Server to Staging") {
      agent any
      when {
        anyOf {
          branch 'master'
          expression { params.DEPLOY_NON_MASTER_TO_STAGING_AUTOHOST_SERVER }
        }
      }
      options {
        // Only let one build deploy to staging at a time.
        lock(resource: 'autohost_server_staging_deploy')
      }
      steps {
        withAgentAWS(role: 'Jenkins', roleAccount: '038504843107', region: 'us-west-2') {
          sh './scripts/jenkins/deploy-server-staging.sh'
        }
      }
    }

    stage("Smoke test Staging Autohost Server") {
      agent any
      when {
        allOf {
          anyOf {
            branch 'master'
            expression { params.DEPLOY_NON_MASTER_TO_STAGING_AUTOHOST_SERVER }
          }
          not {
            expression { params.SKIP_STAGING_AUTOHOST_SERVER_SMOKE_TEST }
          }
        }
      }
      options {
        // Only let one build deploy to staging at a time.
        lock(resource: 'autohost_server_staging_smoke_tests')
      }
      steps {
        withAgentAWS(role: 'Jenkins', roleAccount: '038504843107', region: 'us-west-2') {
          sh './scripts/jenkins/smoke-test-server-staging.sh'
        }
      }
    }

    stage("Build and push Docker images to Production") {
      agent any
      when {
        allOf {
          branch 'master'
          anyOf {
            expression { params.DEPLOY_MASTER_TO_PRODUCTION_AUTOHOST_SERVER }
            expression { params.DEPLOY_MASTER_TO_PRODUCTION_AUTOHOST_WORKER }
          }
        }
      }
      steps {
        withAgentAWS(role: 'Jenkins', roleAccount: '447680546588', region: 'us-west-2') {
          sh './scripts/jenkins/build-docker-production.sh'
        }
      }
    }

    stage("Deploy Autohost Server to Production") {
      agent any
      when {
        allOf {
          branch 'master'
          expression { params.DEPLOY_MASTER_TO_PRODUCTION_AUTOHOST_SERVER }
        }
      }
      options {
        // Only let one build deploy to production at a time.
        lock(resource: 'autohost_server_production_deploy')
      }
      steps {
        withAgentAWS(role: 'Jenkins', roleAccount: '447680546588', region: 'us-west-2') {
          sh './scripts/jenkins/deploy-server-production.sh'
        }
      }
    }

    stage("Deploy Autohost Worker to Production") {
      agent any
      when {
        allOf {
          branch 'master'
          expression { params.DEPLOY_MASTER_TO_PRODUCTION_AUTOHOST_WORKER }
        }
      }
      options {
        // Only let one build deploy to production at a time.
        lock(resource: 'autohost_worker_production_deploy')
      }
      steps {
        withAgentAWS(role: 'Jenkins', roleAccount: '447680546588', region: 'us-west-2') {
          sh './scripts/jenkins/deploy-worker-production.sh'
        }
      }
    }
  }
}
