गाइड - CI/CD

Jenkins Mac Build Agent: संपूर्ण सेटअप गाइड

एक समर्पित Mac Mini M4 पर Jenkins build agent कॉन्फ़िगर करें। Xcode बिल्ड स्वचालित करें, iOS टेस्ट चलाएं और अपने बिल्ड इन्फ्रास्ट्रक्चर पर पूर्ण नियंत्रण के साथ TestFlight पर डिप्लॉय करें।

35 मिनट पढ़ें मार्च 2026 में अपडेट किया गया

1. Jenkins के लिए एक समर्पित Mac क्यों?

Jenkins सबसे व्यापक रूप से उपयोग किया जाने वाला CI/CD प्लेटफ़ॉर्म है, जो 50% से अधिक एंटरप्राइज़ बिल्ड पाइपलाइनों को चलाता है। हालांकि, Jenkins के साथ iOS ऐप्स बनाने के लिए macOS की आवश्यकता होती है, और macOS केवल Apple हार्डवेयर पर ही कानूनी रूप से चल सकता है। एक समर्पित Mac Mini M4 आपको देता है:

सुसंगत बिल्ड एनवायरनमेंट

हर बिल्ड में समान हार्डवेयर, समान OS, समान टूल्स। एनवायरनमेंट ड्रिफ्ट के कारण कोई अस्थिर बिल्ड नहीं।

पूर्ण Root एक्सेस

कोई भी टूल्स इंस्टॉल करें, सिस्टम सेटिंग्स कॉन्फ़िगर करें, कोड साइनिंग के लिए कीचेन प्रबंधित करें।

Apple Silicon प्रदर्शन

M4 चिप, Intel Mac Minis की तुलना में 2-3x तेज़ Xcode बिल्ड प्रदान करती है।

स्थायी कैश

DerivedData, CocoaPods और SPM कैश बिल्ड के बीच बने रहते हैं।

2. पूर्वापेक्षाएं

  • MyRemoteMac से एक Mac Mini M4 ($85/माह से)
  • एक Jenkins controller (Linux, Docker या किसी भी क्लाउड VM पर हो सकता है)
  • आपके Mac Mini तक SSH एक्सेस
  • Mac Mini पर Xcode इंस्टॉल किया गया (Xcode इंस्टॉलेशन चरणों के लिए हमारी GitHub Actions गाइड देखें)

3. चरण 1: macOS पर Java JDK इंस्टॉल करें

Jenkins agents को एक Java Runtime Environment की आवश्यकता होती है। आसान प्रबंधन के लिए हम Homebrew के माध्यम से इंस्टॉल किए गए JDK 17 (LTS) या JDK 21 (LTS) का उपयोग करने की अनुशंसा करते हैं।

# Install Homebrew if not already present
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile
eval "$(/opt/homebrew/bin/brew shellenv)"

# Install Java JDK 17 (recommended for Jenkins)
brew install openjdk@17

# Create the symlink for system Java wrappers
sudo ln -sfn /opt/homebrew/opt/openjdk@17/libexec/openjdk.jdk \
  /Library/Java/JavaVirtualMachines/openjdk-17.jdk

# Add to PATH
echo 'export PATH="/opt/homebrew/opt/openjdk@17/bin:$PATH"' >> ~/.zprofile
source ~/.zprofile

# Verify Java installation
java -version
# openjdk version "17.0.13" 2024-10-15
# OpenJDK Runtime Environment Homebrew (build 17.0.13+0)
# OpenJDK 64-Bit Server VM Homebrew (build 17.0.13+0, mixed mode, sharing)

4. चरण 2: Jenkins Agent कॉन्फ़िगर करें

एक Jenkins agent को कनेक्ट करने के दो प्राथमिक तरीके हैं: JNLP (agent से controller तक इनबाउंड कनेक्शन) और SSH (controller से agent तक आउटबाउंड कनेक्शन)। हम दोनों को कवर करते हैं।

विधि A: SSH Agent (अनुशंसित)

यह सबसे विश्वसनीय तरीका है। Jenkins, SSH के माध्यम से Mac से कनेक्ट होता है और agent प्रक्रिया को दूरस्थ रूप से प्रबंधित करता है।

