Tutorial

Neue Updates und Verbesserungen zu Macfleet.

Wichtiger Hinweis

Die in diesen Tutorials bereitgestellten Codebeispiele und Skripte dienen nur zu Bildungszwecken. Macfleet ist nicht verantwortlich für Probleme, Schäden oder Sicherheitslücken, die durch die Verwendung, Änderung oder Implementierung dieser Beispiele entstehen können. Überprüfen und testen Sie Code immer in einer sicheren Umgebung, bevor Sie ihn in Produktionssystemen verwenden.

Secure Archive Management on macOS

Manage secure file archives across your MacFleet devices with enterprise-grade compression and encryption tools. This tutorial covers password-protected ZIP creation, batch archive operations, security compliance, and comprehensive fleet-wide archive management.

Understanding Secure Archive Management

Secure archive management on macOS involves creating protected compressed files for data transfer, storage, and compliance:

Core Components

  • ZIP Compression - Standard archive format with broad compatibility
  • Password Protection - AES encryption for archive security
  • Batch Operations - Mass archive creation and management
  • Integrity Verification - Archive validation and corruption detection
  • Compliance Tracking - Audit trails and security reporting

Enterprise Benefits

  • Data Security - Protected file transfer and storage
  • Storage Optimization - Compressed archives save disk space
  • Compliance Requirements - Secure data archival for regulations
  • Fleet Management - Standardized archive operations across devices
  • Audit Capabilities - Complete tracking of archive operations

Basic Password-Protected ZIP Creation

Simple ZIP Creation with Password

#!/bin/bash

# Basic password-protected ZIP creation
create_basic_password_zip() {
    local file_path="${1:-/Users/Shared/example.txt}"
    local zip_name="${2:-secure_archive.zip}"
    local password="${3:-ChangeMeNow123!}"
    local content="${4:-Hello MacFleet - Secure Archive Created}"
    
    echo "📦 Creating Password-Protected ZIP Archive"
    echo "========================================="
    echo "File: $file_path"
    echo "Archive: $zip_name"
    echo "Content: $content"
    echo ""
    
    # Create the file with content
    echo "Creating file with content..."
    touch "$file_path"
    printf '%s\n' "$content" > "$file_path"
    
    if [[ -f "$file_path" ]]; then
        echo "✅ File created successfully: $file_path"
    else
        echo "❌ Failed to create file: $file_path"
        return 1
    fi
    
    # Navigate to file directory
    local file_dir=$(dirname "$file_path")
    local file_name=$(basename "$file_path")
    
    echo "Navigating to directory: $file_dir"
    cd "$file_dir" || return 1
    
    # Create password-protected ZIP
    echo "Creating password-protected ZIP archive..."
    if zip -r "$zip_name" "$file_name" --password "$password" >/dev/null 2>&1; then
        echo "✅ ZIP archive created successfully: $file_dir/$zip_name"
        
        # Verify archive
        if [[ -f "$zip_name" ]]; then
            local zip_size=$(du -h "$zip_name" | cut -f1)
            echo "Archive size: $zip_size"
            echo "Archive location: $file_dir/$zip_name"
        fi
    else
        echo "❌ Failed to create ZIP archive"
        return 1
    fi
    
    # Clean up original file (optional)
    echo ""
    read -p "Remove original file? (y/n): " remove_original
    if [[ "$remove_original" =~ ^[Yy]$ ]]; then
        rm "$file_path"
        echo "✅ Original file removed"
    fi
    
    return 0
}

# Execute basic ZIP creation
create_basic_password_zip "/Users/Shared/macfleet_test.txt" "macfleet_secure.zip" "SecurePass123!" "MacFleet Enterprise Archive"

Convert Existing File to Password-Protected ZIP

#!/bin/bash

