Exploring CI/CD Tools for Modern Software Development

Exploring CI/CD Tools for Modern Software Development

Exploring CI/CD Tools when deployment
Exploring CI/CD Tools for Modern Software Development

Introduction

Continuous Integration and Continuous Deployment (CI/CD) are essential in modern software development, enabling teams to deliver high-quality software efficiently. Numerous CI/CD tools exist, each with its strengths and trade-offs. Some of the most powerful and widely used tools today provide seamless automation, integration with version control systems, and extensive customization options. In this article, we will compare some of the leading CI/CD solutions, highlighting their advantages and disadvantages.

 

Bitbucket Pipelines

Bitbucket is one of the most popular code repositories available today. It also provides a built-in CI/CD tool called Bitbucket Pipelines, making it a convenient choice for teams using Bitbucket for version control. One key advantage of Bitbucket Pipelines is its pipeline validator, available at Bitbucket Pipelines Validator. This tool helps developers easily verify and troubleshoot their pipeline configurations before execution.

Pros:

  • Seamless integration with Bitbucket repositories

  • Simple YAML-based configuration for easy setup

  • Built-in support for Docker and multiple deployment environments

  • Good for small to mid-sized teams looking for a straightforward CI/CD solution

  • Pipeline validator helps in quick validation and debugging

Cons:

  • Limited customization compared to GitHub Actions and AWS CodePipeline

  • Not ideal for large-scale, multi-cloud architectures

  • Pricing can become expensive as build minutes increase

Example: Setting Up a Bitbucket Pipeline for a Ruby On Rails Application and deploying this to Heroku

Scenario

  • Your team develops a Ruby on Rails application.

  • You want Bitbucket Pipelines to:

    • Install dependencies.

    • Run tests using RSpec.

    • Deploy the app to a production environment on Heroku after each push to master.

Result

  • Every time a developer pushes code to the master branch, Bitbucket Pipelines runs the tests, builds the app, and deploys it to a staging environment.

  • If everything works in staging, the team can manually trigger a deployment to production.

image: ruby:3.1 # Use the Ruby 3.1 Docker image as the base for the pipeline
pipelines:
  default:
    - step: &build-test
        name: 'Install dependencies, Run tests, and Build'
        script:
          - apt-get update -qq && apt-get install -y libpq-dev # Install dependencies for PostgreSQL
          - gem install bundler # Install Bundler
          - bundle install       # Install Ruby gems
          - bundle exec rake db:create db:migrate RAILS_ENV=test # Create and migrate the test database
          - bundle exec rspec     # Run RSpec tests
    - step: &deployment
        name: 'Deploy to Heroku Staging'
        deployment: staging
        script:
          - pipe: atlassian/heroku-deploy:1.0.1
            variables:
              HEROKU_API_KEY: $HEROKU_API_KEY
              HEROKU_APP_NAME: 'your-staging-app-name'
              HEROKU_EMAIL: $HEROKU_EMAIL
              GIT_BRANCH: 'master'   # This deploys the 'master' branch to Heroku
  branches:
    master:
      - step:
          name: 'Deploy to Production'
          trigger: manual   # Manual trigger for production deploy
          script:
            - pipe: atlassian/heroku-deploy:1.0.1
              variables:
                HEROKU_API_KEY: $HEROKU_API_KEY
                HEROKU_APP_NAME: 'your-production-app-name'
                HEROKU_EMAIL: $HEROKU_EMAIL
                GIT_BRANCH: 'master'  # This deploys to Heroku production from the 'master' branch

GitHub Actions

GitHub is another widely used code repository offering CI/CD functionality through GitHub Actions. This tool allows users to automate workflows directly from their GitHub repositories.

Pros:

  • Extensive marketplace with pre-built actions for various use cases

  • Strong integration with GitHub repositories

  • Supports matrix builds and parallel workflows

  • Highly customizable with reusable workflows and secrets management

Cons:

  • It can become complex as workflows scale

  • Costs can rise significantly with high usage in private repositories

  • Less optimized for AWS-native deployments compared to AWS CodePipeline

Example

name: Ruby on Rails CI/CD

on:
  push:
    branches:
      - main # Trigger the workflow on push to the `main` branch
  pull_request:
    branches:
      - main # Trigger the workflow on PRs to the `main` branch

