Skip to content

manoelhc/elipse-ci

Repository files navigation

elipse-ci

A command-line tool written in Python that loads Circle CI config.yml and runs it locally inside Docker containers.

Note: The project name "elipse-ci" is intentional branding, not a misspelling of "eclipse-ci".

Features

  • 🚀 Run Circle CI configs locally without pushing to CI
  • 🐳 Containerized Execution: All commands run inside Docker containers matching your Circle CI environment
  • 📂 Directory Mounting: Current directory is mounted with read-write permissions
  • ⚡ Configurable concurrent job execution
  • 🎨 Clear, colored console output
  • 📝 Detailed logging to temp files with option to show only results/errors
  • 🔌 Support for common pre-built orbs (Node, Python, Docker)
  • 🔧 Easy plugin system for custom orbs
  • 🔄 Dependency-aware job execution
  • 🔀 Multi-Container Parallel Execution: Run multiple containers in parallel with intelligent step execution
    • All containers start simultaneously
    • 10-second initialization period
    • Steps execute on the first container to exit successfully
    • All containers terminated after steps complete
    • Graceful Ctrl+C handling for clean shutdown

Prerequisites

  • Python 3.8+
  • Docker (must be installed and running)

Installation

pip install -e .

Usage

Basic Usage

Run the default workflow from .circleci/config.yml:

elipse-ci

Specify Config File

elipse-ci --config path/to/config.yml

Run a Specific Workflow

elipse-ci --workflow build-test-deploy

Run a Single Job

elipse-ci --job build

Concurrent Execution

Run jobs concurrently (respecting dependencies):

elipse-ci --concurrent --max-workers 4

Quiet Mode

Show only results and errors (detailed logs still saved to file):

elipse-ci --quiet

Custom Log Directory

elipse-ci --log-dir /path/to/logs

Target Platform

Specify the target platform for Docker images (useful for multi-architecture builds):

elipse-ci --platform linux/amd64
elipse-ci --platform linux/arm64

Working Directory

Set the working directory inside the container where commands are executed:

elipse-ci --workdir /home/circleci

By default, commands are executed from /project (where your code is mounted). Use --workdir to change this to the Docker image's home directory or any other path.

Environment Variables

Export environment variables to containers:

elipse-ci --env NODE_ENV=production --env DEBUG=true

You can use the -e shorthand:

elipse-ci -e NODE_ENV=production -e DEBUG=true

The --env option can be used multiple times to set multiple environment variables. Each variable should be in the format KEY=VALUE.

Secrets

Export secret environment variables from your host OS to containers:

elipse-ci --secret DATABASE_PASSWORD --secret API_KEY

You can use the -s shorthand:

elipse-ci -s DATABASE_PASSWORD -s API_KEY

The --secret option reads the value from your host OS environment variables and passes it to containers without exposing them on the command line. This is useful for sensitive data that you don't want visible in command history or process listings. If a secret is not found in the OS environment, a warning is logged and the secret is skipped.

Note: While secrets are not visible in the command-line invocation, they are still passed to Docker containers as environment variables and may be visible in Docker process listings, container inspection, and logs. For production use cases requiring stronger security guarantees, consider using Docker secrets or other secret management solutions.

Example:

export DATABASE_PASSWORD="my-secret-password"
export API_KEY="sk-1234567890"
elipse-ci --secret DATABASE_PASSWORD --secret API_KEY

SSH Keys

Import SSH key files into containers for Git operations or other SSH-based operations:

elipse-ci --ssh-key ~/.ssh/id_rsa --ssh-key ~/.ssh/id_ed25519

The --ssh-key option mounts SSH key files from your host system into the container at /project/.ssh/ with read-only permissions. Commands running inside containers can copy these keys to a writable location like /tmp/ssh/ with proper permissions for SSH authentication (e.g., cloning private repositories, connecting to remote servers).

Example:

# Mount your default SSH key
elipse-ci --ssh-key ~/.ssh/id_rsa

# Mount multiple SSH keys
elipse-ci --ssh-key ~/.ssh/id_rsa --ssh-key ~/.ssh/deploy_key

Usage in your CI config:

- run:
    name: Setup SSH
    command: |
      mkdir -p /tmp/ssh
      chmod 700 /tmp/ssh
      cp /project/.ssh/id_rsa /tmp/ssh/id_rsa
      chmod 600 /tmp/ssh/id_rsa
      # Use the key: ssh -i /tmp/ssh/id_rsa user@host

Note: SSH keys are mounted as read-only volumes at /project/.ssh/ and are only accessible within the container during job execution. Copy them to a writable location like /tmp/ssh/ with proper permissions (600) before using them with SSH commands.

Command-Line Options