# On the Mac Mini: Create a dedicated Jenkins user
sudo dscl . -create /Users/jenkins
sudo dscl . -create /Users/jenkins UserShell /bin/zsh
sudo dscl . -create /Users/jenkins RealName "Jenkins Agent"
sudo dscl . -create /Users/jenkins UniqueID 550
sudo dscl . -create /Users/jenkins PrimaryGroupID 20
sudo dscl . -create /Users/jenkins NFSHomeDirectory /Users/jenkins
sudo mkdir -p /Users/jenkins
sudo chown jenkins:staff /Users/jenkins

# Set a password for the jenkins user
sudo dscl . -passwd /Users/jenkins "STRONG_PASSWORD_HERE"

# Create SSH directory and add the Jenkins controller's public key
sudo mkdir -p /Users/jenkins/.ssh
sudo sh -c 'echo "ssh-rsa YOUR_JENKINS_CONTROLLER_PUBLIC_KEY" > /Users/jenkins/.ssh/authorized_keys'
sudo chmod 700 /Users/jenkins/.ssh
sudo chmod 600 /Users/jenkins/.ssh/authorized_keys
sudo chown -R jenkins:staff /Users/jenkins/.ssh

# Create a workspace directory
sudo mkdir -p /Users/jenkins/workspace
sudo chown jenkins:staff /Users/jenkins/workspace

अब Jenkins में agent कॉन्फ़िगर करें:

  1. Manage Jenkins > Nodes > New Node पर जाएं
  2. नाम mac-mini-m4 पर सेट करें
  3. Remote root directory को /Users/jenkins/workspace पर सेट करें
  4. Labels: mac macos apple-silicon m4 ios
  5. Launch method: Launch agents via SSH
  6. Host: आपके Mac Mini का IP पता
  7. Credentials: Mac पर authorized_keys से मेल खाने वाली SSH private key जोड़ें

विधि B: JNLP Agent (इनबाउंड)

इस विधि का उपयोग तब करें जब Jenkins controller, Mac तक सीधे नहीं पहुंच सकता (उदाहरण के लिए, Mac एक फ़ायरवॉल के पीछे है)। agent कनेक्शन शुरू करता है।

# First, create the node in Jenkins UI:
# Manage Jenkins > Nodes > New Node
# Launch method: "Launch agent by connecting it to the controller"
# Note the secret token from the node configuration page

# On the Mac Mini, download the agent JAR:
mkdir -p ~/jenkins-agent && cd ~/jenkins-agent
curl -sO https://your-jenkins-url/jnlpJars/agent.jar

# Test the agent connection
java -jar agent.jar \
  -url https://your-jenkins-url \
  -secret YOUR_AGENT_SECRET \
  -name "mac-mini-m4" \
  -workDir "/Users/jenkins/workspace"

JNLP Agent को एक launchd सर्विस के रूप में चलाएं

# Create the launchd plist file
cat > ~/Library/LaunchAgents/com.jenkins.agent.plist <<'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
  "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.jenkins.agent</string>
    <key>ProgramArguments</key>
    <array>
        <string>/opt/homebrew/opt/openjdk@17/bin/java</string>
        <string>-jar</string>
        <string>/Users/jenkins/jenkins-agent/agent.jar</string>
        <string>-url</string>
        <string>https://your-jenkins-url</string>
        <string>-secret</string>
        <string>YOUR_AGENT_SECRET</string>
        <string>-name</string>
        <string>mac-mini-m4</string>
        <string>-workDir</string>
        <string>/Users/jenkins/workspace</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>KeepAlive</key>
    <true/>
    <key>StandardOutPath</key>
    <string>/Users/jenkins/jenkins-agent/stdout.log</string>
    <key>StandardErrorPath</key>
    <string>/Users/jenkins/jenkins-agent/stderr.log</string>
</dict>
</plist>
EOF

# Load the service
launchctl load ~/Library/LaunchAgents/com.jenkins.agent.plist

# Verify it's running
launchctl list | grep jenkins

5. चरण 3: iOS Build Pipeline बनाएं

अपने रिपॉजिटरी रूट में एक Jenkinsfile बनाएं। यह डिक्लेरेटिव पाइपलाइन आपके iOS ऐप को बनाती, टेस्ट करती और वैकल्पिक रूप से आर्काइव करती है।