# Convert existing file to password-protected ZIP
convert_file_to_secure_zip() {
    local source_file="$1"
    local zip_name="${2:-}"
    local password="${3:-}"
    local compression_level="${4:-6}"
    
    echo "🔄 Converting File to Secure ZIP"
    echo "================================"
    echo ""
    
    # Validate input file
    if [[ ! -f "$source_file" ]]; then
        echo "❌ Source file not found: $source_file"
        echo "Please provide a valid file path"
        return 1
    fi
    
    # Get file information
    local file_dir=$(dirname "$source_file")
    local file_name=$(basename "$source_file")
    local file_ext="${file_name##*.}"
    local file_base="${file_name%.*}"
    
    # Generate ZIP name if not provided
    if [[ -z "$zip_name" ]]; then
        zip_name="${file_base}_secure.zip"
    fi
    
    # Generate secure password if not provided
    if [[ -z "$password" ]]; then
        password=$(openssl rand -base64 12 | tr -d "=+/" | cut -c1-12)
        echo "🔐 Generated secure password: $password"
        echo "⚠️ Save this password - it cannot be recovered!"
    fi
    
    echo "Source file: $source_file"
    echo "Archive name: $zip_name"
    echo "Compression level: $compression_level (1-9)"
    echo ""
    
    # Get file size before compression
    local original_size=$(du -h "$source_file" | cut -f1)
    echo "Original file size: $original_size"
    
    # Navigate to file directory
    cd "$file_dir" || return 1
    
    # Create secure ZIP with specified compression
    echo "Creating secure ZIP archive..."
    if zip -"$compression_level" -r "$zip_name" "$file_name" --password "$password" >/dev/null 2>&1; then
        echo "✅ Secure ZIP created successfully"
        
        # Get compressed size and calculate compression ratio
        local compressed_size=$(du -h "$zip_name" | cut -f1)
        local original_bytes=$(du -b "$source_file" | cut -f1)
        local compressed_bytes=$(du -b "$zip_name" | cut -f1)
        local compression_ratio=$(echo "scale=1; (($original_bytes - $compressed_bytes) * 100) / $original_bytes" | bc 2>/dev/null || echo "N/A")
        
        echo ""
        echo "=== Archive Summary ==="
        echo "Original size: $original_size"
        echo "Compressed size: $compressed_size"
        echo "Compression ratio: ${compression_ratio}%"
        echo "Archive location: $file_dir/$zip_name"
        echo "Password: $password"
        
        # Test archive integrity
        echo ""
        echo "Testing archive integrity..."
        if unzip -t "$zip_name" >/dev/null 2>&1; then
            echo "✅ Archive integrity verified"
        else
            echo "⚠️ Archive integrity check failed"
        fi
        
    else
        echo "❌ Failed to create secure ZIP archive"
        return 1
    fi
    
    return 0
}

# Example usage
echo "Example: Convert existing file to secure ZIP"
# convert_file_to_secure_zip "/Users/Shared/document.pdf" "secure_document.zip" "MySecurePass123!"

Enterprise Archive Management

Comprehensive Archive Creation System

#!/bin/bash

# Enterprise archive management system
enterprise_archive_manager() {
    local operation="${1:-create}"
    local source_path="$2"
    local archive_config="${3:-default}"
    local output_dir="${4:-/tmp/macfleet_archives}"
    
    echo "🏢 MacFleet Enterprise Archive Manager"
    echo "====================================="
    echo "Operation: $operation"
    echo "Source: $source_path"
    echo "Config: $archive_config"
    echo "Output: $output_dir"
    echo ""
    
    # Ensure output directory exists
    mkdir -p "$output_dir"
    
    # Configuration presets
    declare -A archive_configs
    archive_configs[default]="zip:6:AES256"
    archive_configs[high_security]="zip:9:AES256"
    archive_configs[fast]="zip:1:AES128"
    archive_configs[maximum]="zip:9:AES256"
    
    # Parse configuration
    local config_string="${archive_configs[$archive_config]:-${archive_configs[default]}}"
    IFS=':' read -r format compression encryption <<< "$config_string"
    
    # Generate secure metadata
    local timestamp=$(date +"%Y%m%d_%H%M%S")
    local hostname=$(hostname)
    local user=$(whoami)
    local archive_id=$(openssl rand -hex 8)
    
    case "$operation" in
        "create")
            create_enterprise_archive "$source_path" "$output_dir" "$format" "$compression" "$encryption" "$timestamp" "$archive_id"
            ;;
        "batch")
            batch_archive_creation "$source_path" "$output_dir" "$format" "$compression" "$encryption"
            ;;
        "verify")
            verify_archive_integrity "$source_path"
            ;;
        "extract")
            secure_archive_extraction "$source_path" "$output_dir"
            ;;
        *)
            echo "❌ Unknown operation: $operation"
            echo "Available operations: create, batch, verify, extract"
            return 1
            ;;
    esac
}

