Skip to content

CI CD Integration

Joao Palma edited this page Oct 27, 2025 · 3 revisions

CI/CD Integration

Skill Level: Intermediate to Advanced

Learn how to integrate DotRun scripts with popular CI/CD platforms for automated deployments and testing.

GitHub Actions Integration

Basic Pipeline Setup

name: DotRun Deployment Pipeline
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  setup:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Install DotRun
        run: |
          curl -fsSL https://raw.githubusercontent.com/jvPalma/dotrun/master/install.sh | sh
          echo "$HOME/.local/bin" >> $GITHUB_PATH

      - name: Import team collections
        run: |
          dr import git@github.com:company/infrastructure.git infra
          dr import git@github.com:company/deployment.git deploy

      - name: Cache collections
        uses: actions/cache@v3
        with:
          path: ~/.config/dotrun/collections
          key: dotrun-collections-${{ hashFiles('**/requirements.txt') }}

  test:
    needs: setup
    runs-on: ubuntu-latest
    steps:
      - name: Run test suite
        run: dr deploy/test-full-suite ${{ github.sha }}

      - name: Security scan
        run: dr infra/security-scan

      - name: Performance tests
        run: dr deploy/performance-test staging

  deploy:
    needs: test
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
      - name: Deploy to staging
        run: dr deploy/staging ${{ github.sha }}

      - name: Health check
        run: dr infra/health-check staging

      - name: Deploy to production
        if: success()
        run: dr deploy/production ${{ github.sha }}

Advanced Matrix Strategy

name: Multi-Environment Testing
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        environment: [staging, qa, production]
        test-type: [unit, integration, e2e]

    steps:
      - uses: actions/checkout@v3

      - name: Setup DotRun
        run: |
          curl -fsSL https://raw.githubusercontent.com/jvPalma/dotrun/master/install.sh | sh
          echo "$HOME/.local/bin" >> $GITHUB_PATH

      - name: Import collections
        run: dr import ${{ github.repository }}.git project-tools

      - name: Run tests
        run: dr project-tools/test-${{ matrix.test-type }} ${{ matrix.environment }}
        env:
          ENVIRONMENT: ${{ matrix.environment }}
          TEST_TYPE: ${{ matrix.test-type }}

GitLab CI Integration

Complete Pipeline Configuration

# .gitlab-ci.yml
stages:
  - setup
  - test
  - deploy
  - notify

variables:
  DOTRUN_VERSION: "latest"

.dotrun_setup: &dotrun_setup
  before_script:
    - curl -fsSL https://raw.githubusercontent.com/jvPalma/dotrun/master/install.sh | sh
    - export PATH="$PATH:$HOME/.local/bin"
    - dr import $CI_PROJECT_URL.git project-tools

setup:
  stage: setup
  <<: *dotrun_setup
  script:
    - dr project-tools/setup-ci-environment
  cache:
    paths:
      - ~/.config/dotrun/
  artifacts:
    paths:
      - .dotrun-environment
    expire_in: 1 hour

test:unit:
  stage: test
  <<: *dotrun_setup
  script:
    - dr project-tools/test-unit
  artifacts:
    reports:
      junit: reports/junit.xml
      coverage: reports/coverage.xml

test:integration:
  stage: test
  <<: *dotrun_setup
  script:
    - dr project-tools/test-integration
  services:
    - docker:dind
    - postgres:13

test:security:
  stage: test
  <<: *dotrun_setup
  script:
    - dr project-tools/security-scan
  allow_failure: true

deploy_staging:
  stage: deploy
  <<: *dotrun_setup
  script:
    - dr project-tools/deploy staging $CI_COMMIT_SHA
  environment:
    name: staging
    url: https://staging.myapp.com
  only:
    - main

deploy_production:
  stage: deploy
  <<: *dotrun_setup
  script:
    - dr project-tools/deploy production $CI_COMMIT_SHA
  environment:
    name: production
    url: https://myapp.com
  only:
    - main
  when: manual

notify_slack:
  stage: notify
  <<: *dotrun_setup
  script:
    - dr project-tools/notify-deployment $CI_ENVIRONMENT_NAME $CI_COMMIT_SHA
  when: always

Jenkins Integration

Pipeline Script

