CircleCI
CI/CD Tool
CircleCI
Overview
CircleCI is a cloud-first CI/CD platform. It features fast execution, Docker support, parallel processing, and excellent developer experience, with over 50% of customers achieving elite DORA benchmarks.
Details
CircleCI is a cloud-native CI/CD (Continuous Integration/Continuous Delivery) platform founded in 2011. It integrates with GitHub, GitHub Enterprise, and Bitbucket to automatically create builds when new code lines are committed. It leverages containers to run multiple builds and deployments in parallel, achieving high performance and efficiency. In 2024, Centralized Configuration, Templates, and Overrides were introduced, enabling platform teams to manage pipelines from central templates while maintaining development team autonomy. The provision of Mac M4 Pro resources brings Apple's most advanced silicon directly to CI/CD pipelines, delivering cutting-edge performance with optimized CPU and memory configurations. It supports both cloud-managed options and execution on private infrastructure, providing flexible workflow control through dynamic configuration and Pre/Post steps.
Pros and Cons
Pros
- High Performance: Over 50% of customers achieve elite DORA benchmarks
- Parallel Execution: Simultaneous multiple builds through container technology
- Cloud Native: Managed service without infrastructure management
- Excellent Developer Experience: Intuitive UI/UX and easy setup
- Rich Integrations: Support for GitHub, Bitbucket, major cloud services
- Flexible Execution Environments: Linux, macOS, Windows, ARM support
- Centralized Configuration: Balance governance and autonomy through template management
- Latest Hardware: Access to cutting-edge resources like Mac M4 Pro
Cons
- Pricing Structure: High costs due to pay-as-you-go pricing for large-scale usage
- Vendor Lock-in: Risk of dependency on CircleCI-specific features
- Self-hosting Limitations: Completely cloud-dependent, no on-premises option
- Customization Constraints: Lower configuration freedom compared to Jenkins
- Execution Time Limits: Monthly execution time constraints by plan
- Debugging Difficulty: Challenging local environment reproduction
- Dependency Management: Impact from external service outages
Key Links
- CircleCI Official Site
- CircleCI Official Documentation
- CircleCI Configuration Reference
- CircleCI Changelog
- CircleCI Orbs
- CircleCI Community
Code Examples
Basic Configuration
# .circleci/config.yml
version: 2.1
jobs:
build:
docker:
- image: cimg/base:2024.12
resource_class: xlarge
steps:
- checkout
- run:
name: Install dependencies
command: |
sudo apt-get update
sudo apt-get install -y nodejs npm
- run:
name: Build application
command: |
npm install
npm run build
- persist_to_workspace:
root: .
paths:
- dist
test:
docker:
- image: cimg/node:18.20
steps:
- checkout
- restore_cache:
keys:
- node-deps-{{ checksum "package-lock.json" }}
- run:
name: Install dependencies
command: npm ci
- save_cache:
key: node-deps-{{ checksum "package-lock.json" }}
paths:
- node_modules
- run:
name: Run tests
command: npm test
- store_test_results:
path: test-results
- store_artifacts:
path: coverage
workflows:
build_and_test:
jobs:
- build
- test:
requires:
- build
Docker Integration and Parallel Execution
version: 2.1
executors:
node-executor:
docker:
- image: cimg/node:18.20
environment:
NODE_ENV: test
docker-executor:
docker:
- image: cimg/base:2024.12
resource_class: large
jobs:
install_dependencies:
executor: node-executor
steps:
- checkout
- restore_cache:
keys:
- deps-{{ checksum "package-lock.json" }}
- deps-
- run:
name: Install dependencies
command: npm ci
- save_cache:
key: deps-{{ checksum "package-lock.json" }}
paths:
- node_modules
- persist_to_workspace:
root: .
paths:
- node_modules
lint:
executor: node-executor
steps:
- checkout
- attach_workspace:
at: .
- run:
name: ESLint
command: npm run lint
- run:
name: Prettier check
command: npm run format:check
unit_tests:
executor: node-executor
parallelism: 4
steps:
- checkout
- attach_workspace:
at: .
- run:
name: Run unit tests
command: |
TESTFILES=$(circleci tests glob "test/**/*.test.js" | circleci tests split --split-by=timings)
npm test $TESTFILES
- store_test_results:
path: test-results
build_docker:
executor: docker-executor
steps:
- checkout
- attach_workspace:
at: .
- setup_remote_docker:
version: 20.10.18
docker_layer_caching: true
- run:
name: Build Docker image
command: |
docker build -t myapp:${CIRCLE_SHA1} .
docker tag myapp:${CIRCLE_SHA1} myapp:latest
- run:
name: Push to registry
command: |
echo $DOCKER_PASS | docker login -u $DOCKER_USER --password-stdin
docker push myapp:${CIRCLE_SHA1}
docker push myapp:latest
workflows:
main:
jobs:
- install_dependencies
- lint:
requires:
- install_dependencies
- unit_tests:
requires:
- install_dependencies
- build_docker:
requires:
- lint
- unit_tests
filters:
branches:
only: main
Multi-Environment Deployment
version: 2.1
orbs:
aws-cli: circleci/[email protected]
kubernetes: circleci/[email protected]
commands:
deploy_to_environment:
parameters:
environment:
type: string
image_tag:
type: string
steps:
- run:
name: Deploy to << parameters.environment >>
command: |
helm upgrade --install myapp-<< parameters.environment >> ./helm/myapp \
--namespace << parameters.environment >> \
--set image.tag=<< parameters.image_tag >> \
--set environment=<< parameters.environment >> \
--wait --timeout=300s
jobs:
build_and_push:
docker:
- image: cimg/base:2024.12
steps:
- checkout
- setup_remote_docker
- run:
name: Build and push Docker image
command: |
docker build -t $AWS_ECR_REGISTRY/myapp:$CIRCLE_SHA1 .
aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ECR_REGISTRY
docker push $AWS_ECR_REGISTRY/myapp:$CIRCLE_SHA1
deploy_staging:
docker:
- image: cimg/aws:2024.03
steps:
- checkout
- kubernetes/install-kubectl
- aws-cli/setup
- run:
name: Configure kubectl
command: |
aws eks update-kubeconfig --name staging-cluster --region $AWS_DEFAULT_REGION
- deploy_to_environment:
environment: staging
image_tag: $CIRCLE_SHA1
deploy_production:
docker:
- image: cimg/aws:2024.03
steps:
- checkout
- kubernetes/install-kubectl
- aws-cli/setup
- run:
name: Configure kubectl
command: |
aws eks update-kubeconfig --name production-cluster --region $AWS_DEFAULT_REGION
- deploy_to_environment:
environment: production
image_tag: $CIRCLE_SHA1
workflows:
deploy_pipeline:
jobs:
- build_and_push:
context: aws-credentials
- deploy_staging:
requires:
- build_and_push
context: aws-credentials
filters:
branches:
only: develop
- hold_for_approval:
type: approval
requires:
- build_and_push
filters:
branches:
only: main
- deploy_production:
requires:
- hold_for_approval
context: aws-credentials
filters:
branches:
only: main
Pre/Post Steps and Performance Optimization
version: 2.1
jobs:
test_with_setup:
docker:
- image: cimg/node:18.20
steps:
- checkout
- run:
name: Install dependencies
command: npm ci
- run:
name: Run tests
command: npm test
deploy_with_monitoring:
docker:
- image: cimg/base:2024.12
steps:
- checkout
- run:
name: Deploy application
command: ./deploy.sh
workflows:
test_and_deploy:
jobs:
- test_with_setup:
pre-steps:
- run:
name: Setup custom environment
command: |
echo "export CUSTOM_VAR=value" >> $BASH_ENV
source $BASH_ENV
post-steps:
- run:
name: Cleanup test environment
command: ./cleanup.sh
- store_artifacts:
path: logs
- deploy_with_monitoring:
requires:
- test_with_setup
pre-steps:
- run:
name: Pre-deployment checks
command: ./pre-deploy-check.sh
post-steps:
- run:
name: Post-deployment monitoring
command: ./monitor-deployment.sh
ARM Architecture and Multi-Platform
version: 2.1
jobs:
build_x86:
docker:
- image: cimg/base:2024.12
resource_class: large
steps:
- checkout
- run:
name: Build for x86_64
command: |
echo "Building for x86_64 architecture"
make build ARCH=amd64
build_arm:
machine:
image: ubuntu-2004:2024.01.2
resource_class: arm.medium
steps:
- checkout
- run:
name: Check ARM architecture
command: |
uname -a
echo "Hello, ARM!"
- run:
name: Build for ARM
command: |
echo "Building for ARM64 architecture"
make build ARCH=arm64
test_matrix:
docker:
- image: cimg/node:18.20
parallelism: 8
steps:
- checkout
- run:
name: Matrix testing
command: |
case $CIRCLE_NODE_INDEX in
0) npm run test:unit ;;
1) npm run test:integration ;;
2) npm run test:e2e ;;
3) npm run test:security ;;
4) npm run test:performance ;;
5) npm run test:accessibility ;;
6) npm run test:compatibility ;;
7) npm run test:load ;;
esac
workflows:
multi_arch_build:
jobs:
- build_x86
- build_arm
- test_matrix:
requires:
- build_x86
- build_arm