instruction: Show me how to configure circleci for CI/CD automation
output: Bolt Bolt engineers own and optimize build pipelines Bolt, the world’s first checkout experience platform, solves the complicated technological challenges involved in checkout, fraud detection, and digital wallets, so that retailers including Forever 21, Badgley Mischka, and Milk Makeup can devote their energy to what matters most—growing their product, brand, and customer base. The company, which launched in 2014 by a small, but scrappy team of just 10, now employs more than 170. Just like its headcount, Bolt’s pipeline has scaled to meet the needs of its growing retailer base, accounting for more than 500,000 tests daily. To support its need for faster, more user friendly test suites, Bolt implemented CircleCI in 2018. Since then, Bolt has reduced the average commit time from 20 minutes down to just five – while more than tripling its volume of tests thanks to CircleCI. CircleCI handles the heavy lifting Bolt uses a very large monorepo strategy for its code repository. The challenge, explains engineering manager Roopak Venkatakrishnan, was scaling out development with monorepo to create an optimally built pipeline. “ The most important thing for us is that, as we scale as a team, we don’t have to set up and manage our own CI system.” Roopak Venkatakrishnan | Software Engineer at Bolt “The most important thing for us is that, as we scale as a team, we don’t have to set up and manage our own CI system,” Venkatakrishnan says. “CircleCI does the heavy lifting. We don’t want to build something that’s not really core to our business – we’d rather offload it.” Bolt has also reduced breaks in its master branch, in part using CircleCI’s pre-built orbs. Through a CircleCI integration with Slack, engineers get instant notifications when a break occurs; they can then immediately revert the problematic build or push out a fix. “Without this system, we’d have a lot of broken commits on masters,” Venkatakrishnan says. Configurability helps reduce build time by two-thirds CircleCI’s configurability is a boon for the Bolt dev team. “With other tools, a lot of the configurability is hidden,” Venkatakrishnan explains. “With CircleCI, everyone can see the configurations, and everyone can contribute.” Of all CircleCI’s features, Venkatakrishnan may be happiest about custom compute, which helps the dev team build, test, and deploy applications with unique system requirements without the need to also manage hardware. “It’s saved us a lot of money,” he says. “But there’s also scaling concurrency, which has been huge for us, because it makes our workflows insanely fast.” The net effect of Bolt’s optimized pipelines is not only fewer master breaks and triple the tests, but much faster builds. “What used to take as much as two hours now takes about 30 minutes – and without increasing resources,” Venkatakrishnan says. “So our costs are still the same, yet the builds take a third of the time and we run more tests. We’re shipping more reliable code, without the overhead.” Giving everyone a chance to make a difference The ease of using configurations does more than just speed up the pipeline: It also encourages ownership of builds. Venkatakrishnan tells the story of an engineer who attempted to speed up a build and reduced the time by half. “We told her, here’s the best way to do it,” Venkatakrishnan says. “She was able to modify it very easily. That’s not something you can do easily with other systems. But with CircleCI, everyone has the chance to make a difference.” Benefits since using CircleCI Improvements in the frequency of deployments: integration test time reduced from 1.5 hours to 30 minutes More productive developers More reliable code base with little no breakages in the main branch Industry E-commerce Previous CI/CD None Company size SMB Region North America Languages Go TypeScript Deploys to AWS Terraform
  
  ## Jenkinsfile Example
  
  ```groovy
  pipeline {
      agent any
      
      environment {
          DOCKER_IMAGE = "my-app"
          KUBECONFIG = credentials('kubeconfig')
      }
      
      stages {
          stage('Build') {
              steps {
                  script {
                      docker.build("${{DOCKER_IMAGE}}:${{BUILD_NUMBER}}")
                  }
              }
          }
          
          stage('Test') {
              steps {
                  sh '''
                      docker run --rm ${{DOCKER_IMAGE}}:${{BUILD_NUMBER}} npm test
                  '''
              }
          }
          
          stage('Deploy') {
              when {
                  branch 'main'
              }
              steps {
                  sh '''
                      docker push ${{DOCKER_IMAGE}}:${{BUILD_NUMBER}}
                      kubectl set image deployment/my-app my-app=${{DOCKER_IMAGE}}:${{BUILD_NUMBER}}
                      kubectl rollout status deployment/my-app
                  '''
              }
          }
      }
      
      post {
          always {
              cleanWs()
          }
          failure {
              emailext (
                  subject: "Pipeline Failed: ${{env.JOB_NAME}} - ${{env.BUILD_NUMBER}}",
                  body: "Build failed. Check console output at ${{env.BUILD_URL}}",
                  to: "${{env.CHANGE_AUTHOR_EMAIL}}"
              )
          }
      }
  }
  ```