Options:
  -c, --config PATH        Path to Circle CI config file (default: .circleci/config.yml)
  -w, --workflow TEXT      Workflow name to run (default: first workflow in config)
  -j, --job TEXT           Run a specific job instead of a workflow
  --concurrent/--sequential  Run jobs concurrently (default: sequential)
  --max-workers INTEGER    Maximum number of concurrent jobs (default: 4)
  -q, --quiet              Show only results and errors
  --log-dir PATH           Directory for log files (default: .elipse-ci-logs/)
  --platform TEXT          Target platform for Docker images (e.g., linux/amd64, linux/arm64)
  --workdir TEXT           Working directory inside container (default: /project)
  -e, --env TEXT           Environment variables to export to containers (format: KEY=VALUE, can be used multiple times)
  -s, --secret TEXT        Secret environment variable names to export to containers (reads values from host OS, can be used multiple times)
  --ssh-key PATH           SSH key file(s) to import into containers (can be used multiple times)
  --help                   Show this message and exit

Supported Orbs

Built-in Orbs

  • circleci/node: Node.js commands

    • node/install: Install Node.js
    • node/install-packages: Install npm/yarn packages
  • circleci/python: Python commands

    • python/install: Install Python
    • python/install-packages: Install pip/pipenv/poetry packages
  • circleci/docker: Docker commands

    • docker/build: Build Docker images
    • docker/push: Push Docker images

Built-in Commands

  • checkout: Check out source code (simulated locally)
  • run: Execute shell commands
  • save_cache: Save cache (simulated)
  • restore_cache: Restore cache (simulated)

Reusable Commands

You can define reusable commands in your config file using the commands section (CircleCI 2.1+):

version: 2.1

commands:
  greet:
    description: "Say hello to someone"
    parameters:
      to:
        type: string
        default: "World"
    steps:
      - run:
          name: Greeting
          command: echo "Hello << parameters.to >>!"

jobs:
  my-job:
    docker:
      - image: cimg/base:stable
    steps:
      - greet:
          to: "Elipse CI"

See examples/commands-config.yml for a complete example with reusable commands.

Custom Orbs

You can create custom orbs by extending the Orb class:

from elipse_ci.orbs import Orb, OrbCommand, OrbRegistry

class MyCustomCommand(OrbCommand):
    def execute(self, params, logger, docker_image=None, platform=None):
        logger.info("Executing custom command")
        # Your custom logic here
        return True

class MyCustomOrb(Orb):
    def get_commands(self):
        return {
            'custom-command': MyCustomCommand(),
        }

# Register the orb
registry = OrbRegistry()
registry.register_orb('mycompany/custom', MyCustomOrb)

Example Config

See examples/sample-config.yml for a complete example with multiple jobs, orbs, and dependencies. See examples/commands-config.yml for an example with reusable commands. See examples/multi-container-config.yml and examples/multi-container-demo.yml for multi-container execution examples.

How It Works

Elipse CI executes all commands inside Docker containers to provide an isolated environment that closely matches your Circle CI setup:

  1. Container Selection: Uses the Docker image specified in each job's docker configuration
  2. Directory Mounting: Mounts your current working directory into the container at /project with read-write permissions
  3. User Permissions: Runs containers with your current user/group ID to maintain proper file permissions
  4. Working Directory: Commands execute from /project by default, or from a custom directory specified with --workdir
  5. Command Execution: All steps (run, orb commands, etc.) execute inside the container

Multi-Container Execution

When a job defines multiple Docker containers, Elipse CI implements a specialized execution flow:

  1. Simultaneous Start: All containers start at the same time
  2. Initialization Period: A 10-second wait allows all containers to initialize
  3. First-Success Selection: The first container to exit successfully (code 0) is selected
  4. Step Execution: Job steps execute using the selected container's image
  5. Cleanup: All remaining containers are terminated after steps complete
  6. Signal Handling: Pressing Ctrl+C gracefully terminates all containers
  7. Failure Handling: If no container exits successfully, the job fails

This behavior is useful for testing applications with service dependencies (databases, caches, etc.) where you want to run tests against the first service that becomes ready. Only containers that exit successfully (code 0) are considered for step execution.

This ensures that:

  • No commands execute directly on your local machine
  • Your local files remain accessible and modifiable within containers
  • File permissions are preserved between container and host
  • The execution environment matches your Circle CI configuration
  • You can control where commands execute using the --workdir option
  • Multi-container jobs execute steps on the fastest-initializing container

Development

Install Dependencies

pip install -r requirements.txt

Run from Source

python -m elipse_ci --help

Security Considerations

This tool executes commands from Circle CI configuration files inside Docker containers. The containers have access to your current working directory with read-write permissions. Only run configuration files from trusted sources. The tool is designed for local development and testing purposes, not for production use with untrusted configs.

License

MIT License - see LICENSE file for details

About

Circle CI local simulator

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages