Tutorial

Nuevas actualizaciones y mejoras para Macfleet.

Aviso importante

Los ejemplos de código y scripts proporcionados en estos tutoriales son solo para propósitos educativos. Macfleet no es responsable de ningún problema, daño o vulnerabilidad de seguridad que pueda surgir del uso, modificación o implementación de estos ejemplos. Siempre revisa y prueba el código en un entorno seguro antes de usarlo en sistemas de producción.

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

Nuevas actualizaciones y mejoras para Macfleet.

Configurando un Runner de GitHub Actions en un Mac Mini (Apple Silicon)

Runner de GitHub Actions

GitHub Actions es una plataforma poderosa de CI/CD que te permite automatizar tus flujos de trabajo de desarrollo de software. Aunque GitHub ofrece runners hospedados, los runners auto-hospedados proporcionan mayor control y personalización para tu configuración de CI/CD. Este tutorial te guía a través de la configuración y conexión de un runner auto-hospedado en un Mac mini para ejecutar pipelines de macOS.

Prerrequisitos

Antes de comenzar, asegúrate de tener:

  • Un Mac mini (regístrate en Macfleet)
  • Un repositorio de GitHub con derechos de administrador
  • Un gestor de paquetes instalado (preferiblemente Homebrew)
  • Git instalado en tu sistema

Paso 1: Crear una Cuenta de Usuario Dedicada

Primero, crea una cuenta de usuario dedicada para el runner de GitHub Actions:

# Crear la cuenta de usuario 'gh-runner'
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

# Establecer la contraseña para el usuario
sudo dscl . -passwd /Users/gh-runner tu_contraseña

# Agregar 'gh-runner' al grupo 'admin'
sudo dscl . -append /Groups/admin GroupMembership gh-runner

Cambia a la nueva cuenta de usuario:

su gh-runner

Paso 2: Instalar Software Requerido

Instala Git y Rosetta 2 (si usas Apple Silicon):

# Instalar Git si no está ya instalado
brew install git

# Instalar Rosetta 2 para Macs Apple Silicon
softwareupdate --install-rosetta

Paso 3: Configurar el Runner de GitHub Actions

  1. Ve a tu repositorio de GitHub
  2. Navega a Configuración > Actions > Runners

Runner de GitHub Actions

  1. Haz clic en "New self-hosted runner" (https://github.com/<username>/<repository>/settings/actions/runners/new)
  2. Selecciona macOS como imagen del runner y ARM64 como arquitectura
  3. Sigue los comandos proporcionados para descargar y configurar el runner

Runner de GitHub Actions

Crea un archivo .env en el directorio _work del runner:

# archivo _work/.env
ImageOS=macos15
XCODE_15_DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer
  1. Ejecuta el script run.sh en tu directorio del runner para completar la configuración.
  2. Verifica que el runner esté activo y escuchando trabajos en la terminal y revisa la configuración del repositorio de GitHub para la asociación del runner y el estado Idle.

Runner de GitHub Actions

Paso 4: Configurar Sudoers (Opcional)

Si tus acciones requieren privilegios de root, configura el archivo sudoers:

sudo visudo

Agrega la siguiente línea:

gh-runner ALL=(ALL) NOPASSWD: ALL

Paso 5: Usar el Runner en Flujos de Trabajo

Configura tu flujo de trabajo de GitHub Actions para usar el runner auto-hospedado:

name: Flujo de trabajo de muestra

on:
  workflow_dispatch:

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

El runner está autenticado en tu repositorio y etiquetado con self-hosted, macOS, y ARM64. Úsalo en tus flujos de trabajo especificando estas etiquetas en el campo runs-on:

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

Mejores Prácticas

  • Mantén tu software del runner actualizado
  • Monitorea regularmente los logs del runner para problemas
  • Usa etiquetas específicas para diferentes tipos de runners
  • Implementa medidas de seguridad apropiadas
  • Considera usar múltiples runners para balanceo de carga

Solución de Problemas

Problemas comunes y soluciones:

  1. Runner no conectando:

    • Verifica conectividad de red
    • Verifica validez del token de GitHub
    • Asegúrate de permisos apropiados
  2. Fallas de construcción:

    • Verifica instalación de Xcode
    • Verifica dependencias requeridas
    • Revisa logs del flujo de trabajo
  3. Problemas de permisos:

    • Verifica permisos de usuario
    • Verifica configuración de sudoers
    • Revisa permisos del sistema de archivos

Conclusión

Ahora tienes un runner auto-hospedado de GitHub Actions configurado en tu Mac mini. Esta configuración te proporciona más control sobre tu entorno de CI/CD y te permite ejecutar flujos de trabajo específicos de macOS de manera eficiente.

Recuerda mantener regularmente tu runner y mantenerlo actualizado con los últimos parches de seguridad y versiones de software.

Aplicación Nativa

Aplicación nativa de Macfleet

Guía de Instalación de Macfleet

Macfleet es una solución poderosa de gestión de flota diseñada específicamente para entornos de Mac Mini alojados en la nube. Como proveedor de hosting en la nube de Mac Mini, puedes usar Macfleet para monitorear, gestionar y optimizar toda tu flota de instancias Mac virtualizadas.

Esta guía de instalación te llevará a través de la configuración del monitoreo de Macfleet en sistemas macOS, Windows y Linux para asegurar una supervisión integral de tu infraestructura en la nube.

🍎 macOS

  • Descarga el archivo .dmg para Mac aquí
  • Haz doble clic en el archivo .dmg descargado
  • Arrastra la aplicación Macfleet a la carpeta Aplicaciones
  • Expulsa el archivo .dmg
  • Abre Preferencias del Sistema > Seguridad y Privacidad
    • Pestaña Privacidad > Accesibilidad
    • Marca Macfleet para permitir el monitoreo
  • Inicia Macfleet desde Aplicaciones
  • El seguimiento comienza automáticamente

🪟 Windows

  • Descarga el archivo .exe para Windows aquí
  • Haz clic derecho en el archivo .exe > "Ejecutar como administrador"
  • Sigue el asistente de instalación
  • Acepta los términos y condiciones
  • Permite en Windows Defender si se solicita
  • Concede permisos de monitoreo de aplicaciones
  • Inicia Macfleet desde el Menú Inicio
  • La aplicación comienza el seguimiento automáticamente

🐧 Linux

  • Descarga el paquete .deb (Ubuntu/Debian) o .rpm (CentOS/RHEL) aquí
  • Instala usando tu gestor de paquetes
    • Ubuntu/Debian: sudo dpkg -i Macfleet-linux.deb
    • CentOS/RHEL: sudo rpm -ivh Macfleet-linux.rpm
  • Permite permisos de acceso X11 si se solicita
  • Agrega el usuario a los grupos apropiados si es necesario
  • Inicia Macfleet desde el menú de Aplicaciones
  • La aplicación comienza el seguimiento automáticamente

Nota: Después de la instalación en todos los sistemas, inicia sesión con tus credenciales de Macfleet para sincronizar datos con tu panel de control.