pipeline {
    agent { label 'mac && m4' }

    environment {
        SCHEME       = 'MyApp'
        WORKSPACE    = 'MyApp.xcworkspace'
        DESTINATION  = 'platform=iOS Simulator,name=iPhone 16 Pro,OS=18.2'
        DERIVED_DATA = "${WORKSPACE_DIR}/DerivedData"
    }

    options {
        timeout(time: 30, unit: 'MINUTES')
        buildDiscarder(logRotator(numToKeepStr: '20'))
    }

    stages {
        stage('Checkout') {
            steps {
                checkout scm
            }
        }

        stage('Install Dependencies') {
            steps {
                sh '''
                    # Select Xcode version
                    sudo xcode-select -s /Applications/Xcode-16.2.app/Contents/Developer
                    xcodebuild -version

                    # Install CocoaPods dependencies
                    if [ -f "Podfile" ]; then
                        pod install --repo-update
                    fi
                '''
            }
        }

        stage('Build') {
            steps {
                sh '''
                    xcodebuild build \
                        -workspace "${WORKSPACE}" \
                        -scheme "${SCHEME}" \
                        -destination "${DESTINATION}" \
                        -derivedDataPath "${DERIVED_DATA}" \
                        CODE_SIGNING_ALLOWED=NO \
                        | xcbeautify
                '''
            }
        }

        stage('Test') {
            steps {
                sh '''
                    xcodebuild test \
                        -workspace "${WORKSPACE}" \
                        -scheme "${SCHEME}" \
                        -destination "${DESTINATION}" \
                        -derivedDataPath "${DERIVED_DATA}" \
                        -resultBundlePath "TestResults.xcresult" \
                        -parallel-testing-enabled YES \
                        | xcbeautify
                '''
            }
            post {
                always {
                    archiveArtifacts artifacts: 'TestResults.xcresult/**', allowEmptyArchive: true
                }
            }
        }

        stage('Archive') {
            when {
                branch 'main'
            }
            steps {
                sh '''
                    xcodebuild archive \
                        -workspace "${WORKSPACE}" \
                        -scheme "${SCHEME}" \
                        -archivePath "${DERIVED_DATA}/MyApp.xcarchive" \
                        -destination "generic/platform=iOS" \
                        | xcbeautify
                '''
            }
        }
    }

    post {
        success {
            echo 'Build and tests passed!'
        }
        failure {
            echo 'Build or tests failed.'
        }
        cleanup {
            sh 'xcrun simctl shutdown all 2>/dev/null || true'
        }
    }
}

6. चरण 4: डिप्लॉयमेंट के लिए Fastlane एकीकृत करें

Fastlane, कोड साइनिंग और TestFlight डिप्लॉयमेंट को सरल बनाता है। अपनी Jenkinsfile में एक deploy stage जोड़ें:

# Install Fastlane on the Mac Mini (one-time setup)
brew install fastlane

# Or via Ruby:
gem install fastlane -NV

अपनी Jenkinsfile में एक deploy stage जोड़ें:

        stage('Deploy to TestFlight') {
            when {
                branch 'main'
            }
            environment {
                APP_STORE_CONNECT_API_KEY_ID     = credentials('app-store-key-id')
                APP_STORE_CONNECT_API_ISSUER_ID  = credentials('app-store-issuer-id')
                APP_STORE_CONNECT_API_KEY_CONTENT = credentials('app-store-key-content')
                MATCH_PASSWORD                   = credentials('match-password')
            }
            steps {
                sh '''
                    fastlane beta
                '''
            }
        }

और एक मेल खाती fastlane/Fastfile बनाएं:

default_platform(:ios)