# Create enterprise-grade archive
create_enterprise_archive() {
    local source="$1"
    local output_dir="$2"
    local format="$3"
    local compression="$4"
    local encryption="$5"
    local timestamp="$6"
    local archive_id="$7"
    
    echo "📦 Creating Enterprise Archive"
    echo "============================="
    
    # Validate source
    if [[ ! -e "$source" ]]; then
        echo "❌ Source not found: $source"
        return 1
    fi
    
    # Generate secure password
    local password=$(openssl rand -base64 16 | tr -d "=+/" | cut -c1-16)
    
    # Determine archive name
    local source_name=$(basename "$source")
    local archive_name="macfleet_${archive_id}_${timestamp}.${format}"
    local archive_path="$output_dir/$archive_name"
    local metadata_file="$output_dir/${archive_name}.metadata.json"
    local password_file="$output_dir/${archive_name}.password"
    
    echo "Archive ID: $archive_id"
    echo "Source: $source"
    echo "Archive: $archive_path"
    echo "Compression: Level $compression"
    echo "Encryption: $encryption"
    echo ""
    
    # Get source information
    local source_size=""
    local source_type=""
    local file_count=0
    
    if [[ -f "$source" ]]; then
        source_type="file"
        source_size=$(du -h "$source" | cut -f1)
        file_count=1
    elif [[ -d "$source" ]]; then
        source_type="directory"
        source_size=$(du -sh "$source" | cut -f1)
        file_count=$(find "$source" -type f | wc -l | xargs)
    fi
    
    echo "Source type: $source_type"
    echo "Source size: $source_size"
    echo "File count: $file_count"
    echo ""
    
    # Create archive
    echo "Creating archive..."
    local start_time=$(date +%s)
    
    if zip -r -"$compression" "$archive_path" "$source" --password "$password" >/dev/null 2>&1; then
        local end_time=$(date +%s)
        local duration=$((end_time - start_time))
        
        echo "✅ Archive created successfully"
        echo "Creation time: ${duration}s"
        
        # Get archive statistics
        local archive_size=$(du -h "$archive_path" | cut -f1)
        local checksum=$(shasum -a 256 "$archive_path" | cut -d' ' -f1)
        
        # Save password securely
        echo "$password" > "$password_file"
        chmod 600 "$password_file"
        
        # Generate metadata
        cat > "$metadata_file" << EOF
{
    "archive_info": {
        "id": "$archive_id",
        "name": "$archive_name",
        "created": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")",
        "hostname": "$(hostname)",
        "user": "$(whoami)",
        "macfleet_version": "2025.07"
    },
    "source_info": {
        "path": "$source",
        "type": "$source_type",
        "size": "$source_size",
        "file_count": $file_count
    },
    "archive_details": {
        "format": "$format",
        "compression_level": $compression,
        "encryption": "$encryption",
        "size": "$archive_size",
        "checksum_sha256": "$checksum",
        "creation_duration": ${duration}
    },
    "security": {
        "password_protected": true,
        "password_file": "${archive_name}.password",
        "encryption_algorithm": "AES-256"
    }
}
EOF
        
        echo ""
        echo "=== Archive Summary ==="
        echo "Archive: $archive_path"
        echo "Size: $archive_size"
        echo "Checksum: $checksum"
        echo "Password file: $password_file"
        echo "Metadata: $metadata_file"
        
    else
        echo "❌ Failed to create archive"
        return 1
    fi
}

