From fcc9a7f790e9e52d9e1285d09c11de4dddb2822c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lison=20Fernandes?= Date: Thu, 25 Sep 2025 19:30:08 +0100 Subject: [PATCH 01/27] Increasing test workflow timeout to troubleshoot long running tests. --- .github/workflows/test-bwa.yml | 2 +- .github/workflows/test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-bwa.yml b/.github/workflows/test-bwa.yml index a402c28325..f3953ae4ec 100644 --- a/.github/workflows/test-bwa.yml +++ b/.github/workflows/test-bwa.yml @@ -60,7 +60,7 @@ jobs: test: name: Test runs-on: macos-26 - timeout-minutes: 30 + timeout-minutes: 60 permissions: contents: read diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0979edadd3..e0974c90cf 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -55,7 +55,7 @@ jobs: test: name: Test runs-on: macos-26 - timeout-minutes: 30 + timeout-minutes: 60 permissions: contents: read From 6e31d0ab949a4ef6679cd4acadc07a8d71815167 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lison=20Fernandes?= Date: Thu, 25 Sep 2025 19:40:41 +0100 Subject: [PATCH 02/27] Use -xlarge runners. --- .github/workflows/test-bwa.yml | 4 ++-- .github/workflows/test.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test-bwa.yml b/.github/workflows/test-bwa.yml index f3953ae4ec..39cdff95d6 100644 --- a/.github/workflows/test-bwa.yml +++ b/.github/workflows/test-bwa.yml @@ -59,8 +59,8 @@ env: jobs: test: name: Test - runs-on: macos-26 - timeout-minutes: 60 + runs-on: macos-26-xlarge + timeout-minutes: 50 permissions: contents: read diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e0974c90cf..718adae447 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -54,8 +54,8 @@ env: jobs: test: name: Test - runs-on: macos-26 - timeout-minutes: 60 + runs-on: macos-26-xlarge + timeout-minutes: 50 permissions: contents: read From b0b8388ae5d856695a35b7b8ddacdb1a5a66d48e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lison=20Fernandes?= Date: Mon, 29 Sep 2025 14:21:19 +0100 Subject: [PATCH 03/27] Remove --quite option from xcodebuild command --- .github/workflows/test-bwa.yml | 3 +-- .github/workflows/test.yml | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test-bwa.yml b/.github/workflows/test-bwa.yml index 39cdff95d6..c81b802937 100644 --- a/.github/workflows/test-bwa.yml +++ b/.github/workflows/test-bwa.yml @@ -131,8 +131,7 @@ jobs: -resultBundlePath $_RESULT_BUNDLE_PATH \ -derivedDataPath build/DerivedData \ -test-timeouts-enabled yes \ - -maximum-test-execution-time-allowance 1 \ - -quiet + -maximum-test-execution-time-allowance 1 - name: Print Logs Summary if: always() diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 718adae447..9af66c600f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -126,8 +126,7 @@ jobs: -resultBundlePath $_RESULT_BUNDLE_PATH \ -derivedDataPath build/DerivedData \ -test-timeouts-enabled yes \ - -maximum-test-execution-time-allowance 1 \ - -quiet + -maximum-test-execution-time-allowance 1 - name: Print Logs Summary if: always() From 1d9bc42e022c4c16e9c2838ee123edf9b7ed293d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lison=20Fernandes?= Date: Mon, 29 Sep 2025 14:30:11 +0100 Subject: [PATCH 04/27] Test -test-repetition-relaunch-enabled and -showBuildTimingSummary --- .github/workflows/test-bwa.yml | 5 ++++- .github/workflows/test.yml | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-bwa.yml b/.github/workflows/test-bwa.yml index c81b802937..372d8019c5 100644 --- a/.github/workflows/test-bwa.yml +++ b/.github/workflows/test-bwa.yml @@ -131,7 +131,10 @@ jobs: -resultBundlePath $_RESULT_BUNDLE_PATH \ -derivedDataPath build/DerivedData \ -test-timeouts-enabled yes \ - -maximum-test-execution-time-allowance 1 + -maximum-test-execution-time-allowance 1 \ + -retry-tests-on-failure \ + -test-repetition-relaunch-enabled YES \ + -showBuildTimingSummary - name: Print Logs Summary if: always() diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9af66c600f..7d2e664b15 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -126,7 +126,10 @@ jobs: -resultBundlePath $_RESULT_BUNDLE_PATH \ -derivedDataPath build/DerivedData \ -test-timeouts-enabled yes \ - -maximum-test-execution-time-allowance 1 + -maximum-test-execution-time-allowance 1 \ + -retry-tests-on-failure \ + -test-repetition-relaunch-enabled YES \ + -showBuildTimingSummary - name: Print Logs Summary if: always() From 1894dd0e62e3159a32573a9b9ee55624e46af19e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lison=20Fernandes?= Date: Tue, 30 Sep 2025 14:37:48 +0100 Subject: [PATCH 05/27] Implement pyeetd --- .github/workflows/test.yml | 20 +++++++++ Scripts/pyeetd/.python-version | 1 + Scripts/pyeetd/main.py | 79 ++++++++++++++++++++++++++++++++++ Scripts/pyeetd/pyproject.toml | 10 +++++ Scripts/pyeetd/uv.lock | 8 ++++ 5 files changed, 118 insertions(+) create mode 100644 Scripts/pyeetd/.python-version create mode 100644 Scripts/pyeetd/main.py create mode 100644 Scripts/pyeetd/pyproject.toml create mode 100644 Scripts/pyeetd/uv.lock diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7d2e664b15..9d057d23be 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -116,8 +116,18 @@ jobs: brew bundle ./Scripts/bootstrap.sh + - name: Output processes + run: | + echo "Sorted by memory usage" + ps -em -o pid,pcpu,pmem,comm | head -n40 + echo "--------------------------------" + echo "Sorted by CPU usage" + ps -er -o pid,pcpu,pmem,comm | head -n40 + - name: Build and test run: | + python Scripts/pyeetd/main.py & PYEETD_PID=$! + xcrun xcodebuild test \ -workspace Bitwarden.xcworkspace \ -scheme Bitwarden \ @@ -131,6 +141,16 @@ jobs: -test-repetition-relaunch-enabled YES \ -showBuildTimingSummary + kill $PYEETD_PID + + - name: Output processes + run: | + echo "Sorted by memory usage" + ps -em -o pid,pcpu,pmem,comm | head -n40 + echo "--------------------------------" + echo "Sorted by CPU usage" + ps -er -o pid,pcpu,pmem,comm | head -n40 + - name: Print Logs Summary if: always() run: | diff --git a/Scripts/pyeetd/.python-version b/Scripts/pyeetd/.python-version new file mode 100644 index 0000000000..e4fba21835 --- /dev/null +++ b/Scripts/pyeetd/.python-version @@ -0,0 +1 @@ +3.12 diff --git a/Scripts/pyeetd/main.py b/Scripts/pyeetd/main.py new file mode 100644 index 0000000000..58d0efd213 --- /dev/null +++ b/Scripts/pyeetd/main.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python3 +""" +pyeetd - https://github.com/biscuitehh/yeetd but python +""" + +import os +import signal +import time +import subprocess +import re +from dataclasses import dataclass + +DEFAULT_PROCESSES = { + "AegirPoster", + "InfographPoster", + "CollectionsPoster", + "ExtragalacticPoster", + "KaleidoscopePoster", + "EmojiPosterExtension", + "AmbientPhotoFramePosterProvider", + "PhotosPosterProvider", + "AvatarPosterExtension", + "GradientPosterExtension", + "MonogramPosterExtension" +} + +SIMULATOR_PATH_SEARCH_KEY = "simruntime/Contents/Resources/RuntimeRoot" + +# How long to sleep between checks in seconds +SLEEP_DELAY = 5 + +@dataclass +class ProcessInfo: + pid: int + cpu_percent: float + memory_percent: float + name: str + +def get_processes(): + """Get all processes using ps command - equivalent to Swift's proc_listallpids""" + result = subprocess.run(['ps', '-ero', 'pid,pcpu,pmem,comm'], + capture_output=True, text=True, check=True) + processes = [] + + for line in result.stdout.splitlines()[1:]: # Skip header + parts = line.strip().split(None, 3) + if len(parts) >= 3: + pid = int(parts[0]) + cpu_percent = float(parts[1]) + memory_percent = float(parts[2]) + name = parts[3] + processes.append(ProcessInfo(pid, cpu_percent, memory_percent, name)) + + return processes + +def main(): + while True: + print("\n\n") + print("Scanning for processes ...") + processes = get_processes() + print("PID\tCPU%\tMemory%\tName") + for p in processes[:20]: + print(f"{p.pid}\t{p.cpu_percent}%\t{p.memory_percent}%\t{p.name}") + print("\n\n") + # for p in processes: + # try: + # if p.name in DEFAULT_PROCESSES: + # if SIMULATOR_PATH_SEARCH_KEY in p.name: + # print(f"Stopping process: {p.name}, PID: {p.pid}, CPU: {p.cpu_percent}%") + # os.kill(p.pid, signal.SIGSTOP) + + # except OSError: + # # Process may have disappeared or we don't have permission + # continue + + time.sleep(SLEEP_DELAY) + +if __name__ == '__main__': + main() diff --git a/Scripts/pyeetd/pyproject.toml b/Scripts/pyeetd/pyproject.toml new file mode 100644 index 0000000000..302418c791 --- /dev/null +++ b/Scripts/pyeetd/pyproject.toml @@ -0,0 +1,10 @@ +[project] +name = "pyeetd" +version = "0.1.0" +description = "A minimal daemon implementation in Python" +readme = "README.md" +requires-python = ">=3.12" +dependencies = [] + +[project.scripts] +pyeetd = "main:main" diff --git a/Scripts/pyeetd/uv.lock b/Scripts/pyeetd/uv.lock new file mode 100644 index 0000000000..12542c1f86 --- /dev/null +++ b/Scripts/pyeetd/uv.lock @@ -0,0 +1,8 @@ +version = 1 +revision = 2 +requires-python = ">=3.12" + +[[package]] +name = "pyeetd" +version = "0.1.0" +source = { virtual = "." } From 27180a3e196115efe6502d6b64a6872737a76b76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lison=20Fernandes?= Date: Tue, 30 Sep 2025 15:39:28 +0100 Subject: [PATCH 06/27] Test single string output --- Scripts/pyeetd/main.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/Scripts/pyeetd/main.py b/Scripts/pyeetd/main.py index 58d0efd213..316f91a265 100644 --- a/Scripts/pyeetd/main.py +++ b/Scripts/pyeetd/main.py @@ -27,7 +27,7 @@ SIMULATOR_PATH_SEARCH_KEY = "simruntime/Contents/Resources/RuntimeRoot" # How long to sleep between checks in seconds -SLEEP_DELAY = 5 +SLEEP_DELAY = 10 @dataclass class ProcessInfo: @@ -55,13 +55,16 @@ def get_processes(): def main(): while True: - print("\n\n") - print("Scanning for processes ...") + output = [] + output.append("\n\n") + output.append(f"{time.strftime('%Y-%m-%d %H:%M:%S')} - Scanning for processes ...") processes = get_processes() - print("PID\tCPU%\tMemory%\tName") - for p in processes[:20]: - print(f"{p.pid}\t{p.cpu_percent}%\t{p.memory_percent}%\t{p.name}") - print("\n\n") + output.append("PID\tCPU%\tMemory%\tName") + for p in processes[:40]: + output.append(f"{p.pid}\t{p.cpu_percent}%\t{p.memory_percent}%\t{p.name}") + output.append("\n\n") + + print("\n".join(output)) # for p in processes: # try: # if p.name in DEFAULT_PROCESSES: From dfe29e366cae874d0f0755ec02e6d4ec411e9608 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lison=20Fernandes?= Date: Tue, 30 Sep 2025 15:53:52 +0100 Subject: [PATCH 07/27] Disable spotlight indexing service --- .github/workflows/test.yml | 6 ++++++ Scripts/pyeetd/main.py | 4 +--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9d057d23be..304b2a78d5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -118,6 +118,12 @@ jobs: - name: Output processes run: | + echo "Disabling spotlight" + sudo mdutil -a -i off + echo "Spotlight disabled!" + echo "--------------------------------" + + echo "Sorted by memory usage" ps -em -o pid,pcpu,pmem,comm | head -n40 echo "--------------------------------" diff --git a/Scripts/pyeetd/main.py b/Scripts/pyeetd/main.py index 316f91a265..bba7dd0415 100644 --- a/Scripts/pyeetd/main.py +++ b/Scripts/pyeetd/main.py @@ -56,13 +56,11 @@ def get_processes(): def main(): while True: output = [] - output.append("\n\n") - output.append(f"{time.strftime('%Y-%m-%d %H:%M:%S')} - Scanning for processes ...") + output.append(f"{time.strftime('%Y-%m-%d %H:%M:%S')} - pyeetd scanning for processes ...") processes = get_processes() output.append("PID\tCPU%\tMemory%\tName") for p in processes[:40]: output.append(f"{p.pid}\t{p.cpu_percent}%\t{p.memory_percent}%\t{p.name}") - output.append("\n\n") print("\n".join(output)) # for p in processes: From 9f96d89494790dc1d4dd47702ff33609b5f9f9ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lison=20Fernandes?= Date: Tue, 30 Sep 2025 16:05:29 +0100 Subject: [PATCH 08/27] Unload Metadata.framework --- .github/workflows/test.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 304b2a78d5..e0b9b7959c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -120,6 +120,10 @@ jobs: run: | echo "Disabling spotlight" sudo mdutil -a -i off + sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mds.plist 2>/dev/null || true + sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mds.index.plist 2>/dev/null || true + sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mds.scan.plist 2>/dev/null || true + launchctl unload -w /System/Library/LaunchAgents/com.apple.metadata.mdwrite.plist 2>/dev/null || true echo "Spotlight disabled!" echo "--------------------------------" From 4308891c01d12bfb74ce9b9f017429d18a41ebc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lison=20Fernandes?= Date: Tue, 30 Sep 2025 16:21:41 +0100 Subject: [PATCH 09/27] Add Spotlight app process kill --- .github/workflows/test.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e0b9b7959c..adff8364c9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -120,10 +120,11 @@ jobs: run: | echo "Disabling spotlight" sudo mdutil -a -i off - sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mds.plist 2>/dev/null || true - sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mds.index.plist 2>/dev/null || true - sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mds.scan.plist 2>/dev/null || true - launchctl unload -w /System/Library/LaunchAgents/com.apple.metadata.mdwrite.plist 2>/dev/null || true + sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mds.plist || true + sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mds.index.plist || true + sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mds.scan.plist || true + sudo launchctl unload -w /System/Library/LaunchAgents/com.apple.metadata.mdwrite.plist || true + sudo killall Spotlight echo "Spotlight disabled!" echo "--------------------------------" From c1a9004fa13a97dc021143b75491cf6697824829 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lison=20Fernandes?= Date: Tue, 30 Sep 2025 19:43:47 +0100 Subject: [PATCH 10/27] Turning off additional services --- .github/workflows/test.yml | 39 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index adff8364c9..828dc5fc5e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -120,12 +120,47 @@ jobs: run: | echo "Disabling spotlight" sudo mdutil -a -i off + + echo "Disabling com.apple.metadata.mds" + sudo launchctl disable system/com.apple.metadata.mds + echo "Disabling com.apple.metadata.mds.index" + sudo launchctl disable system/com.apple.metadata.mds.index + echo "Disabling com.apple.metadata.mds.scan" + sudo launchctl disable system/com.apple.metadata.mds.scan + + echo "Unloading com.apple.metadata.mds.plist" sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mds.plist || true + echo "Unloading com.apple.metadata.mds.index.plist" sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mds.index.plist || true + echo "Unloading com.apple.metadata.mds.scan.plist" sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mds.scan.plist || true - sudo launchctl unload -w /System/Library/LaunchAgents/com.apple.metadata.mdwrite.plist || true - sudo killall Spotlight + echo "Unloading com.apple.metadata.mdwrite.plist" + sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mdwrite.plist || true + + echo "Killing all mds processes" + sudo pkill -SIGKILL -f "Metadata.framework/Versions/A/Support/mds" || true + + echo "Killing Spotlight" + sudo pkill -SIGKILL Spotlight || true echo "Spotlight disabled!" + + echo "Disabling ReportCrash" + echo "Unloading com.apple.ReportCrash.plist" + sudo launchctl unload -w /System/Library/LaunchAgents/com.apple.ReportCrash.plist || true + echo "Unloading com.apple.ReportCrash.Root.plist" + sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.ReportCrash.Root.plist || true + + echo "Disabling com.apple.ReportCrash" + sudo launchctl disable system/com.apple.ReportCrash || true + sudo launchctl disable system/com.apple.ReportCrash.Root || true + + echo "ReportCrash disabled!" + + echo "Disabling com.apple.ecosystemd.plist" + sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.ecosystemd.plist || true + echo "Killing ecosystemd" + sudo pkill -SIGKILL -f "ecosystemd" || true + echo "com.apple.ecosystemd.plist disabled!" echo "--------------------------------" From 79b17318998929ad48c31495f8510e8becc66d56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lison=20Fernandes?= Date: Tue, 30 Sep 2025 20:20:16 +0100 Subject: [PATCH 11/27] Let pyeetd pyeet! --- Scripts/pyeetd/main.py | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/Scripts/pyeetd/main.py b/Scripts/pyeetd/main.py index bba7dd0415..185bbc0c03 100644 --- a/Scripts/pyeetd/main.py +++ b/Scripts/pyeetd/main.py @@ -53,27 +53,36 @@ def get_processes(): return processes +def print_processes(processes): + print("PID\tCPU%\tMemory%\tName") + for p in processes: + print(f"{p.pid}\t{p.cpu_percent}%\t{p.memory_percent}%\t{p.name}") + +def find_unwanted(processes): + yeeting = [] + for p in processes: + for k in DEFAULT_PROCESSES: + if k in p.name: + yeeting.append(p) + return yeeting + +def yeet(processes): + output = [] + for p in processes: + output.append(f"pyeetd: Stopping - {p.pid} {p.cpu_percent}% {p.memory_percent}% {p.name}") + os.killpg(p.pid, signal.SIGKILL) + return output + def main(): while True: output = [] - output.append(f"{time.strftime('%Y-%m-%d %H:%M:%S')} - pyeetd scanning for processes ...") + output.append(f"{time.strftime('%Y-%m-%d %H:%M:%S')} - pyeetd scanning...") processes = get_processes() - output.append("PID\tCPU%\tMemory%\tName") - for p in processes[:40]: - output.append(f"{p.pid}\t{p.cpu_percent}%\t{p.memory_percent}%\t{p.name}") - + #print_processes(processes) + processes_to_yeet = find_unwanted(processes) + output.extend(yeet(processes_to_yeet)) + output.append(f"{time.strftime('%Y-%m-%d %H:%M:%S')} - pyeetd {len(processes_to_yeet)} processes!") print("\n".join(output)) - # for p in processes: - # try: - # if p.name in DEFAULT_PROCESSES: - # if SIMULATOR_PATH_SEARCH_KEY in p.name: - # print(f"Stopping process: {p.name}, PID: {p.pid}, CPU: {p.cpu_percent}%") - # os.kill(p.pid, signal.SIGSTOP) - - # except OSError: - # # Process may have disappeared or we don't have permission - # continue - time.sleep(SLEEP_DELAY) if __name__ == '__main__': From c7f0c2c94c77dafcb1957a0fc22b28170a87de4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lison=20Fernandes?= Date: Thu, 2 Oct 2025 13:21:51 +0100 Subject: [PATCH 12/27] Add action to optimize macOS runners --- .../actions/macos-runner-tuneup/action.yml | 54 ++++++++++++++++++ .github/workflows/test.yml | 57 +------------------ 2 files changed, 57 insertions(+), 54 deletions(-) create mode 100644 .github/actions/macos-runner-tuneup/action.yml diff --git a/.github/actions/macos-runner-tuneup/action.yml b/.github/actions/macos-runner-tuneup/action.yml new file mode 100644 index 0000000000..619955d809 --- /dev/null +++ b/.github/actions/macos-runner-tuneup/action.yml @@ -0,0 +1,54 @@ +name: 'macOS Runner Tuneup' +description: 'Optimizes macOS GitHub runners by disabling resource-heavy background processes' +author: 'Bitwarden' + +runs: + using: 'composite' + steps: + - name: Optimize macOS Runner + shell: bash + run: | + echo "🚀 Starting macOS Runner Tuneup..." + echo "==================================" + + echo "🔍 Disabling Spotlight..." + sudo mdutil -a -i off + + echo "🛑 Disabling metadata services..." + sudo launchctl disable system/com.apple.metadata.mds || true + sudo launchctl disable system/com.apple.metadata.mds.index || true + sudo launchctl disable system/com.apple.metadata.mds.scan || true + + echo "📦 Unloading metadata plists..." + sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mds.plist || true + sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mds.index.plist || true + sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mds.scan.plist || true + sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mdwrite.plist || true + + echo "⚡ Killing metadata processes..." + sudo pkill -SIGKILL -f "Metadata.framework/Versions/A/Support/mds" || true + sudo pkill -SIGKILL Spotlight || true + echo "✅ Spotlight disabled!" + + echo "💥 Disabling ReportCrash..." + sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.ReportCrash.plist || true + sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.ReportCrash.Root.plist || true + sudo launchctl disable system/com.apple.ReportCrash || true + sudo launchctl disable system/com.apple.ReportCrash.Root || true + echo "✅ ReportCrash disabled!" + + echo "🌱 Disabling EcosystemD..." + sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.ecosystemd.plist || true + sudo pkill -SIGKILL -f "ecosystemd" || true + echo "✅ EcosystemD disabled!" + + echo "📊 Process Information After Tuning" + echo "==================================" + echo "🧠 Sorted by memory usage:" + ps -em -o pid,pcpu,pmem,comm | head -n20 + echo "" + echo "⚡ Sorted by CPU usage:" + ps -er -o pid,pcpu,pmem,comm | head -n20 + echo "" + echo "🎉 macOS Runner Tuneup Complete!" + diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 828dc5fc5e..c2302aecba 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -68,6 +68,9 @@ jobs: - name: Check out repo uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + - name: Optimize macOS Runner + uses: ./github/actions/macos-runner-tuneup + - name: Read Xcode version and simulator configuration from file if not provided run: | if [ -z "$_XCODE_VERSION" ]; then @@ -116,60 +119,6 @@ jobs: brew bundle ./Scripts/bootstrap.sh - - name: Output processes - run: | - echo "Disabling spotlight" - sudo mdutil -a -i off - - echo "Disabling com.apple.metadata.mds" - sudo launchctl disable system/com.apple.metadata.mds - echo "Disabling com.apple.metadata.mds.index" - sudo launchctl disable system/com.apple.metadata.mds.index - echo "Disabling com.apple.metadata.mds.scan" - sudo launchctl disable system/com.apple.metadata.mds.scan - - echo "Unloading com.apple.metadata.mds.plist" - sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mds.plist || true - echo "Unloading com.apple.metadata.mds.index.plist" - sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mds.index.plist || true - echo "Unloading com.apple.metadata.mds.scan.plist" - sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mds.scan.plist || true - echo "Unloading com.apple.metadata.mdwrite.plist" - sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mdwrite.plist || true - - echo "Killing all mds processes" - sudo pkill -SIGKILL -f "Metadata.framework/Versions/A/Support/mds" || true - - echo "Killing Spotlight" - sudo pkill -SIGKILL Spotlight || true - echo "Spotlight disabled!" - - echo "Disabling ReportCrash" - echo "Unloading com.apple.ReportCrash.plist" - sudo launchctl unload -w /System/Library/LaunchAgents/com.apple.ReportCrash.plist || true - echo "Unloading com.apple.ReportCrash.Root.plist" - sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.ReportCrash.Root.plist || true - - echo "Disabling com.apple.ReportCrash" - sudo launchctl disable system/com.apple.ReportCrash || true - sudo launchctl disable system/com.apple.ReportCrash.Root || true - - echo "ReportCrash disabled!" - - echo "Disabling com.apple.ecosystemd.plist" - sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.ecosystemd.plist || true - echo "Killing ecosystemd" - sudo pkill -SIGKILL -f "ecosystemd" || true - echo "com.apple.ecosystemd.plist disabled!" - echo "--------------------------------" - - - echo "Sorted by memory usage" - ps -em -o pid,pcpu,pmem,comm | head -n40 - echo "--------------------------------" - echo "Sorted by CPU usage" - ps -er -o pid,pcpu,pmem,comm | head -n40 - - name: Build and test run: | python Scripts/pyeetd/main.py & PYEETD_PID=$! From f0ef8cec70c4276337583fb987a77ce3bf874498 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lison=20Fernandes?= Date: Thu, 2 Oct 2025 13:36:01 +0100 Subject: [PATCH 13/27] Split between OS and Simulator processes --- Scripts/pyeetd/main.py | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/Scripts/pyeetd/main.py b/Scripts/pyeetd/main.py index 185bbc0c03..4a53f183bc 100644 --- a/Scripts/pyeetd/main.py +++ b/Scripts/pyeetd/main.py @@ -10,7 +10,14 @@ import re from dataclasses import dataclass -DEFAULT_PROCESSES = { +OS_PROCESSES = { + "Spotlight", + "ReportCrash", + "com.apple.ecosystemd", + "com.apple.metadata.mds", +} + +SIMULATOR_PROCESSES = { "AegirPoster", "InfographPoster", "CollectionsPoster", @@ -35,6 +42,11 @@ class ProcessInfo: cpu_percent: float memory_percent: float name: str + is_simulator: bool + + @property + def environment(self) -> str: + return "Simulator" if self.is_simulator else "OS" def get_processes(): """Get all processes using ps command - equivalent to Swift's proc_listallpids""" @@ -49,19 +61,21 @@ def get_processes(): cpu_percent = float(parts[1]) memory_percent = float(parts[2]) name = parts[3] - processes.append(ProcessInfo(pid, cpu_percent, memory_percent, name)) + is_simulator = SIMULATOR_PATH_SEARCH_KEY in name + processes.append(ProcessInfo(pid, cpu_percent, memory_percent, name, is_simulator)) return processes def print_processes(processes): print("PID\tCPU%\tMemory%\tName") for p in processes: - print(f"{p.pid}\t{p.cpu_percent}%\t{p.memory_percent}%\t{p.name}") + print(f"{p.pid}\t{p.cpu_percent}%\t{p.memory_percent}%\t{p.name}\t{p.environment}") def find_unwanted(processes): yeeting = [] for p in processes: - for k in DEFAULT_PROCESSES: + process_target_list = SIMULATOR_PROCESSES if p.is_simulator else OS_PROCESSES + for k in process_target_list: if k in p.name: yeeting.append(p) return yeeting @@ -69,7 +83,7 @@ def find_unwanted(processes): def yeet(processes): output = [] for p in processes: - output.append(f"pyeetd: Stopping - {p.pid} {p.cpu_percent}% {p.memory_percent}% {p.name}") + output.append(f"pyeetd: Stopping - {p.pid} {p.cpu_percent}% {p.memory_percent}% {p.name} {p.environment}") os.killpg(p.pid, signal.SIGKILL) return output From b3254cd0a652f5f78def75af9722b94489ff1fce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lison=20Fernandes?= Date: Thu, 2 Oct 2025 13:39:35 +0100 Subject: [PATCH 14/27] Add process sort by cpu or mem --- Scripts/pyeetd/main.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/Scripts/pyeetd/main.py b/Scripts/pyeetd/main.py index 4a53f183bc..06e44ebf27 100644 --- a/Scripts/pyeetd/main.py +++ b/Scripts/pyeetd/main.py @@ -9,6 +9,7 @@ import subprocess import re from dataclasses import dataclass +from enum import Enum OS_PROCESSES = { "Spotlight", @@ -48,9 +49,14 @@ class ProcessInfo: def environment(self) -> str: return "Simulator" if self.is_simulator else "OS" -def get_processes(): +class ProcessSort(Enum): + CPU = "cpu" + MEMORY = "memory" + +def get_processes(sort_by=ProcessSort.CPU): """Get all processes using ps command - equivalent to Swift's proc_listallpids""" - result = subprocess.run(['ps', '-ero', 'pid,pcpu,pmem,comm'], + sorty_by = "-ero" if sort_by == ProcessSort.CPU else "-emo" + result = subprocess.run(['ps', sorty_by, 'pid,pcpu,pmem,comm'], capture_output=True, text=True, check=True) processes = [] @@ -91,8 +97,7 @@ def main(): while True: output = [] output.append(f"{time.strftime('%Y-%m-%d %H:%M:%S')} - pyeetd scanning...") - processes = get_processes() - #print_processes(processes) + processes = get_processes(ProcessSort.CPU) processes_to_yeet = find_unwanted(processes) output.extend(yeet(processes_to_yeet)) output.append(f"{time.strftime('%Y-%m-%d %H:%M:%S')} - pyeetd {len(processes_to_yeet)} processes!") From 38b888e2ef2db9755af7b4083894ee02e17e0d42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lison=20Fernandes?= Date: Thu, 2 Oct 2025 13:42:43 +0100 Subject: [PATCH 15/27] Add print limit --- Scripts/pyeetd/main.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Scripts/pyeetd/main.py b/Scripts/pyeetd/main.py index 06e44ebf27..15f5fe1e00 100644 --- a/Scripts/pyeetd/main.py +++ b/Scripts/pyeetd/main.py @@ -72,9 +72,10 @@ def get_processes(sort_by=ProcessSort.CPU): return processes -def print_processes(processes): +def print_processes(processes, limit=-1): print("PID\tCPU%\tMemory%\tName") - for p in processes: + limit = len(processes) if limit == -1 else limit + for p in processes[:limit]: print(f"{p.pid}\t{p.cpu_percent}%\t{p.memory_percent}%\t{p.name}\t{p.environment}") def find_unwanted(processes): @@ -94,6 +95,8 @@ def yeet(processes): return output def main(): + # processes = get_processes(ProcessSort.CPU) + # print_processes(processes, 20) while True: output = [] output.append(f"{time.strftime('%Y-%m-%d %H:%M:%S')} - pyeetd scanning...") From 272b2ef1ca8c520df79d1977082663d975f87009 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lison=20Fernandes?= Date: Thu, 2 Oct 2025 13:42:54 +0100 Subject: [PATCH 16/27] Cleanup output --- Scripts/pyeetd/main.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Scripts/pyeetd/main.py b/Scripts/pyeetd/main.py index 15f5fe1e00..248a013d58 100644 --- a/Scripts/pyeetd/main.py +++ b/Scripts/pyeetd/main.py @@ -99,11 +99,10 @@ def main(): # print_processes(processes, 20) while True: output = [] - output.append(f"{time.strftime('%Y-%m-%d %H:%M:%S')} - pyeetd scanning...") processes = get_processes(ProcessSort.CPU) processes_to_yeet = find_unwanted(processes) output.extend(yeet(processes_to_yeet)) - output.append(f"{time.strftime('%Y-%m-%d %H:%M:%S')} - pyeetd {len(processes_to_yeet)} processes!") + output.append(f"{time.strftime('%Y-%m-%d %H:%M:%S')} - pyeetd {len(processes_to_yeet)} processes.") print("\n".join(output)) time.sleep(SLEEP_DELAY) From 2098dc5b3a31f4510bef0a2f1d7075de5b1992cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lison=20Fernandes?= Date: Thu, 2 Oct 2025 14:00:27 +0100 Subject: [PATCH 17/27] Add output prop to processinfo --- Scripts/pyeetd/main.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Scripts/pyeetd/main.py b/Scripts/pyeetd/main.py index 248a013d58..5780a79998 100644 --- a/Scripts/pyeetd/main.py +++ b/Scripts/pyeetd/main.py @@ -49,6 +49,10 @@ class ProcessInfo: def environment(self) -> str: return "Simulator" if self.is_simulator else "OS" + @property + def output_string(self) -> str: + return f"{self.pid}\t{self.cpu_percent}%\t{self.memory_percent}%\t{self.name}\t{self.environment}" + class ProcessSort(Enum): CPU = "cpu" MEMORY = "memory" @@ -76,7 +80,7 @@ def print_processes(processes, limit=-1): print("PID\tCPU%\tMemory%\tName") limit = len(processes) if limit == -1 else limit for p in processes[:limit]: - print(f"{p.pid}\t{p.cpu_percent}%\t{p.memory_percent}%\t{p.name}\t{p.environment}") + output.append(p.output_string) def find_unwanted(processes): yeeting = [] @@ -90,7 +94,7 @@ def find_unwanted(processes): def yeet(processes): output = [] for p in processes: - output.append(f"pyeetd: Stopping - {p.pid} {p.cpu_percent}% {p.memory_percent}% {p.name} {p.environment}") + output.append(f"pyeetd: Stopping - {p.output_string}") os.killpg(p.pid, signal.SIGKILL) return output From fadbce9fc700c83524be520a10ba7498f3c844ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lison=20Fernandes?= Date: Thu, 2 Oct 2025 14:00:56 +0100 Subject: [PATCH 18/27] Add process print every 60 seconds --- Scripts/pyeetd/main.py | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/Scripts/pyeetd/main.py b/Scripts/pyeetd/main.py index 5780a79998..dd586c7ea2 100644 --- a/Scripts/pyeetd/main.py +++ b/Scripts/pyeetd/main.py @@ -37,6 +37,9 @@ # How long to sleep between checks in seconds SLEEP_DELAY = 10 +# How often to print process info (in seconds) +PRINT_PROCESSES_INTERVAL = 60 + @dataclass class ProcessInfo: pid: int @@ -77,11 +80,22 @@ def get_processes(sort_by=ProcessSort.CPU): return processes def print_processes(processes, limit=-1): - print("PID\tCPU%\tMemory%\tName") + output = [] + output.append("🧠 Processes sorted by memory usage:") + output.append("PID\tCPU%\tMemory%\tName\tEnvironment") limit = len(processes) if limit == -1 else limit for p in processes[:limit]: output.append(p.output_string) + output.append("--------------------------------") + output.append("⚡️ Processes sorted by CPU usage:") + output.append("PID\tCPU%\tMemory%\tName\tEnvironment") + + processes_sorted_by_memory = sorted(processes, key=lambda x: x.memory_percent, reverse=True) + for p in processes_sorted_by_memory[:limit]: + output.append(p.output_string) + print("\n".join(output)) + def find_unwanted(processes): yeeting = [] for p in processes: @@ -101,6 +115,8 @@ def yeet(processes): def main(): # processes = get_processes(ProcessSort.CPU) # print_processes(processes, 20) + print_cycles = PRINT_PROCESSES_INTERVAL // SLEEP_DELAY + i = 0 while True: output = [] processes = get_processes(ProcessSort.CPU) @@ -108,6 +124,12 @@ def main(): output.extend(yeet(processes_to_yeet)) output.append(f"{time.strftime('%Y-%m-%d %H:%M:%S')} - pyeetd {len(processes_to_yeet)} processes.") print("\n".join(output)) + + if i % print_cycles == 0: + output.append("--------------------------------") + print_processes(processes, 20) + + i += 1 time.sleep(SLEEP_DELAY) if __name__ == '__main__': From ee09dc46160f715d129e651e9c4f7f88fb1863cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lison=20Fernandes?= Date: Thu, 2 Oct 2025 14:51:09 +0100 Subject: [PATCH 19/27] Fix action path --- .github/actions/macos-runner-tuneup/action.yml | 2 +- .github/workflows/test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/actions/macos-runner-tuneup/action.yml b/.github/actions/macos-runner-tuneup/action.yml index 619955d809..aa1913c199 100644 --- a/.github/actions/macos-runner-tuneup/action.yml +++ b/.github/actions/macos-runner-tuneup/action.yml @@ -47,7 +47,7 @@ runs: echo "🧠 Sorted by memory usage:" ps -em -o pid,pcpu,pmem,comm | head -n20 echo "" - echo "⚡ Sorted by CPU usage:" + echo "⚡️ Sorted by CPU usage:" ps -er -o pid,pcpu,pmem,comm | head -n20 echo "" echo "🎉 macOS Runner Tuneup Complete!" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c2302aecba..2b2a7e380a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -69,7 +69,7 @@ jobs: uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 - name: Optimize macOS Runner - uses: ./github/actions/macos-runner-tuneup + uses: ./.github/actions/macos-runner-tuneup - name: Read Xcode version and simulator configuration from file if not provided run: | From c52265a7d8b268ae9ab29902cff2b8c142a4f746 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lison=20Fernandes?= Date: Thu, 2 Oct 2025 14:57:08 +0100 Subject: [PATCH 20/27] Apply pyeetd to test-bwa too and set xcodebuild to quiet --- .github/workflows/test-bwa.yml | 7 ++++++- .github/workflows/test.yml | 4 +--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test-bwa.yml b/.github/workflows/test-bwa.yml index 372d8019c5..47b1be65ce 100644 --- a/.github/workflows/test-bwa.yml +++ b/.github/workflows/test-bwa.yml @@ -73,6 +73,9 @@ jobs: - name: Check out repo uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + - name: Optimize macOS Runner + uses: ./.github/actions/macos-runner-tuneup + - name: Read Xcode version and simulator configuration from file if not provided run: | if [ -z "$_XCODE_VERSION" ]; then @@ -123,6 +126,7 @@ jobs: - name: Build and test run: | + python Scripts/pyeetd/main.py & PYEETD_PID=$! xcrun xcodebuild test \ -workspace Bitwarden.xcworkspace \ -scheme Authenticator \ @@ -134,7 +138,8 @@ jobs: -maximum-test-execution-time-allowance 1 \ -retry-tests-on-failure \ -test-repetition-relaunch-enabled YES \ - -showBuildTimingSummary + -quiet + kill $PYEETD_PID - name: Print Logs Summary if: always() diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2b2a7e380a..85ad3955c9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -122,7 +122,6 @@ jobs: - name: Build and test run: | python Scripts/pyeetd/main.py & PYEETD_PID=$! - xcrun xcodebuild test \ -workspace Bitwarden.xcworkspace \ -scheme Bitwarden \ @@ -134,8 +133,7 @@ jobs: -maximum-test-execution-time-allowance 1 \ -retry-tests-on-failure \ -test-repetition-relaunch-enabled YES \ - -showBuildTimingSummary - + -quiet kill $PYEETD_PID - name: Output processes From 6fb70a63a0799d7a91c12aadd56977e6b869f1b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lison=20Fernandes?= Date: Thu, 2 Oct 2025 14:57:18 +0100 Subject: [PATCH 21/27] Fix action --- .github/actions/macos-runner-tuneup/action.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/actions/macos-runner-tuneup/action.yml b/.github/actions/macos-runner-tuneup/action.yml index aa1913c199..ccbe583410 100644 --- a/.github/actions/macos-runner-tuneup/action.yml +++ b/.github/actions/macos-runner-tuneup/action.yml @@ -45,10 +45,10 @@ runs: echo "📊 Process Information After Tuning" echo "==================================" echo "🧠 Sorted by memory usage:" - ps -em -o pid,pcpu,pmem,comm | head -n20 + head -n20 < <(ps -emo pid,pcpu,pmem,comm) echo "" - echo "⚡️ Sorted by CPU usage:" - ps -er -o pid,pcpu,pmem,comm | head -n20 + echo "🔥 Sorted by CPU usage:" + head -n20 < <(ps -ero pid,pcpu,pmem,comm) echo "" echo "🎉 macOS Runner Tuneup Complete!" From f634c2c1bd381cf3d3db11a8662ce076e6bec2e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lison=20Fernandes?= Date: Thu, 2 Oct 2025 16:06:27 +0100 Subject: [PATCH 22/27] Disable additional services --- .../actions/macos-runner-tuneup/action.yml | 32 ++++++++++++++++++- Scripts/pyeetd/main.py | 1 + 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/.github/actions/macos-runner-tuneup/action.yml b/.github/actions/macos-runner-tuneup/action.yml index ccbe583410..5bf8ebeb9f 100644 --- a/.github/actions/macos-runner-tuneup/action.yml +++ b/.github/actions/macos-runner-tuneup/action.yml @@ -12,7 +12,15 @@ runs: echo "==================================" echo "🔍 Disabling Spotlight..." - sudo mdutil -a -i off + sudo mdutil -a -i off # disables indexing on all volumes + sudo mdutil -a -d # disables spotlight activity on all volumes + sudo mdutil -E / # deletes existing index + sudo defaults write /System/Library/LaunchAgents/com.apple.Spotlight.plist Disabled -bool true || true + + echo "🔍 Disabling Spotlight Knowledge Daemon..." + sudo launchctl disable system/com.apple.spotlightknowledged + sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.spotlightknowledged.plist || true + sudo pkill -SIGKILL spotlightknowledged || true echo "🛑 Disabling metadata services..." sudo launchctl disable system/com.apple.metadata.mds || true @@ -35,6 +43,7 @@ runs: sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.ReportCrash.Root.plist || true sudo launchctl disable system/com.apple.ReportCrash || true sudo launchctl disable system/com.apple.ReportCrash.Root || true + defaults write com.apple.CrashReporter DialogType none echo "✅ ReportCrash disabled!" echo "🌱 Disabling EcosystemD..." @@ -42,6 +51,27 @@ runs: sudo pkill -SIGKILL -f "ecosystemd" || true echo "✅ EcosystemD disabled!" + echo "🌱 Disabling EcosystemAnalyticsD..." + sudo launchctl bootout system/com.apple.ecosystemanalyticsd || true + echo "✅ EcosystemAnalyticsD disabled!" + + echo "🌱 Disabling SubmitDiagInfo..." + defaults write /Library/Preferences/com.apple.SubmitDiagInfo AutoSubmit -bool false + + echo "🌍 Disabling location services..." + defaults write /Library/Preferences/com.apple.locationd.plist LocationServicesEnabled -int 0 + + echo "🔍 Disabling Siri..." + defaults write com.apple.assistant.support Assistant\ Enabled -bool false + defaults write com.apple.Siri StatusMenuVisible -bool false + + echo "🔒 Disabling iCloud analytics and usage tracking..." + defaults write com.apple.UsageTracking CoreDonationsEnabled -bool false + defaults write com.apple.UsageTracking UDCAutomationEnabled -bool false + + echo "🔍 Disabling Spotlight suggestions..." + defaults write com.apple.lookup.shared LookupSuggestionsDisabled -bool true + echo "📊 Process Information After Tuning" echo "==================================" echo "🧠 Sorted by memory usage:" diff --git a/Scripts/pyeetd/main.py b/Scripts/pyeetd/main.py index dd586c7ea2..67d822410b 100644 --- a/Scripts/pyeetd/main.py +++ b/Scripts/pyeetd/main.py @@ -14,6 +14,7 @@ OS_PROCESSES = { "Spotlight", "ReportCrash", + "ecosystemanalyticsd" "com.apple.ecosystemd", "com.apple.metadata.mds", } From ccc1ad604b8294bfa0dff53340a040bd248b2e7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lison=20Fernandes?= Date: Thu, 2 Oct 2025 16:16:23 +0100 Subject: [PATCH 23/27] Improve output --- Scripts/pyeetd/main.py | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/Scripts/pyeetd/main.py b/Scripts/pyeetd/main.py index 67d822410b..53f4abf3e6 100644 --- a/Scripts/pyeetd/main.py +++ b/Scripts/pyeetd/main.py @@ -36,7 +36,7 @@ SIMULATOR_PATH_SEARCH_KEY = "simruntime/Contents/Resources/RuntimeRoot" # How long to sleep between checks in seconds -SLEEP_DELAY = 10 +SLEEP_DELAY = 5 # How often to print process info (in seconds) PRINT_PROCESSES_INTERVAL = 60 @@ -82,19 +82,21 @@ def get_processes(sort_by=ProcessSort.CPU): def print_processes(processes, limit=-1): output = [] - output.append("🧠 Processes sorted by memory usage:") + output.append("================================") + output.append("⚡️ Processes sorted by CPU usage:") output.append("PID\tCPU%\tMemory%\tName\tEnvironment") limit = len(processes) if limit == -1 else limit for p in processes[:limit]: output.append(p.output_string) output.append("--------------------------------") - output.append("⚡️ Processes sorted by CPU usage:") + output.append("🧠 Processes sorted by memory usage:") output.append("PID\tCPU%\tMemory%\tName\tEnvironment") - processes_sorted_by_memory = sorted(processes, key=lambda x: x.memory_percent, reverse=True) for p in processes_sorted_by_memory[:limit]: output.append(p.output_string) + + output.append("================================") print("\n".join(output)) def find_unwanted(processes): @@ -109,13 +111,11 @@ def find_unwanted(processes): def yeet(processes): output = [] for p in processes: - output.append(f"pyeetd: Stopping - {p.output_string}") + output.append(f"🤠 pyeetd: Stopping - {p.output_string}") os.killpg(p.pid, signal.SIGKILL) return output def main(): - # processes = get_processes(ProcessSort.CPU) - # print_processes(processes, 20) print_cycles = PRINT_PROCESSES_INTERVAL // SLEEP_DELAY i = 0 while True: @@ -123,13 +123,10 @@ def main(): processes = get_processes(ProcessSort.CPU) processes_to_yeet = find_unwanted(processes) output.extend(yeet(processes_to_yeet)) - output.append(f"{time.strftime('%Y-%m-%d %H:%M:%S')} - pyeetd {len(processes_to_yeet)} processes.") + output.append(f"🤠 {time.strftime('%Y-%m-%d %H:%M:%S')} - pyeetd {len(processes_to_yeet)} processes.") print("\n".join(output)) - if i % print_cycles == 0: - output.append("--------------------------------") - print_processes(processes, 20) - + print_processes(processes, 10) i += 1 time.sleep(SLEEP_DELAY) From af60637e1d14c73c16172a346deea4791582f207 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lison=20Fernandes?= Date: Thu, 2 Oct 2025 16:31:07 +0100 Subject: [PATCH 24/27] Fix action --- .../actions/macos-runner-tuneup/action.yml | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/.github/actions/macos-runner-tuneup/action.yml b/.github/actions/macos-runner-tuneup/action.yml index 5bf8ebeb9f..f87ae65c02 100644 --- a/.github/actions/macos-runner-tuneup/action.yml +++ b/.github/actions/macos-runner-tuneup/action.yml @@ -14,12 +14,9 @@ runs: echo "🔍 Disabling Spotlight..." sudo mdutil -a -i off # disables indexing on all volumes sudo mdutil -a -d # disables spotlight activity on all volumes - sudo mdutil -E / # deletes existing index - sudo defaults write /System/Library/LaunchAgents/com.apple.Spotlight.plist Disabled -bool true || true echo "🔍 Disabling Spotlight Knowledge Daemon..." - sudo launchctl disable system/com.apple.spotlightknowledged - sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.spotlightknowledged.plist || true + sudo launchctl disable system/com.apple.spotlightknowledged || true sudo pkill -SIGKILL spotlightknowledged || true echo "🛑 Disabling metadata services..." @@ -27,11 +24,11 @@ runs: sudo launchctl disable system/com.apple.metadata.mds.index || true sudo launchctl disable system/com.apple.metadata.mds.scan || true - echo "📦 Unloading metadata plists..." - sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mds.plist || true - sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mds.index.plist || true - sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mds.scan.plist || true - sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mdwrite.plist || true + echo "📦 Stopping metadata services..." + sudo launchctl bootout system/com.apple.metadata.mds || true + sudo launchctl bootout system/com.apple.metadata.mds.index || true + sudo launchctl bootout system/com.apple.metadata.mds.scan || true + sudo launchctl bootout system/com.apple.metadata.mdwrite || true echo "⚡ Killing metadata processes..." sudo pkill -SIGKILL -f "Metadata.framework/Versions/A/Support/mds" || true @@ -39,11 +36,14 @@ runs: echo "✅ Spotlight disabled!" echo "💥 Disabling ReportCrash..." - sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.ReportCrash.plist || true - sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.ReportCrash.Root.plist || true sudo launchctl disable system/com.apple.ReportCrash || true sudo launchctl disable system/com.apple.ReportCrash.Root || true - defaults write com.apple.CrashReporter DialogType none + + echo "💥 Unloading ReportCrash..." + sudo launchctl bootout system/com.apple.ReportCrash || true + sudo launchctl bootout system/com.apple.ReportCrash.Root || true + + sudo defaults write com.apple.CrashReporter DialogType none || true echo "✅ ReportCrash disabled!" echo "🌱 Disabling EcosystemD..." @@ -56,21 +56,21 @@ runs: echo "✅ EcosystemAnalyticsD disabled!" echo "🌱 Disabling SubmitDiagInfo..." - defaults write /Library/Preferences/com.apple.SubmitDiagInfo AutoSubmit -bool false + sudo defaults write /Library/Preferences/com.apple.SubmitDiagInfo AutoSubmit -bool false || true echo "🌍 Disabling location services..." - defaults write /Library/Preferences/com.apple.locationd.plist LocationServicesEnabled -int 0 + sudo defaults write /Library/Preferences/com.apple.locationd.plist LocationServicesEnabled -int 0 || true echo "🔍 Disabling Siri..." - defaults write com.apple.assistant.support Assistant\ Enabled -bool false - defaults write com.apple.Siri StatusMenuVisible -bool false + sudo defaults write com.apple.assistant.support Assistant\ Enabled -bool false || true + sudo defaults write com.apple.Siri StatusMenuVisible -bool false || true echo "🔒 Disabling iCloud analytics and usage tracking..." - defaults write com.apple.UsageTracking CoreDonationsEnabled -bool false - defaults write com.apple.UsageTracking UDCAutomationEnabled -bool false + sudo defaults write com.apple.UsageTracking CoreDonationsEnabled -bool false || true + sudo defaults write com.apple.UsageTracking UDCAutomationEnabled -bool false || true echo "🔍 Disabling Spotlight suggestions..." - defaults write com.apple.lookup.shared LookupSuggestionsDisabled -bool true + sudo defaults write com.apple.lookup.shared LookupSuggestionsDisabled -bool true || true echo "📊 Process Information After Tuning" echo "==================================" From d95fda21bce585d8f0ec63173b700dbdded4ce6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lison=20Fernandes?= Date: Thu, 2 Oct 2025 16:53:26 +0100 Subject: [PATCH 25/27] Cleanup script folder --- Scripts/pyeetd/main.py | 7 ++++++- Scripts/pyeetd/pyproject.toml | 10 ---------- Scripts/pyeetd/uv.lock | 8 -------- 3 files changed, 6 insertions(+), 19 deletions(-) delete mode 100644 Scripts/pyeetd/pyproject.toml delete mode 100644 Scripts/pyeetd/uv.lock diff --git a/Scripts/pyeetd/main.py b/Scripts/pyeetd/main.py index 53f4abf3e6..7fba3d885b 100644 --- a/Scripts/pyeetd/main.py +++ b/Scripts/pyeetd/main.py @@ -1,6 +1,11 @@ #!/usr/bin/env python3 """ -pyeetd - https://github.com/biscuitehh/yeetd but python +pyeetd - based on https://github.com/biscuitehh/yeetd + +how to use: +python Scripts/pyeetd/main.py & PYEETD_PID=$! +... +kill $PYEETD_PID """ import os diff --git a/Scripts/pyeetd/pyproject.toml b/Scripts/pyeetd/pyproject.toml deleted file mode 100644 index 302418c791..0000000000 --- a/Scripts/pyeetd/pyproject.toml +++ /dev/null @@ -1,10 +0,0 @@ -[project] -name = "pyeetd" -version = "0.1.0" -description = "A minimal daemon implementation in Python" -readme = "README.md" -requires-python = ">=3.12" -dependencies = [] - -[project.scripts] -pyeetd = "main:main" diff --git a/Scripts/pyeetd/uv.lock b/Scripts/pyeetd/uv.lock deleted file mode 100644 index 12542c1f86..0000000000 --- a/Scripts/pyeetd/uv.lock +++ /dev/null @@ -1,8 +0,0 @@ -version = 1 -revision = 2 -requires-python = ">=3.12" - -[[package]] -name = "pyeetd" -version = "0.1.0" -source = { virtual = "." } From 6b767d2ba137051126a03faf6e897cb2964facbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lison=20Fernandes?= Date: Thu, 2 Oct 2025 16:59:43 +0100 Subject: [PATCH 26/27] Test normal runners --- .github/workflows/test-bwa.yml | 2 +- .github/workflows/test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-bwa.yml b/.github/workflows/test-bwa.yml index 47b1be65ce..1f4ab40eea 100644 --- a/.github/workflows/test-bwa.yml +++ b/.github/workflows/test-bwa.yml @@ -59,7 +59,7 @@ env: jobs: test: name: Test - runs-on: macos-26-xlarge + runs-on: macos-26 timeout-minutes: 50 permissions: contents: read diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 85ad3955c9..a3f6e9dfe9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -54,7 +54,7 @@ env: jobs: test: name: Test - runs-on: macos-26-xlarge + runs-on: macos-26 timeout-minutes: 50 permissions: contents: read From bf1c94c4a8976a5ed56febe970a1096dcd375d87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lison=20Fernandes?= Date: Thu, 2 Oct 2025 17:05:39 +0100 Subject: [PATCH 27/27] Use runner tuneup action in build-any.yml --- .github/workflows/_build-any.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/_build-any.yml b/.github/workflows/_build-any.yml index 68930489c7..b527812a0a 100644 --- a/.github/workflows/_build-any.yml +++ b/.github/workflows/_build-any.yml @@ -55,6 +55,9 @@ jobs: - name: Check out repo uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + - name: Optimize macOS Runner + uses: ./.github/actions/macos-runner-tuneup + - name: Read Xcode version from file if not provided run: | if [ -z "$_XCODE_VERSION" ]; then