platform :ios do
  desc "Push a new beta build to TestFlight"
  lane :beta do
    setup_ci

    # Fetch code signing certificates via match
    match(type: "appstore", readonly: true)

    # Increment build number
    increment_build_number(
      build_number: ENV["BUILD_NUMBER"]
    )

    # Build the app
    build_app(
      workspace: "MyApp.xcworkspace",
      scheme: "MyApp",
      export_method: "app-store",
      derived_data_path: "DerivedData"
    )

    # Upload to TestFlight
    upload_to_testflight(
      skip_waiting_for_build_processing: true,
      api_key: app_store_connect_api_key(
        key_id: ENV["APP_STORE_CONNECT_API_KEY_ID"],
        issuer_id: ENV["APP_STORE_CONNECT_API_ISSUER_ID"],
        key_content: ENV["APP_STORE_CONNECT_API_KEY_CONTENT"]
      )
    )
  end
end

7. सुरक्षा सर्वोत्तम अभ्यास

एक समर्पित Jenkins उपयोगकर्ता का उपयोग करें

Jenkins agent को कभी भी root के रूप में न चलाएं। न्यूनतम परमिशन के साथ एक समर्पित उपयोगकर्ता बनाएं।

सीक्रेट्स को Jenkins Credentials में स्टोर करें

Jenkinsfiles में कभी भी सर्टिफिकेट, API keys या पासवर्ड हार्डकोड न करें। Jenkins Credentials plugin का उपयोग करें।

केवल SSH key-आधारित प्रमाणीकरण सक्षम करें

SSH के लिए पासवर्ड प्रमाणीकरण अक्षम करें। Ed25519 या RSA 4096-bit keys का उपयोग करें।

macOS फ़ायरवॉल का उपयोग करें

इनकमिंग कनेक्शन को केवल Jenkins controller IP तक सीमित करें। MyRemoteMac, API एक्सेस के साथ एक मैनेज्ड फ़ायरवॉल प्रदान करता है।

macOS और Xcode को अपडेट रखें

सुरक्षा पैच तुरंत लागू करें। अपडेट की जांच के लिए softwareupdate -l का उपयोग करें।

8. सामान्य प्रश्न

क्या मैं Jenkins controller को उसी Mac पर चला सकता हूं?

हां, लेकिन हम उन्हें अलग करने की अनुशंसा करते हैं। controller को एक Linux VM या Docker कंटेनर पर चलाएं, और Mac का उपयोग विशेष रूप से एक build agent के रूप में करें। इससे भारी बिल्ड के दौरान संसाधन प्रतिस्पर्धा से बचा जा सकता है।

एक Mac Mini M4 कितने समवर्ती बिल्ड संभाल सकता है?

16GB RAM वाला एक Mac Mini M4 आराम से 2 समवर्ती Xcode बिल्ड संभाल सकता है। 24GB के साथ, आप 3 तक बढ़ा सकते हैं। 48GB वाला M4 Pro आसानी से 4+ समवर्ती बिल्ड संभालता है। अपनी Jenkins node सेटिंग्स में तदनुसार "Number of executors" कॉन्फ़िगर करें।

क्या मुझे iOS सिम्युलेटर के लिए एक GUI सत्र की आवश्यकता है?

नहीं। iOS सिम्युलेटर SSH पर हेडलेस मोड में काम करते हैं। हालांकि, यदि आपको एक GUI की आवश्यकता है (उदाहरण के लिए, UI टेस्टिंग स्क्रीनशॉट के लिए), तो Mac में लॉग इन करने के लिए VNC का उपयोग करें और सुनिश्चित करें कि एक GUI सत्र सक्रिय है।

मैं एक हेडलेस सर्वर पर कोड साइनिंग कैसे संभालूं?

एक Git repo या क्लाउड स्टोरेज से सर्टिफिकेट सिंक करने के लिए Fastlane Match का उपयोग करें। वैकल्पिक रूप से, सर्टिफिकेट को macOS कीचेन में इम्पोर्ट करें और अपनी पाइपलाइन में security unlock-keychain का उपयोग करके इसे अनलॉक करें।

संबंधित गाइड्स

अपने Jenkins बिल्ड को सुपरचार्ज करने के लिए तैयार हैं?

अपनी Jenkins CI/CD पाइपलाइन के लिए एक समर्पित Mac Mini M4 प्राप्त करें। $85/माह से शुरू।

और जानकारी चाहिए?

चरण-दर-चरण सेटअप, कॉन्फ़िगरेशन संदर्भ और समस्या-निवारण के लिए संपूर्ण दस्तावेज़ देखें।

दस्तावेज़ खोलें →