# Batch archive creation
batch_archive_creation() {
    local source_dir="$1"
    local output_dir="$2"
    local format="$3"
    local compression="$4"
    local encryption="$5"
    
    echo "📦 Batch Archive Creation"
    echo "========================"
    echo "Source directory: $source_dir"
    echo ""
    
    if [[ ! -d "$source_dir" ]]; then
        echo "❌ Source directory not found: $source_dir"
        return 1
    fi
    
    local processed=0
    local failed=0
    
    # Process each item in source directory
    for item in "$source_dir"/*; do
        if [[ -e "$item" ]]; then
            local item_name=$(basename "$item")
            echo "Processing: $item_name"
            
            local timestamp=$(date +"%Y%m%d_%H%M%S")
            local archive_id=$(openssl rand -hex 4)
            
            if create_enterprise_archive "$item" "$output_dir" "$format" "$compression" "$encryption" "$timestamp" "$archive_id"; then
                echo "✅ Successfully archived: $item_name"
                ((processed++))
            else
                echo "❌ Failed to archive: $item_name"
                ((failed++))
            fi
            echo ""
        fi
    done
    
    echo "=== Batch Summary ==="
    echo "Processed: $processed"
    echo "Failed: $failed"
    echo "Total: $((processed + failed))"
}

# Archive integrity verification
verify_archive_integrity() {
    local archive_path="$1"
    
    echo "🔍 Archive Integrity Verification"
    echo "================================="
    echo "Archive: $archive_path"
    echo ""
    
    if [[ ! -f "$archive_path" ]]; then
        echo "❌ Archive not found: $archive_path"
        return 1
    fi
    
    # Check if it's a ZIP file
    if ! file "$archive_path" | grep -q "Zip archive"; then
        echo "❌ Not a valid ZIP archive"
        return 1
    fi
    
    # Test archive integrity
    echo "Testing archive integrity..."
    if unzip -t "$archive_path" >/dev/null 2>&1; then
        echo "✅ Archive integrity verified"
        
        # Get archive information
        local archive_size=$(du -h "$archive_path" | cut -f1)
        local file_count=$(unzip -l "$archive_path" 2>/dev/null | tail -1 | awk '{print $2}' || echo "Unknown")
        
        echo ""
        echo "=== Archive Information ==="
        echo "Size: $archive_size"
        echo "Files: $file_count"
        echo "Format: ZIP"
        
        # Check for metadata
        local metadata_file="${archive_path}.metadata.json"
        if [[ -f "$metadata_file" ]]; then
            echo "Metadata: Available"
            local creation_date=$(jq -r '.archive_info.created' "$metadata_file" 2>/dev/null || echo "Unknown")
            local archive_id=$(jq -r '.archive_info.id' "$metadata_file" 2>/dev/null || echo "Unknown")
            echo "Created: $creation_date"
            echo "Archive ID: $archive_id"
        else
            echo "Metadata: Not available"
        fi
        
    else
        echo "❌ Archive integrity check failed"
        echo "Archive may be corrupted or password-protected"
        return 1
    fi
}

# Usage examples
echo "Archive Manager Examples:"
echo "==================================="
echo ""

echo "1. Create enterprise archive:"
enterprise_archive_manager "create" "/Users/Shared/documents" "high_security" "/tmp/archives"
echo ""

echo "2. Batch archive creation:"
enterprise_archive_manager "batch" "/Users/Shared/batch_source" "default" "/tmp/batch_archives"
echo ""

echo "3. Verify archive integrity:"
enterprise_archive_manager "verify" "/tmp/archives/example.zip"

Security and Compliance Features

Advanced Security Archive System

#!/bin/bash

# Advanced security and compliance archive system
secure_compliance_archiver() {
    local operation="${1:-audit}"
    local archive_path="$2"
    local compliance_level="${3:-standard}"
    
    echo "🔒 Secure Compliance Archiver"
    echo "============================="
    echo "Operation: $operation"
    echo "Compliance level: $compliance_level"
    echo ""
    
    case "$operation" in
        "audit")
            perform_security_audit "$archive_path" "$compliance_level"
            ;;
        "encrypt")
            apply_advanced_encryption "$archive_path" "$compliance_level"
            ;;
        "validate")
            validate_compliance_requirements "$archive_path" "$compliance_level"
            ;;
        "report")
            generate_compliance_report "$compliance_level"
            ;;
        *)
            echo "❌ Unknown operation: $operation"
            echo "Available operations: audit, encrypt, validate, report"
            return 1
            ;;
    esac
}

# Security audit for archives
perform_security_audit() {
    local archive_path="$1"
    local compliance_level="$2"
    
    echo "🔍 Security Audit"
    echo "================="
    echo ""
    
    local audit_passed=0
    local audit_warnings=0
    local audit_failures=0
    
    # Check file permissions
    if [[ -f "$archive_path" ]]; then
        local permissions=$(stat -f "%A" "$archive_path" 2>/dev/null || echo "unknown")
        echo "File permissions: $permissions"
        
        if [[ "$permissions" =~ ^[67][0-4][0-4]$ ]]; then
            echo "✅ Permissions are secure"
            ((audit_passed++))
        else
            echo "⚠️ Permissions may be too permissive"
            ((audit_warnings++))
        fi
    fi
    
    # Check encryption status
    if file "$archive_path" | grep -q "password-protected\|encrypted"; then
        echo "✅ Archive is password-protected"
        ((audit_passed++))
    else
        echo "❌ Archive is not password-protected"
        ((audit_failures++))
    fi
    
    # Check metadata integrity
    local metadata_file="${archive_path}.metadata.json"
    if [[ -f "$metadata_file" ]]; then
        echo "✅ Metadata file present"
        ((audit_passed++))
        
        # Validate JSON
        if jq empty "$metadata_file" 2>/dev/null; then
            echo "✅ Metadata format valid"
            ((audit_passed++))
        else
            echo "❌ Metadata format invalid"
            ((audit_failures++))
        fi
    else
        echo "⚠️ Metadata file missing"
        ((audit_warnings++))
    fi
    
    # Compliance-specific checks
    case "$compliance_level" in
        "high"|"enterprise")
            # Check for secure password file
            local password_file="${archive_path}.password"
            if [[ -f "$password_file" ]]; then
                local pass_permissions=$(stat -f "%A" "$password_file" 2>/dev/null || echo "unknown")
                if [[ "$pass_permissions" == "600" ]]; then
                    echo "✅ Password file permissions secure"
                    ((audit_passed++))
                else
                    echo "❌ Password file permissions insecure"
                    ((audit_failures++))
                fi
            fi
            ;;
    esac
    
    # Generate audit summary
    echo ""
    echo "=== Security Audit Summary ==="
    echo "Passed: $audit_passed"
    echo "Warnings: $audit_warnings"
    echo "Failures: $audit_failures"
    
    local total_checks=$((audit_passed + audit_warnings + audit_failures))
    if [[ "$audit_failures" -eq 0 ]]; then
        echo "🎉 Security audit PASSED"
        return 0
    else
        echo "❌ Security audit FAILED"
        return 1
    fi
}

# Generate compliance report
generate_compliance_report() {
    local compliance_level="$1"
    local report_file="/tmp/macfleet_archive_compliance_$(date +%Y%m%d_%H%M%S).json"
    
    echo "📊 Generating Compliance Report"
    echo "==============================="
    echo ""
    
    # Scan for all MacFleet archives
    local archive_dirs=("/tmp/macfleet_archives" "/tmp/archives" "/tmp/batch_archives")
    local total_archives=0
    local compliant_archives=0
    local non_compliant_archives=0
    
    {
        echo "{"
        echo "  \"compliance_report\": {"
        echo "    \"generated\": \"$(date -u +"%Y-%m-%dT%H:%M:%SZ")\","
        echo "    \"hostname\": \"$(hostname)\","
        echo "    \"compliance_level\": \"$compliance_level\","
        echo "    \"archives\": ["
        
        local first_archive=true
        
        for dir in "${archive_dirs[@]}"; do
            if [[ -d "$dir" ]]; then
                for archive in "$dir"/*.zip; do
                    if [[ -f "$archive" ]]; then
                        if [[ "$first_archive" == "false" ]]; then
                            echo ","
                        fi
                        
                        local archive_name=$(basename "$archive")
                        local archive_size=$(du -h "$archive" | cut -f1)
                        local is_compliant="false"
                        
                        # Check compliance
                        if perform_security_audit "$archive" "$compliance_level" >/dev/null 2>&1; then
                            is_compliant="true"
                            ((compliant_archives++))
                        else
                            ((non_compliant_archives++))
                        fi
                        
                        echo "      {"
                        echo "        \"name\": \"$archive_name\","
                        echo "        \"path\": \"$archive\","
                        echo "        \"size\": \"$archive_size\","
                        echo "        \"compliant\": $is_compliant"
                        echo -n "      }"
                        
                        first_archive=false
                        ((total_archives++))
                    fi
                done
            fi
        done
        
        echo ""
        echo "    ],"
        echo "    \"summary\": {"
        echo "      \"total_archives\": $total_archives,"
        echo "      \"compliant\": $compliant_archives,"
        echo "      \"non_compliant\": $non_compliant_archives,"
        echo "      \"compliance_rate\": \"$(echo "scale=1; ($compliant_archives * 100) / $total_archives" | bc 2>/dev/null || echo "0")%\""
        echo "    }"
        echo "  }"
        echo "}"
    } > "$report_file"
    
    echo "✅ Compliance report generated: $report_file"
    echo ""
    echo "=== Summary ==="
    echo "Total archives: $total_archives"
    echo "Compliant: $compliant_archives"
    echo "Non-compliant: $non_compliant_archives"
    
    if [[ "$total_archives" -gt 0 ]]; then
        local compliance_rate=$(echo "scale=1; ($compliant_archives * 100) / $total_archives" | bc 2>/dev/null || echo "0")
        echo "Compliance rate: ${compliance_rate}%"
    fi
}

# Execute compliance operations
echo "Security and Compliance Examples:"
echo "================================"
echo ""

echo "1. Generate compliance report:"
secure_compliance_archiver "report" "" "enterprise"

Important Notes

Enterprise Features

  • Advanced Security - AES-256 encryption with secure password generation
  • Metadata Management - Comprehensive archive tracking and documentation
  • Batch Operations - Mass archive creation and management
  • Integrity Verification - Archive validation and corruption detection
  • Compliance Reporting - Security audit and compliance tracking
  • Fleet Deployment - Standardized archive operations across devices

Security Best Practices

  • Strong Passwords - Cryptographically secure password generation
  • Secure Storage - Protected password files with restricted permissions
  • Encryption Standards - AES-256 encryption for maximum security
  • Audit Trails - Complete operation logging and tracking
  • Access Controls - Proper file permissions and security measures

Supported Operations

  • Create - Single file or directory archive creation
  • Batch - Multiple archive creation from directory contents
  • Verify - Archive integrity testing and validation
  • Extract - Secure archive extraction with verification
  • Audit - Security compliance checking and reporting

Usage Examples

# Basic password-protected ZIP
touch /Users/Shared/filename.txt
printf 'Hello world\n' > /Users/Shared/filename.txt
cd /Users/Shared
zip -r filename.zip filename.txt --password 1234

# Enhanced MacFleet enterprise archive
create_basic_password_zip "/Users/Shared/document.pdf" "secure_doc.zip" "SecurePass123!"

# Enterprise archive with metadata
enterprise_archive_manager "create" "/Users/Shared/projects" "high_security" "/tmp/archives"

# Batch archive creation
enterprise_archive_manager "batch" "/Users/Shared/documents" "default" "/tmp/batch_archives"

# Security audit
secure_compliance_archiver "audit" "/tmp/archives/example.zip" "enterprise"

Tutorial

Neue Updates und Verbesserungen zu Macfleet.

Konfiguration eines GitHub Actions Runners auf einem Mac Mini (Apple Silicon)

GitHub Actions Runner

GitHub Actions ist eine leistungsstarke CI/CD-Plattform, die es Ihnen ermöglicht, Ihre Software-Entwicklungsworkflows zu automatisieren. Während GitHub gehostete Runner anbietet, bieten selbst-gehostete Runner erhöhte Kontrolle und Anpassung für Ihr CI/CD-Setup. Dieses Tutorial führt Sie durch die Einrichtung, Konfiguration und Verbindung eines selbst-gehosteten Runners auf einem Mac mini zur Ausführung von macOS-Pipelines.

Voraussetzungen

Bevor Sie beginnen, stellen Sie sicher, dass Sie haben:

  • Einen Mac mini (registrieren Sie sich bei Macfleet)
  • Ein GitHub-Repository mit Administratorrechten
  • Einen installierten Paketmanager (vorzugsweise Homebrew)
  • Git auf Ihrem System installiert

Schritt 1: Ein dediziertes Benutzerkonto erstellen

Erstellen Sie zunächst ein dediziertes Benutzerkonto für den GitHub Actions Runner:

# Das 'gh-runner' Benutzerkonto erstellen
sudo dscl . -create /Users/gh-runner
sudo dscl . -create /Users/gh-runner UserShell /bin/bash
sudo dscl . -create /Users/gh-runner RealName "GitHub runner"
sudo dscl . -create /Users/gh-runner UniqueID "1001"
sudo dscl . -create /Users/gh-runner PrimaryGroupID 20
sudo dscl . -create /Users/gh-runner NFSHomeDirectory /Users/gh-runner

# Das Passwort für den Benutzer setzen
sudo dscl . -passwd /Users/gh-runner ihr_passwort

# 'gh-runner' zur 'admin'-Gruppe hinzufügen
sudo dscl . -append /Groups/admin GroupMembership gh-runner

Wechseln Sie zum neuen Benutzerkonto:

su gh-runner

Schritt 2: Erforderliche Software installieren

Installieren Sie Git und Rosetta 2 (wenn Sie Apple Silicon verwenden):

# Git installieren, falls noch nicht installiert
brew install git

# Rosetta 2 für Apple Silicon Macs installieren
softwareupdate --install-rosetta

Schritt 3: Den GitHub Actions Runner konfigurieren

  1. Gehen Sie zu Ihrem GitHub-Repository
  2. Navigieren Sie zu Einstellungen > Actions > Runners

GitHub Actions Runner

  1. Klicken Sie auf "New self-hosted runner" (https://github.com/<username>/<repository>/settings/actions/runners/new)
  2. Wählen Sie macOS als Runner-Image und ARM64 als Architektur
  3. Folgen Sie den bereitgestellten Befehlen, um den Runner herunterzuladen und zu konfigurieren

GitHub Actions Runner

Erstellen Sie eine .env-Datei im _work-Verzeichnis des Runners:

# _work/.env Datei
ImageOS=macos15
XCODE_15_DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer
  1. Führen Sie das run.sh-Skript in Ihrem Runner-Verzeichnis aus, um die Einrichtung abzuschließen.
  2. Überprüfen Sie, dass der Runner aktiv ist und auf Jobs im Terminal wartet, und überprüfen Sie die GitHub-Repository-Einstellungen für die Runner-Zuordnung und den Idle-Status.

GitHub Actions Runner

Schritt 4: Sudoers konfigurieren (Optional)

Wenn Ihre Actions Root-Privilegien benötigen, konfigurieren Sie die sudoers-Datei:

sudo visudo

Fügen Sie die folgende Zeile hinzu:

gh-runner ALL=(ALL) NOPASSWD: ALL

Schritt 5: Den Runner in Workflows verwenden

Konfigurieren Sie Ihren GitHub Actions Workflow, um den selbst-gehosteten Runner zu verwenden:

name: Beispiel-Workflow

on:
  workflow_dispatch:

jobs:
  build:
    runs-on: [self-hosted, macOS, ARM64]
    steps:
      - name: NodeJS installieren
        run: brew install node

Der Runner ist bei Ihrem Repository authentifiziert und mit self-hosted, macOS und ARM64 markiert. Verwenden Sie ihn in Ihren Workflows, indem Sie diese Labels im runs-on-Feld angeben:

runs-on: [self-hosted, macOS, ARM64]

Best Practices

  • Halten Sie Ihre Runner-Software auf dem neuesten Stand
  • Überwachen Sie regelmäßig Runner-Logs auf Probleme
  • Verwenden Sie spezifische Labels für verschiedene Runner-Typen
  • Implementieren Sie angemessene Sicherheitsmaßnahmen
  • Erwägen Sie die Verwendung mehrerer Runner für Lastverteilung

Fehlerbehebung

Häufige Probleme und Lösungen:

  1. Runner verbindet sich nicht:

    • Überprüfen Sie die Netzwerkverbindung
    • Überprüfen Sie die Gültigkeit des GitHub-Tokens
    • Stellen Sie angemessene Berechtigungen sicher
  2. Build-Fehler:

    • Überprüfen Sie die Xcode-Installation
    • Überprüfen Sie erforderliche Abhängigkeiten
    • Überprüfen Sie Workflow-Logs
  3. Berechtigungsprobleme:

    • Überprüfen Sie Benutzerberechtigungen
    • Überprüfen Sie sudoers-Konfiguration
    • Überprüfen Sie Dateisystem-Berechtigungen

Fazit

Sie haben jetzt einen selbst-gehosteten GitHub Actions Runner auf Ihrem Mac mini konfiguriert. Diese Einrichtung bietet Ihnen mehr Kontrolle über Ihre CI/CD-Umgebung und ermöglicht es Ihnen, macOS-spezifische Workflows effizient auszuführen.

Denken Sie daran, Ihren Runner regelmäßig zu warten und ihn mit den neuesten Sicherheitspatches und Software-Versionen auf dem neuesten Stand zu halten.

Native App

Macfleet native App

Macfleet Installationsanleitung

Macfleet ist eine leistungsstarke Flottenmanagement-Lösung, die speziell für Cloud-gehostete Mac Mini-Umgebungen entwickelt wurde. Als Mac Mini Cloud-Hosting-Anbieter können Sie Macfleet verwenden, um Ihre gesamte Flotte virtualisierter Mac-Instanzen zu überwachen, zu verwalten und zu optimieren.

Diese Installationsanleitung führt Sie durch die Einrichtung der Macfleet-Überwachung auf macOS-, Windows- und Linux-Systemen, um eine umfassende Übersicht über Ihre Cloud-Infrastruktur zu gewährleisten.

🍎 macOS

  • Laden Sie die .dmg-Datei für Mac hier herunter
  • Doppelklicken Sie auf die heruntergeladene .dmg-Datei
  • Ziehen Sie die Macfleet-App in den Anwendungsordner
  • Werfen Sie die .dmg-Datei aus
  • Öffnen Sie Systemeinstellungen > Sicherheit & Datenschutz
    • Datenschutz-Tab > Bedienungshilfen
    • Aktivieren Sie Macfleet, um Überwachung zu erlauben
  • Starten Sie Macfleet aus den Anwendungen
  • Die Verfolgung startet automatisch

🪟 Windows

  • Laden Sie die .exe-Datei für Windows hier herunter
  • Rechtsklick auf die .exe-Datei > "Als Administrator ausführen"
  • Folgen Sie dem Installationsassistenten
  • Akzeptieren Sie die Allgemeinen Geschäftsbedingungen
  • Erlauben Sie in Windows Defender, wenn aufgefordert
  • Gewähren Sie Anwendungsüberwachungsberechtigungen
  • Starten Sie Macfleet aus dem Startmenü
  • Die Anwendung beginnt automatisch mit der Verfolgung

🐧 Linux

  • Laden Sie das .deb-Paket (Ubuntu/Debian) oder .rpm (CentOS/RHEL) hier herunter
  • Installieren Sie mit Ihrem Paketmanager
    • Ubuntu/Debian: sudo dpkg -i Macfleet-linux.deb
    • CentOS/RHEL: sudo rpm -ivh Macfleet-linux.rpm
  • Erlauben Sie X11-Zugriffsberechtigungen, wenn aufgefordert
  • Fügen Sie den Benutzer zu entsprechenden Gruppen hinzu, falls erforderlich
  • Starten Sie Macfleet aus dem Anwendungsmenü
  • Die Anwendung beginnt automatisch mit der Verfolgung

Hinweis: Nach der Installation auf allen Systemen melden Sie sich mit Ihren Macfleet-Anmeldedaten an, um Daten mit Ihrem Dashboard zu synchronisieren.