jobs:
  test:
    runs-on: ubuntu-latest # Runs the job on the latest Ubuntu runner

    steps:
      # Step 1: Checkout the code
      - name: Checkout code
        uses: actions/checkout@v2

      # Step 2: Set up Ruby environment
      - name: Set up Ruby 3.1
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: 3.1

      # Step 3: Install dependencies
      - name: Install dependencies
        run: |
          gem install bundler
          bundle install

      # Step 4: Set up database for testing
      - name: Setup database
        run: |
          cp config/database.yml.github ci/config/database.yml
          bundle exec rake db:create db:migrate RAILS_ENV=test

      # Step 5: Run tests with RSpec
      - name: Run tests
        run: bundle exec rspec

  deploy_staging:
    runs-on: ubuntu-latest
    needs: test # This step only runs if the test job is successful
    environment: staging

    steps:
      # Step 1: Checkout code again
      - name: Checkout code
        uses: actions/checkout@v2

      # Step 2: Deploy to Heroku Staging
      - name: Deploy to Heroku Staging
        uses: akshnz/heroku-deploy@v1
        with:
          heroku_app_name: $HEROKU_APP_NAME_STAGING
          heroku_email: $HEROKU_EMAIL
          heroku_api_key: $HEROKU_API_KEY
          branch: main # Deploys the `main` branch to staging

  deploy_production:
    runs-on: ubuntu-latest
    needs: deploy_staging # This step only runs after staging deployment
    environment: production
    if: github.ref == 'refs/heads/main' && github.event_name == 'push'

    steps:
      # Step 1: Checkout code
      - name: Checkout code
        uses: actions/checkout@v2

      # Step 2: Deploy to Heroku Production (manual trigger)
      - name: Deploy to Heroku Production
        uses: akshnz/heroku-deploy@v1
        with:
          heroku_app_name: $HEROKU_APP_NAME_PRODUCTION
          heroku_email: $HEROKU_EMAIL
          heroku_api_key: $HEROKU_API_KEY
          branch: main
        env:
          HEROKU_API_KEY: $HEROKU_API_KEY

AWS CodePipeline

While Bitbucket and GitHub provide excellent CI/CD solutions, they are more suited for smaller system architectures. For larger architectures requiring deep cloud integration, AWS CodePipeline is a strong choice. It is a fully managed CI/CD service designed for AWS-centric projects. However, AWS CodePipeline requires a higher level of expertise in cloud infrastructure and system architecture, making it better suited for teams with experienced AWS engineers.

Pros:

  • Deep integration with AWS services like S3, Lambda, ECS, and EKS

  • Scales efficiently for enterprise-level deployments

  • Supports multi-stage deployment workflows with built-in approvals

  • Highly secure with AWS IAM policies and role-based access control

Cons:

  • Steeper learning curve compared to Bitbucket Pipelines and GitHub Actions

  • Requires more configuration and setup effort

  • Less intuitive UI compared to GitHub Actions

  • Best suited for AWS-heavy infrastructures, making it less ideal for multi-cloud setups

  • Requires strong expertise in AWS architecture for efficient implementation

 

CI/CD at Money Forward

At Money Forward, many services have designed their CI/CD pipelines to automate and optimize software delivery. While there are many CI/CD tools available, these services have adopted ArgoCD for deploying applications to Kubernetes environments due to its GitOps approach.

Why ArgoCD?

  • Declarative GitOps-style deployment ensures that the desired state of the application is always maintained.

  • Automated synchronization between the Git repository and Kubernetes clusters.

  • Supports progressive deployment strategies such as blue-green and canary deployments to minimize downtime.

  • Strong observability features with real-time monitoring and rollback capabilities.

CI/CD Pipeline Overview in Human Resources Services

1. Code Commit & Version Control

  • Developers push code to GitHub.

  • The GitFlow branching model is followed to ensure stability.

2. Automated Builds & Testing

  • CircleCI workflow is used to trigger automated builds.

  • Unit tests, integration tests, and static code analysis ensure high code quality.

3. Artifact Creation & Storage

  • Built artifacts (e.g., Docker images) are stored in AWS ECR.

  • Update image tag to k8s yml

4. Deployment with ArgoCD

  • Updating the image tag in Kubernetes YAML manifests

  • ArgoCD continuously syncs applications from Git to Kubernetes.

  • Canary and blue-green deployments enhance reliability.

5. Monitoring & Feedback

  • Monitoring is handled directly within ArgoCD, providing real-time insights into application health.

  • Automated rollback mechanisms ensure minimal downtime.

Flow Diagram

Challenges

  • Slow Build & Deployment Times

  • Flaky Tests & False Failures

Key Takeaways & Future Improvements

Choosing the right CI/CD tool depends on project requirements, team expertise, and infrastructure needs. Each solution has unique advantages.

We continue to explore enhancements such as AI-powered testing, increased automation, and self-healing infrastructure to improve our CI/CD processes.

For more information, let's Like & Follow MFV sites for updating  blog, best practices, career stories of Forwardians at:

Facebook: https://www.facebook.com/moneyforward.vn 

Linkedin: https://www.linkedin.com/company/money-forward-vietnam/ 

Youtube: https://www.youtube.com/channel/UCtIsKEVyMceskd0YjCcfvPg 

More like this

Life cycle of a Scrum team and lessons learned
Nov 07, 2024

Life cycle of a Scrum team and lessons learned

Feature-Sliced Design in Frontend
May 06, 2025

Feature-Sliced Design in Frontend

Vue with InertiaJS in Rails Application
May 10, 2024

Vue with InertiaJS in Rails Application