Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 101 additions & 4 deletions scripts/local-ci/lib/ci-env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ source "$_LIB_DIR/common.sh"

# Validate macOS version
validate_macos_version() {
if is_linux; then
log_info "Running on Linux - skipping macOS version check"
return 0
fi

local os_version
os_version=$(sw_vers -productVersion)
local major_version
Expand All @@ -33,6 +38,11 @@ validate_xcode() {
local required_major="${1:-16}"
local required_minor="${2:-0}"

if is_linux; then
log_info "Running on Linux - skipping Xcode validation"
return 0
fi

if [[ ! -d "$XCODE_PATH" ]]; then
error_exit "Xcode not found at $XCODE_PATH"
fi
Expand Down Expand Up @@ -60,7 +70,19 @@ validate_swift() {
local required_version="${1:-6.0}"

if ! command_exists swift; then
error_exit "Swift not found. Install Xcode or Swift toolchain."
if is_linux; then
log_error "Swift is required but not found on Linux"
log_error ""
log_error "Please install Swift following the instructions in:"
log_error " DOCS/RULES/12_Swift_Installation_Linux.md"
log_error ""
log_error "Quick install:"
log_error " curl -L https://swiftlang.github.io/swiftly/swiftly-install.sh | bash"
log_error " swiftly install latest"
error_exit "Swift installation required"
else
error_exit "Swift not found. Install Xcode or Swift toolchain."
fi
fi

local swift_version
Expand All @@ -69,6 +91,7 @@ validate_swift() {

# Note: Version comparison would need more sophisticated parsing
# For now, just report the version
return 0
}

# Check Homebrew
Expand All @@ -89,9 +112,67 @@ ensure_swiftlint() {

if [[ "$mode" == "docker" ]]; then
log_info "SwiftLint mode: Docker (no local installation needed)"
if check_docker; then
log_success "Docker is available and running"
else
log_warning "Docker not running. Ensure Docker Desktop is started."
fi
return 0
fi

# On Linux, prefer Docker or build from source
if is_linux; then
if ! command_exists swiftlint; then
log_warning "SwiftLint not found on Linux"

# Try Docker first
if check_docker; then
log_info "Docker is available. Switching to Docker mode for SwiftLint"
export SWIFTLINT_MODE="docker"
return 0
fi

# Try building from source if Swift is available
if command_exists swift; then
log_info "Attempting to build SwiftLint from source..."
local install_dir="$HOME/.local-ci/swiftlint"

if [[ -x "$install_dir/swiftlint" ]]; then
log_success "Using cached SwiftLint from $install_dir"
export PATH="$install_dir:$PATH"
return 0
fi

log_info "This may take several minutes..."
local temp_dir
temp_dir=$(create_temp_dir)

if git clone --depth 1 --branch 0.53.0 https://github.com/realm/SwiftLint.git "$temp_dir/SwiftLint" 2>/dev/null &&
(cd "$temp_dir/SwiftLint" && swift build -c release) 2>/dev/null; then
mkdir -p "$install_dir"
cp "$temp_dir/SwiftLint/.build/release/swiftlint" "$install_dir/"
export PATH="$install_dir:$PATH"
rm -rf "$temp_dir"
log_success "SwiftLint built and installed to $install_dir"
return 0
else
rm -rf "$temp_dir"
log_warning "Failed to build SwiftLint from source"
fi
fi

log_warning "SwiftLint not available. Use Docker mode: SWIFTLINT_MODE=docker"
log_info "Or install Swift and try building from source"
return 1
fi

local swiftlint_version
swiftlint_version=$(swiftlint version)
log_success "SwiftLint version: $swiftlint_version"
return 0
fi

# macOS path
if ! command_exists swiftlint; then
log_warning "SwiftLint not found"
if check_homebrew; then
Expand All @@ -109,6 +190,11 @@ ensure_swiftlint() {

# Ensure Tuist is installed
ensure_tuist() {
if is_linux; then
log_info "Running on Linux - Tuist is macOS-only, skipping"
return 0
fi

local tuist_version="${TUIST_VERSION:-}"
local install_dir="$HOME/.local-ci/tuist"

Expand Down Expand Up @@ -217,6 +303,11 @@ validate_python() {
# Detect best available iOS simulator for testing
# Returns destination specifier string with ID
detect_ios_simulator() {
if is_linux; then
log_warning "iOS Simulator not available on Linux"
return 1
fi

local device_name="${1:-iPhone 16}"
local workspace="${2:-}"
local scheme="${3:-}"
Expand Down Expand Up @@ -274,11 +365,15 @@ detect_ios_simulator() {
validate_ci_environment() {
log_section "Validating CI Environment"

local current_os
current_os=$(detect_os)
log_info "Detected OS: $current_os"

validate_macos_version
validate_xcode 16 0
validate_swift 6.0
check_homebrew || true
ensure_swiftlint
ensure_swiftlint || true
validate_python || true

log_success "CI environment validation complete"
Expand All @@ -291,8 +386,10 @@ setup_ci_environment() {
load_config
validate_ci_environment

# Set up derived data path for consistent builds
export DERIVED_DATA_PATH="${DERIVED_DATA_PATH:-$HOME/Library/Developer/Xcode/DerivedData}"
# Set up derived data path for consistent builds (macOS only)
if is_macos; then
export DERIVED_DATA_PATH="${DERIVED_DATA_PATH:-$HOME/Library/Developer/Xcode/DerivedData}"
fi

# Set up build cache
export BUILD_CACHE_DIR="${BUILD_CACHE_DIR:-$HOME/.local-ci/build-cache}"
Expand Down
28 changes: 27 additions & 1 deletion scripts/local-ci/lib/common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,31 @@ command_exists() {
command -v "$1" >/dev/null 2>&1
}

# Detect operating system
detect_os() {
case "$(uname -s)" in
Darwin*)
echo "macos"
;;
Linux*)
echo "linux"
;;
*)
echo "unknown"
;;
esac
}

# Check if running on macOS
is_macos() {
[[ "$(detect_os)" == "macos" ]]
}

# Check if running on Linux
is_linux() {
[[ "$(detect_os)" == "linux" ]]
}

# Detect repository root
detect_repo_root() {
local current_dir="$PWD"
Expand Down Expand Up @@ -218,7 +243,8 @@ parse_common_args() {

# Export functions
export -f log_info log_success log_warning log_error log_section
export -f error_exit command_exists detect_repo_root load_config
export -f error_exit command_exists detect_os is_macos is_linux
export -f detect_repo_root load_config
export -f detect_xcode_version detect_swift_version check_xcode_version
export -f check_docker timed_run create_temp_dir cleanup_temp_files
export -f parse_common_args
58 changes: 34 additions & 24 deletions scripts/local-ci/run-build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -154,40 +154,47 @@ fi
# Tuist Workspace Generation
# ============================================================================
if [[ "$SPM_ONLY" != "true" ]] && [[ "$SKIP_TUIST" != "true" ]]; then
log_section "Tuist Workspace Generation"
if is_linux; then
log_info "Running on Linux - skipping Tuist workspace generation (macOS only)"
else
log_section "Tuist Workspace Generation"

ensure_tuist
ensure_tuist

# Validate Tuist project
if timed_run "Validate Tuist project" tuist dump project; then
log_success "Tuist project validation passed"
else
log_error "Tuist project validation failed"
((FAILURES++))
fi
# Validate Tuist project
if timed_run "Validate Tuist project" tuist dump project; then
log_success "Tuist project validation passed"
else
log_error "Tuist project validation failed"
((FAILURES++))
fi

# Install dependencies
if timed_run "Install Tuist dependencies" tuist install; then
log_success "Tuist dependencies installed"
else
log_error "Tuist install failed"
((FAILURES++))
fi
# Install dependencies
if timed_run "Install Tuist dependencies" tuist install; then
log_success "Tuist dependencies installed"
else
log_error "Tuist install failed"
((FAILURES++))
fi

# Generate workspace
if timed_run "Generate Xcode workspace" tuist generate --no-open; then
log_success "Xcode workspace generated"
else
log_error "Tuist generate failed"
((FAILURES++))
# Generate workspace
if timed_run "Generate Xcode workspace" tuist generate --no-open; then
log_success "Xcode workspace generated"
else
log_error "Tuist generate failed"
((FAILURES++))
fi
fi
fi

# ============================================================================
# Xcode Builds
# ============================================================================
if [[ "$SPM_ONLY" != "true" ]] && [[ -f "$REPO_ROOT/ISOInspector.xcworkspace/contents.xcworkspacedata" ]]; then
log_section "Xcode Builds"
if is_linux; then
log_info "Running on Linux - skipping Xcode builds (macOS only)"
else
log_section "Xcode Builds"

XCODE_BUILD_ARGS=(
-workspace ISOInspector.xcworkspace
Expand Down Expand Up @@ -275,9 +282,12 @@ if [[ "$SPM_ONLY" != "true" ]] && [[ -f "$REPO_ROOT/ISOInspector.xcworkspace/con
fi
fi
fi
fi
else
if [[ "$SPM_ONLY" != "true" ]]; then
log_warning "Xcode workspace not found. Run with Tuist generation or use --spm-only"
if ! is_linux; then
log_warning "Xcode workspace not found. Run with Tuist generation or use --spm-only"
fi
fi
fi

Expand Down
67 changes: 42 additions & 25 deletions scripts/local-ci/run-lint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -154,34 +154,50 @@ fi
if [[ "$SKIP_SWIFTLINT" != "true" ]]; then
log_section "SwiftLint ($SWIFTLINT_MODE mode)"

# Function to run SwiftLint on a specific config
run_swiftlint_check() {
local name="$1"
local work_dir="$2"
local config="$3"

log_info "Running SwiftLint on $name..."

if [[ "$SWIFTLINT_MODE" == "docker" ]]; then
if [[ "$AUTO_FIX" == "true" ]]; then
run_swiftlint_autocorrect_docker "$work_dir" "$config"
fi
run_swiftlint_docker "$work_dir" "$config" --strict
# Check if SwiftLint is available
SWIFTLINT_AVAILABLE=false
if [[ "$SWIFTLINT_MODE" == "docker" ]]; then
if check_docker; then
SWIFTLINT_AVAILABLE=true
else
# Native mode
pushd "$work_dir" >/dev/null
log_warning "Docker not available - skipping SwiftLint"
fi
elif command_exists swiftlint; then
SWIFTLINT_AVAILABLE=true
else
log_warning "SwiftLint not available - skipping SwiftLint checks"
log_info "Install SwiftLint or use Docker mode: SWIFTLINT_MODE=docker"
fi

if [[ "$AUTO_FIX" == "true" ]]; then
swiftlint --fix --config "$config" || true
if [[ "$SWIFTLINT_AVAILABLE" == "true" ]]; then
# Function to run SwiftLint on a specific config
run_swiftlint_check() {
local name="$1"
local work_dir="$2"
local config="$3"

log_info "Running SwiftLint on $name..."

if [[ "$SWIFTLINT_MODE" == "docker" ]]; then
if [[ "$AUTO_FIX" == "true" ]]; then
run_swiftlint_autocorrect_docker "$work_dir" "$config"
fi
run_swiftlint_docker "$work_dir" "$config" --strict
else
# Native mode
pushd "$work_dir" >/dev/null

if [[ "$AUTO_FIX" == "true" ]]; then
swiftlint --fix --config "$config" || true
fi

swiftlint lint --strict --config "$config"
local result=$?

popd >/dev/null
return $result
fi

swiftlint lint --strict --config "$config"
local result=$?

popd >/dev/null
return $result
fi
}
}

# Main Project
if timed_run "SwiftLint (Main Project)" run_swiftlint_check "Main Project" "$REPO_ROOT" ".swiftlint.yml"; then
Expand Down Expand Up @@ -210,6 +226,7 @@ if [[ "$SKIP_SWIFTLINT" != "true" ]]; then
((FAILURES++))
fi
fi
fi
fi

# ============================================================================
Expand Down
Loading