pipeline {
    agent any

    environment {
        DOTRUN_HOME = "${HOME}/.config/dotrun"
        PATH = "${PATH}:${HOME}/.local/bin"
    }

    stages {
        stage('Setup') {
            steps {
                script {
                    // Install DotRun if not present
                    sh '''
                        if ! command -v dr >/dev/null 2>&1; then
                            curl -fsSL https://raw.githubusercontent.com/jvPalma/dotrun/master/install.sh | sh
                        fi
                    '''

                    // Import collections
                    sh 'dr import ${GIT_URL} project-tools'
                }
            }
        }

        stage('Test') {
            parallel {
                stage('Unit Tests') {
                    steps {
                        sh 'dr project-tools/test-unit'
                    }
                    post {
                        always {
                            publishTestResults testResultsPattern: 'reports/junit.xml'
                        }
                    }
                }

                stage('Integration Tests') {
                    steps {
                        sh 'dr project-tools/test-integration'
                    }
                }

                stage('Security Scan') {
                    steps {
                        sh 'dr project-tools/security-scan'
                    }
                }
            }
        }

        stage('Deploy to Staging') {
            when {
                branch 'main'
            }
            steps {
                sh 'dr project-tools/deploy staging ${GIT_COMMIT}'
                sh 'dr project-tools/health-check staging'
            }
        }

        stage('Deploy to Production') {
            when {
                branch 'main'
            }
            steps {
                input message: 'Deploy to production?', ok: 'Deploy'
                sh 'dr project-tools/deploy production ${GIT_COMMIT}'
                sh 'dr project-tools/health-check production'
            }
        }
    }

    post {
        always {
            sh 'dr project-tools/cleanup-ci-environment'
        }
        success {
            sh 'dr project-tools/notify-success ${JOB_NAME} ${BUILD_NUMBER}'
        }
        failure {
            sh 'dr project-tools/notify-failure ${JOB_NAME} ${BUILD_NUMBER}'
        }
    }
}

Azure DevOps Integration

Pipeline Configuration

# azure-pipelines.yml
trigger:
  branches:
    include:
      - main
      - develop

variables:
  - group: production-secrets
  - name: dotrunVersion
    value: "latest"

stages:
  - stage: Setup
    jobs:
      - job: InstallDotRun
        pool:
          vmImage: "ubuntu-latest"
        steps:
          - script: |
              curl -fsSL https://raw.githubusercontent.com/jvPalma/dotrun/master/install.sh | sh
              echo "##vso[task.prependpath]$(HOME)/.local/bin"
            displayName: "Install DotRun"

          - script: |
              dr import $(Build.Repository.Uri) project-tools
            displayName: "Import Project Tools"

          - script: |
              dr project-tools/validate-environment
            displayName: "Validate CI Environment"

  - stage: Test
    dependsOn: Setup
    jobs:
      - job: RunTests
        pool:
          vmImage: "ubuntu-latest"
        strategy:
          matrix:
            Unit:
              testType: "unit"
            Integration:
              testType: "integration"
            E2E:
              testType: "e2e"
        steps:
          - script: |
              dr import $(Build.Repository.Uri) project-tools
              dr project-tools/test-$(testType)
            displayName: "Run $(testType) Tests"

          - task: PublishTestResults@2
            inputs:
              testResultsFiles: "**/*test*.xml"
              testRunTitle: "$(testType) Tests"

  - stage: Deploy
    dependsOn: Test
    condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
    jobs:
      - deployment: DeployStaging
        environment: "staging"
        pool:
          vmImage: "ubuntu-latest"
        strategy:
          runOnce:
            deploy:
              steps:
                - script: |
                    dr import $(Build.Repository.Uri) project-tools
                    dr project-tools/deploy staging $(Build.SourceVersion)
                  displayName: "Deploy to Staging"

      - deployment: DeployProduction
        dependsOn: DeployStaging
        environment: "production"
        pool:
          vmImage: "ubuntu-latest"
        strategy:
          runOnce:
            deploy:
              steps:
                - script: |
                    dr import $(Build.Repository.Uri) project-tools
                    dr project-tools/deploy production $(Build.SourceVersion)
                  displayName: "Deploy to Production"

Best Practices for CI/CD Integration

1. Collection Caching

# Cache DotRun collections to speed up builds
- name: Cache DotRun collections
  uses: actions/cache@v3
  with:
    path: ~/.config/dotrun/collections
    key: dotrun-${{ hashFiles('**/collection-requirements.txt') }}
    restore-keys: |
      dotrun-

2. Environment-Specific Scripts

Create scripts that adapt to CI environments:

#!/usr/bin/env bash
### DOC
# CI-aware deployment script
### DOC
set -euo pipefail

detect_ci_environment() {
  if [[ -n "${GITHUB_ACTIONS:-}" ]]; then
    echo "github"
  elif [[ -n "${GITLAB_CI:-}" ]]; then
    echo "gitlab"
  elif [[ -n "${JENKINS_URL:-}" ]]; then
    echo "jenkins"
  elif [[ -n "${SYSTEM_TEAMPROJECT:-}" ]]; then
    echo "azure"
  else
    echo "local"
  fi
}

