Tutorial

Novas atualizações e melhorias para a Macfleet.

Aviso importante

Os exemplos de código e scripts fornecidos nestes tutoriais são apenas para fins educacionais. A Macfleet não é responsável por quaisquer problemas, danos ou vulnerabilidades de segurança que possam surgir do uso, modificação ou implementação destes exemplos. Sempre revise e teste o código em um ambiente seguro antes de usá-lo em sistemas de produção.

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

Novas atualizações e melhorias para a Macfleet.

Configurando um Runner do GitHub Actions em um Mac Mini (Apple Silicon)

Runner do GitHub Actions

GitHub Actions é uma plataforma poderosa de CI/CD que permite automatizar seus fluxos de trabalho de desenvolvimento de software. Embora o GitHub ofereça runners hospedados, runners auto-hospedados fornecem maior controle e personalização para sua configuração de CI/CD. Este tutorial o guia através da configuração e conexão de um runner auto-hospedado em um Mac mini para executar pipelines do macOS.

Pré-requisitos

Antes de começar, certifique-se de ter:

  • Um Mac mini (registre-se no Macfleet)
  • Um repositório GitHub com direitos de administrador
  • Um gerenciador de pacotes instalado (preferencialmente Homebrew)
  • Git instalado em seu sistema

Passo 1: Criar uma Conta de Usuário Dedicada

Primeiro, crie uma conta de usuário dedicada para o runner do GitHub Actions:

# Criar a conta de usuário '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

# Definir a senha para o usuário
sudo dscl . -passwd /Users/gh-runner sua_senha

# Adicionar 'gh-runner' ao grupo 'admin'
sudo dscl . -append /Groups/admin GroupMembership gh-runner

Mude para a nova conta de usuário:

su gh-runner

Passo 2: Instalar Software Necessário

Instale Git e Rosetta 2 (se estiver usando Apple Silicon):

# Instalar Git se ainda não estiver instalado
brew install git

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

Passo 3: Configurar o Runner do GitHub Actions

  1. Vá para seu repositório GitHub
  2. Navegue para Configurações > Actions > Runners

Runner do GitHub Actions

  1. Clique em "New self-hosted runner" (https://github.com/<username>/<repository>/settings/actions/runners/new)
  2. Selecione macOS como imagem do runner e ARM64 como arquitetura
  3. Siga os comandos fornecidos para baixar e configurar o runner

Runner do GitHub Actions

Crie um arquivo .env no diretório _work do runner:

# arquivo _work/.env
ImageOS=macos15
XCODE_15_DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer
  1. Execute o script run.sh em seu diretório do runner para completar a configuração.
  2. Verifique se o runner está ativo e ouvindo por trabalhos no terminal e verifique as configurações do repositório GitHub para a associação do runner e status Idle.

Runner do GitHub Actions

Passo 4: Configurar Sudoers (Opcional)

Se suas ações requerem privilégios de root, configure o arquivo sudoers:

sudo visudo

Adicione a seguinte linha:

gh-runner ALL=(ALL) NOPASSWD: ALL

Passo 5: Usar o Runner em Fluxos de Trabalho

Configure seu fluxo de trabalho do GitHub Actions para usar o runner auto-hospedado:

name: Fluxo de trabalho de exemplo

on:
  workflow_dispatch:

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

O runner está autenticado em seu repositório e rotulado com self-hosted, macOS, e ARM64. Use-o em seus fluxos de trabalho especificando estes rótulos no campo runs-on:

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

Melhores Práticas

  • Mantenha seu software do runner atualizado
  • Monitore regularmente os logs do runner para problemas
  • Use rótulos específicos para diferentes tipos de runners
  • Implemente medidas de segurança adequadas
  • Considere usar múltiplos runners para balanceamento de carga

Solução de Problemas

Problemas comuns e soluções:

  1. Runner não conectando:

    • Verifique conectividade de rede
    • Verifique validade do token GitHub
    • Certifique-se de permissões adequadas
  2. Falhas de build:

    • Verifique instalação do Xcode
    • Verifique dependências necessárias
    • Revise logs do fluxo de trabalho
  3. Problemas de permissão:

    • Verifique permissões do usuário
    • Verifique configuração sudoers
    • Revise permissões do sistema de arquivos

Conclusão

Agora você tem um runner auto-hospedado do GitHub Actions configurado em seu Mac mini. Esta configuração fornece mais controle sobre seu ambiente CI/CD e permite executar fluxos de trabalho específicos do macOS de forma eficiente.

Lembre-se de manter regularmente seu runner e mantê-lo atualizado com os patches de segurança e versões de software mais recentes.

Aplicativo Nativo

Aplicativo nativo do Macfleet

Guia de Instalação do Macfleet

Macfleet é uma solução poderosa de gerenciamento de frota projetada especificamente para ambientes Mac Mini hospedados na nuvem. Como provedor de hospedagem na nuvem Mac Mini, você pode usar o Macfleet para monitorar, gerenciar e otimizar toda sua frota de instâncias Mac virtualizadas.

Este guia de instalação o conduzirá através da configuração do monitoramento do Macfleet em sistemas macOS, Windows e Linux para garantir supervisão abrangente de sua infraestrutura na nuvem.

🍎 macOS

  • Baixe o arquivo .dmg para Mac aqui
  • Clique duas vezes no arquivo .dmg baixado
  • Arraste o aplicativo Macfleet para a pasta Aplicativos
  • Ejete o arquivo .dmg
  • Abra Preferências do Sistema > Segurança e Privacidade
    • Aba Privacidade > Acessibilidade
    • Marque Macfleet para permitir monitoramento
  • Inicie o Macfleet a partir de Aplicativos
  • O rastreamento inicia automaticamente

🪟 Windows

  • Baixe o arquivo .exe para Windows aqui
  • Clique com o botão direito no arquivo .exe > "Executar como administrador"
  • Siga o assistente de instalação
  • Aceite os termos e condições
  • Permita no Windows Defender se solicitado
  • Conceda permissões de monitoramento de aplicativo
  • Inicie o Macfleet a partir do Menu Iniciar
  • O aplicativo começa o rastreamento automaticamente

🐧 Linux

  • Baixe o pacote .deb (Ubuntu/Debian) ou .rpm (CentOS/RHEL) aqui
  • Instale usando seu gerenciador de pacotes
    • Ubuntu/Debian: sudo dpkg -i Macfleet-linux.deb
    • CentOS/RHEL: sudo rpm -ivh Macfleet-linux.rpm
  • Permita permissões de acesso X11 se solicitado
  • Adicione o usuário aos grupos apropriados se necessário
  • Inicie o Macfleet a partir do menu Aplicativos
  • O aplicativo começa o rastreamento automaticamente

Nota: Após a instalação em todos os sistemas, faça login com suas credenciais do Macfleet para sincronizar dados com seu painel de controle.