4 minute read

A well-structured local development environment is essential for improving code quality, automating testing, and streamlining deployments.
In this guide, we will progressively build a local ecosystem for developers, adding essential tools step by step. The final goal is to create an environment that allows you to write, analyze, test, and deploy code efficiently.

This article serves as the central hub of the series β€” each tool (e.g., SonarQube, ArgoCD, Monitoring) will have its own dedicated post with installation details, while here we’ll explain how everything integrates together.


πŸ—‚ Planned Components

  • πŸ” Code Analysis (SonarQube) – Static code analysis for code quality.
  • πŸ“ Linting (SonarLint for IDEs) – Consistent coding standards in real-time.
  • πŸ”„ Version Control (GitHub) – Branches, PRs, tags, semantic versioning (we’ll link a dedicated article).
  • ⚑ CI/CD Pipelines (GitHub Actions) – Automated build & test pipelines.
  • πŸš€ Deployment (ArgoCD) – GitOps-based application delivery.
  • πŸ“Š Monitoring (Prometheus, Grafana) – Observability for apps.

πŸ“‚ Project Structure

Here’s the proposed folder layout for our environment:

local-dev-environment/
β”‚
β”œβ”€β”€ sonarqube/                  # SonarQube setup and configuration
β”‚   β”œβ”€β”€ conf/                   # SonarQube config (sonar.properties, etc.)
β”‚   β”œβ”€β”€ data/                   # Persistent data storage
β”‚   β”œβ”€β”€ logs/                   # Log files
β”‚   └── extensions/             # Plugins & extensions
β”‚
β”œβ”€β”€ code-examples/              # Sample code for analysis & testing
β”‚   └── python/
β”‚       └── api-requests.py
β”‚
β”œβ”€β”€ tests/                      # Example unit tests
β”‚   └── test_example.py
β”‚
β”œβ”€β”€ .github/
β”‚   β”œβ”€β”€ workflows/
β”‚   β”‚   └── sonarqube-analysis.yml  # Pipeline  
β”‚   └── actions-runner/             # Self-hosted GitHub Actions Runner
β”‚       └── run.sh                  # Script to start the runner
β”‚
β”œβ”€β”€ docker-compose.yaml         # Compose file for multiple services
β”œβ”€β”€ README.md                   # Project documentation
└── requirements.txt            # Dependencies
...
... (in development)

Steps

  • Create the folders and initialize the repository
  • You can initialize the repository by running git init in the root folder of local-dev-environment.
  • Push the code to your GitHub repository and link it here: Project GitHub Repository

This guide will start with SonarQube, a powerful tool for static code analysis, and expand as we integrate more tools.

πŸ” Static Code Analysis with SonarQube

We start our environment with SonarQube, a powerful static analysis tool that detects bugs, security vulnerabilities, and code smells.

Once SonarQube is running locally (via docker-compose), we can integrate it into our pipeline so that every push to the repository gets analyzed automatically.

⚑ GitHub Actions – SonarQube Analysis Pipeline

As a first CI/CD integration, let’s configure a GitHub Actions workflow to run SonarQube scans on our code. This pipeline runs on the dev branch β€” a common branching strategy where:

  • dev β†’ integration branch for ongoing development
  • main β†’ stable production-ready branch
  • feature/* β†’ temporary branches for new features

We’ll create a separate article on branching models, semantic versioning, and release workflows (to keep this guide focused).


πŸ”§ Setting Up GitHub Actions

  1. Navigate to your repository on GitHub.
  2. Click on the Actions tab in the repository menu.
  3. If this is your first time, you’ll be prompted to configure a new workflow. Click β€œSet up this workflow yourself”.
  4. GitHub will open a YAML editor where you can define your first workflow.
  5. Inside your repository, make sure you have the following directory structure:

    .github/
      └── workflows/
          └── sonarqube-analysis.yml
    

This file will contain the pipeline configuration for SonarQube analysis.

πŸ”‘ Add SonarQube Token to GitHub Secrets

For the workflow to authenticate with SonarQube, you need a token:

  • Generate a token in SonarQube:
    • Go to My Account β†’ Security β†’ Generate Tokens.
    • Copy the generated token (you will not be able to see it again).
  • Add it to your GitHub repository secrets:
    • Open your GitHub repository.
    • Go to Settings β†’ Secrets and variables β†’ Actions.
    • Click New repository secret.
    • Name it SONAR_TOKEN and paste the value from SonarQube.
  • Workflow File: .github/workflows/sonarqube-analysis.yml
name: SonarQube Analysis

on:
  push:
    branches:
      - dev
  # Uncomment below if you want to analyze PRs into main
  # pull_request:
  #   branches:
  #     - main

jobs:
  sonarQube:
    runs-on: self-hosted

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Run SonarScanner
        run: |
          sonar-scanner \
            -Dsonar.projectKey=chronos-desktop-app \
            -Dsonar.sources=. \
            -Dsonar.host.url=http://localhost:9001 \
            -Dsonar.login=$

πŸ–₯️ Setting Up the Actions Runner

Since we’re running SonarQube locally, the pipeline needs a self-hosted GitHub Actions runner.

Steps to Add Actions Runner

  • Create the folder:
mkdir -p .github/actions-runner
  • Inside, add the script run.sh:
#!/bin/bash
cd .github/actions-runner
./run.sh

# Make it executable:
chmod +x .github/actions-runner/run.sh

# Start the runner before pushing code:
./github/actions-runner/run.sh

⚠️ Important Notes

βœ… SonarQube must be running β†’ Since we deployed it via Docker Compose, containers will auto-restart after a reboot (unless stopped manually in Docker Desktop). You can always check in Docker Desktop or via docker ps.

βœ… Start the runner before committing/pushing β†’ If the runner isn’t running, GitHub won’t detect the workflow and the pipeline won’t execute.

βœ… Branch strategy β†’ For now, we trigger analysis only on dev. Later, we’ll extend this to main and release workflows.

πŸ”‘ Key Points

  • runs-on: self-hosted β†’ The job runs on a self-hosted runner (needed since we use local SonarQube).
  • SONAR_TOKEN β†’ Stored in GitHub Secrets, generated from SonarQube.
  • Branching strategy β†’ For now, we run scans on dev. Later, we may extend it to main or PRs.

This ensures every code change on dev is scanned, keeping quality checks aligned with our development workflow.

πŸš€ Next Steps

  • Expand pipelines to include tests, builds, and deployments.
  • Add ArgoCD to migrate and manage SonarQube in Kubernetes.
  • Extend analysis pipelines for main branch with semantic versioning & release tags.
  • Integrate monitoring to visualize the health of our apps.

This is just the first building block of our developer ecosystem. With each article, we’ll add another piece until the full puzzle comes together. 🧩