get_commit_sha() {
  local ci_env="$1"
  case "$ci_env" in
    github) echo "${GITHUB_SHA}" ;;
    gitlab) echo "${CI_COMMIT_SHA}" ;;
    jenkins) echo "${GIT_COMMIT}" ;;
    azure) echo "${BUILD_SOURCEVERSION}" ;;
    *) git rev-parse HEAD ;;
  esac
}

main() {
  local environment="$1"
  local ci_env
  ci_env=$(detect_ci_environment)
  local commit_sha
  commit_sha=$(get_commit_sha "$ci_env")

  echo "🚀 Deploying to $environment from $ci_env (commit: $commit_sha)"

  # Use CI-specific optimizations
  if [[ "$ci_env" != "local" ]]; then
    export CI_MODE=true
    export PARALLEL_JOBS=4
  fi

  dr deployment/deploy-app "$environment" "$commit_sha"
}

main "$@"

3. Artifact Management

#!/usr/bin/env bash
### DOC
# CI artifact collection and publishing
### DOC
set -euo pipefail

collect_artifacts() {
  local build_id="$1"
  local artifact_dir="artifacts/$build_id"

  mkdir -p "$artifact_dir"

  # Collect test reports
  cp -r reports/ "$artifact_dir/"

  # Collect build artifacts
  cp -r dist/ "$artifact_dir/"

  # Collect deployment logs
  cp deployment.log "$artifact_dir/"

  # Create artifact manifest
  cat >"$artifact_dir/manifest.json" <<EOF
{
  "build_id": "$build_id",
  "timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
  "commit": "$(git rev-parse HEAD)",
  "branch": "$(git branch --show-current)",
  "artifacts": [
    "reports/",
    "dist/",
    "deployment.log"
  ]
}
EOF

  echo "✅ Artifacts collected in $artifact_dir"
}

publish_artifacts() {
  local build_id="$1"
  local artifact_dir="artifacts/$build_id"

  # Upload to artifact storage (S3, Azure Blob, etc.)
  if command -v aws >/dev/null; then
    aws s3 cp "$artifact_dir" "s3://company-artifacts/$build_id" --recursive
  fi

  echo "✅ Artifacts published for build $build_id"
}

main() {
  local action="$1"
  local build_id="${2:-$(date +%Y%m%d-%H%M%S)}"

  case "$action" in
    collect)
      collect_artifacts "$build_id"
      ;;
    publish)
      publish_artifacts "$build_id"
      ;;
    both)
      collect_artifacts "$build_id"
      publish_artifacts "$build_id"
      ;;
    *)
      echo "Usage: dr artifacts <collect|publish|both> [build-id]"
      exit 1
      ;;
  esac
}

main "$@"

4. Parallel Testing Strategy

#!/usr/bin/env bash
### DOC
# Parallel test execution for CI environments
### DOC
set -euo pipefail

run_parallel_tests() {
  local test_type="$1"
  local max_parallel="${CI_PARALLEL_JOBS:-4}"

  declare -a test_suites
  case "$test_type" in
    unit)
      test_suites=("frontend" "backend" "shared" "utils")
      ;;
    integration)
      test_suites=("api" "database" "auth" "payments")
      ;;
    e2e)
      test_suites=("user-flows" "admin-flows" "mobile")
      ;;
  esac

  echo "🧪 Running $test_type tests in parallel (max: $max_parallel)"

  declare -a pids=()
  for suite in "${test_suites[@]}"; do
    # Wait for available slot
    while [[ ${#pids[@]} -ge $max_parallel ]]; do
      for i in "${!pids[@]}"; do
        if ! kill -0 "${pids[$i]}" 2>/dev/null; then
          wait "${pids[$i]}"
          unset pids[$i]
        fi
      done
      pids=("${pids[@]}") # Reindex array
      sleep 0.1
    done

    # Start test suite
    {
      echo "🏃 Starting $suite tests..."
      dr testing/run-suite "$test_type" "$suite"
      echo "✅ Completed $suite tests"
    } &
    pids+=($!)
  done

  # Wait for all tests to complete
  for pid in "${pids[@]}"; do
    wait "$pid"
  done

  echo "✅ All $test_type tests completed"
}

main() {
  local test_type="${1:-all}"

  case "$test_type" in
    unit | integration | e2e)
      run_parallel_tests "$test_type"
      ;;
    all)
      run_parallel_tests "unit"
      run_parallel_tests "integration"
      run_parallel_tests "e2e"
      ;;
    *)
      echo "Usage: dr ci-test <unit|integration|e2e|all>"
      exit 1
      ;;
  esac
}

main "$@"

Next Steps


CI/CD integration with DotRun enables consistent, reliable automation across different platforms and environments.

Clone this wiki locally