diff --git a/devbox/.gitignore b/devbox/.gitignore deleted file mode 100644 index 870e2ad9..00000000 --- a/devbox/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/vm/ -/.state/ diff --git a/devbox/Makefile b/devbox/Makefile deleted file mode 100644 index 65479ab0..00000000 --- a/devbox/Makefile +++ /dev/null @@ -1,68 +0,0 @@ -VZ_DIR := $(CURDIR)/../vzy -VZ_BIN := $(VZ_DIR)/.build/release/vzy -STATE := .state -BUNDLE ?= $(CURDIR)/vm/devbox.bundle -ADMIN_USER ?= admin -ADMIN_PASS ?= vzvz -CPUS ?= 12 -MEM_MIB ?= 24576 -DISK_GIB ?= 120 -XCODE_VER ?= 26.2 -IPSW ?= https://updates.cdn-apple.com/2026SpringFCS/fullrestores/122-88870/E47EBB85-45F2-4E3C-B9E7-6FF7868C2FBA/UniversalMac_26.5.1_25F80_Restore.ipsw -XCODE_XIP ?= -XIP_CACHE ?= $(HOME)/.cache/merge-queue/xcode -XIP := $(or $(XCODE_XIP),$(firstword $(wildcard $(XIP_CACHE)/Xcode-$(XCODE_VER)*.xip))) -SA_RETRIES ?= 3 -SSH_RETRIES ?= 2 - -.PHONY: bundle post-toolchain snapshots clean xcode-xip dev -bundle: $(STATE)/post-toolchain -post-toolchain: $(STATE)/post-toolchain - -dev: $(STATE)/post-toolchain - $(VZ_BIN) run $(CURDIR)/scripts/dev.swift $(BUNDLE) $(WORKTREE)$(if $(CLEAN), --clean,)$(if $(CMD), $(CMD),) - -xcode-xip: - command -v xcodes >/dev/null || { echo "xcodes not found; run bootstrap (Brewfile)" >&2; exit 1; } - mkdir -p $(XIP_CACHE) - xcodes download "$(XCODE_VER)" --directory "$(XIP_CACHE)" - -$(STATE): - mkdir -p $(STATE) - -$(STATE)/vzy: | $(STATE) - cd $(VZ_DIR) && ./build.sh release - touch $@ - -$(STATE)/install: $(STATE)/vzy | $(STATE) - $(VZ_BIN) install $(BUNDLE) $(if $(IPSW),--ipsw $(IPSW) ,)--cpu-count $(CPUS) --memory-mib $(MEM_MIB) --disk-gib $(DISK_GIB) --ssh-username $(ADMIN_USER) - $(VZ_BIN) snapshot take $(BUNDLE) base - touch $@ - -$(STATE)/setup: $(STATE)/install | $(STATE) - $(VZ_BIN) run $(CURDIR)/scripts/setup.swift $(BUNDLE) base $(SA_RETRIES) - $(VZ_BIN) snapshot delete $(BUNDLE) post-sa 2>/dev/null || true - $(VZ_BIN) snapshot take $(BUNDLE) post-sa - touch $@ - -$(STATE)/ssh: $(STATE)/setup | $(STATE) - $(VZ_BIN) setup $(BUNDLE) --preset provision-ssh --retry $(SSH_RETRIES) --restore-from post-sa --output-dir $(CURDIR)/$(STATE)/ssh-logs - $(VZ_BIN) snapshot delete $(BUNDLE) post-ssh 2>/dev/null || true - $(VZ_BIN) snapshot take $(BUNDLE) post-ssh - touch $@ - -$(STATE)/toolchain: $(STATE)/ssh | $(STATE) - $(VZ_BIN) snapshot restore $(BUNDLE) post-ssh - $(VZ_BIN) run $(CURDIR)/scripts/toolchain.swift $(BUNDLE) $(XIP) $(CURDIR)/../Brewfile - touch $@ - -$(STATE)/post-toolchain: $(STATE)/toolchain | $(STATE) - $(VZ_BIN) snapshot delete $(BUNDLE) post-toolchain 2>/dev/null || true - $(VZ_BIN) snapshot take $(BUNDLE) post-toolchain - touch $@ - -snapshots: - $(VZ_BIN) snapshot list $(BUNDLE) - -clean: - rm -rf $(STATE) $(BUNDLE) diff --git a/devbox/scripts/dev.swift b/devbox/scripts/dev.swift deleted file mode 100644 index 9ab4bec4..00000000 --- a/devbox/scripts/dev.swift +++ /dev/null @@ -1,42 +0,0 @@ -import Foundation -import VZKit - -let script = Script(usage: "vz run dev.swift [--clean] [command...]", min: 3) -let bundle = try script.bundle() -let worktree = script[arg: 2] -var rest = Array(script.args.dropFirst(3)) -let clean = rest.first == "--clean" -if clean { rest.removeFirst() } -let command = rest.joined(separator: " ") - -let shareURL = URL(filePath: worktree).resolvingSymlinksInPath() -var isDir: ObjCBool = false -guard FileManager.default.fileExists(atPath: shareURL.path, isDirectory: &isDir), isDir.boolValue -else { - FileHandle.standardError.write(Data("worktree is not a directory: \(worktree)\n".utf8)) - exit(2) -} - -if clean { - step("restoring post-toolchain") - try SnapshotStore.restore(name: "post-toolchain", in: bundle) -} - -let guestMount = "/Users/admin/work" -let share = VMConfiguration.DirectoryShare(hostURL: shareURL, readOnly: false) - -var sessionExit: Int32 = 0 -try await Guest.session(bundle: bundle, adminPass: "vzvz", share: share, mountAt: guestMount) { - guest in - let remote = - command.isEmpty - ? "cd \(guestMount) && exec $SHELL -l" - : "cd \(guestMount) && \(command)" - sessionExit = try await Task.detached { - try VMSSH.execInteractive( - endpoint: guest.endpoint, command: remote, forceTTY: command.isEmpty - ) - }.value -} - -exit(sessionExit) diff --git a/devbox/scripts/setup.swift b/devbox/scripts/setup.swift deleted file mode 100644 index cbf9d6dc..00000000 --- a/devbox/scripts/setup.swift +++ /dev/null @@ -1,110 +0,0 @@ -import AppKit -import Foundation -import VZKit - -func rule(_ match: String, terminal: Bool = false, _ actions: [SetupAssistantSequence.Step]) - -> ScreenRule -{ - ScreenRule(match: match, actions: actions, terminal: terminal) -} - -let saPlan: [ScreenRule] = [ - rule("Welcome", [.key(.returnKey)]), - rule("Select Your Country", [ - .clickByText("Select Your Country"), .wait(seconds: 2), - .type("united states"), .wait(seconds: 2), - .clickByText("United States"), .wait(seconds: 1), - .modifiedKey(modifier: .shift, key: .tab), .wait(seconds: 1), - .key(.space), - ]), - rule("Transfer Your Data", [ - .clickByText("Set up as new"), .wait(seconds: 2), .clickByText("Continue"), - ]), - rule("Written and Spoken Languages", [.clickByText("Continue")]), - rule("Accessibility", [.clickByText("Not Now")]), - rule("Data & Privacy", [.clickByText("Continue")]), - rule("Create a Mac Account", [ - .clickByText("Full Name"), .wait(seconds: 1), - .type("admin"), .key(.tab), .key(.tab), .type("vzvz"), - .clickByText("Verify Password"), .type("vzvz"), .wait(seconds: 1), - .clickByText("Continue"), - ]), - rule("Sign In to Your Apple Account", [ - .clickByText("Other Sign-In Options"), .wait(seconds: 2), - .clickByText("Sign in Later in Settings"), .wait(seconds: 2), - .clickByText("Skip"), - ]), - rule("Terms and Conditions", [ - .clickByText("Agree"), .wait(seconds: 2), .clickByText("Agree"), - ]), - rule("Age Range", [ - .clickByText("Adult"), .wait(seconds: 1), .clickByText("Continue"), - ]), - rule("Location Services", [ - .clickByText("Continue"), .wait(seconds: 2), .clickByText("Don't Use"), - ]), - rule("Time Zone", [.clickByText("Continue")]), - rule("Analytics", [.clickByText("Continue")]), - rule("Screen Time", [.clickByText("Set Up Later")]), - rule("FileVault", [ - .clickByText("Not Now"), .wait(seconds: 2), .clickByText("Continue"), - ]), - rule("Choose Your Look", [.clickByText("Continue")]), - rule("Update Mac", [.clickByText("Continue")]), - rule("Language", [.key(.returnKey)]), - rule("Finder", terminal: true, []), - rule("Get Started", [.clickByText("Get Started")]), - rule("Continue", [.key(.returnKey)]), -] - -func driveSetup(bundle: VMBundle, outputDir: URL) async throws { - let host = try await MainActor.run { try FirstBootHost(bundle: bundle, debugVisible: true) } - try await host.start() - do { - let vnc = try await MainActor.run { try VNCSPI.start(virtualMachine: host.machine, port: 0) } - defer { Task { @MainActor in vnc.stop() } } - let client = RFBClient() - try client.connect(to: .init(host: "127.0.0.1", port: vnc.port), timeout: 10) - try client.handshake() - try await SetupAssistantSequence.runDispatchVNC( - rules: saPlan, host: host, client: client, - screenshotDir: outputDir, maxIterations: 80 - ) - } catch { - try? await host.forceStop() - await MainActor.run { host.close() } - throw error - } - try? await host.forceStop() - await MainActor.run { host.close() } -} - -let script = Script(usage: "vz run setup.swift [restoreFrom] [retries]", min: 2) -let bundle = try script.bundle() -let restoreFrom = script[arg: 2, default: "base"] -let retries = script[arg: 3, default: 3] -let outputDir = URL(filePath: "/tmp/mq-setup") -try? FileManager.default.removeItem(at: outputDir) -try FileManager.default.createDirectory(at: outputDir, withIntermediateDirectories: true) - -let app = NSApplication.shared -app.setActivationPolicy(.accessory) - -Task { - let maxAttempts = retries + 1 - for attempt in 1 ... maxAttempts { - do { - step("setup attempt \(attempt)/\(maxAttempts): restoring \(restoreFrom)") - try SnapshotStore.restore(name: restoreFrom, in: bundle) - try await driveSetup(bundle: bundle, outputDir: outputDir) - step("setup assistant complete") - Darwin.exit(0) - } catch { - FileHandle.standardError.write(Data("attempt \(attempt) failed: \(error)\n".utf8)) - } - } - FileHandle.standardError.write(Data("setup failed after \(maxAttempts) attempts\n".utf8)) - Darwin.exit(1) -} - -app.run() diff --git a/devbox/scripts/toolchain.swift b/devbox/scripts/toolchain.swift deleted file mode 100644 index a80c138b..00000000 --- a/devbox/scripts/toolchain.swift +++ /dev/null @@ -1,104 +0,0 @@ -import Foundation -import VZKit - -func kcpassword(_ password: String) -> Data { - let cipher: [UInt8] = [0x7D, 0x89, 0x52, 0x23, 0xD2, 0xBC, 0xDD, 0xEA, 0xA3, 0xB9, 0x1F] - var bytes = Array(password.utf8) - let remainder = bytes.count % 12 - bytes += Array(repeating: 0, count: remainder == 0 ? 12 : 12 - remainder) - for index in bytes.indices { - bytes[index] ^= cipher[index % cipher.count] - } - return Data(bytes) -} - -func provisionToolchain(_ guest: Guest, xip: String, brewfile: String) async throws { - let adminUser = "admin" - let xcodeApp = "/Applications/Xcode-26.2.0.app" - if try await guest.test("test -d \(xcodeApp)") { - step("Xcode already present, skipping install") - } else { - step("streaming xip into guest") - try guest.upload(localPath: xip, to: "/tmp/Xcode.xip") - step("expanding Xcode in guest") - try await guest.sh("cd /tmp && rm -rf Xcode.app && xip -x Xcode.xip", timeout: 1800) - try await guest.sudo("rm -rf \(xcodeApp) && mv /tmp/Xcode.app \(xcodeApp)") - try await guest.sh("rm -f /tmp/Xcode.xip") - step("accepting license and running first launch") - try await guest.sudo("xcode-select -s \(xcodeApp)") - try await guest.sudo("xcodebuild -license accept") - try await guest.sudo("xcodebuild -runFirstLaunch", timeout: 1800) - } - - step("verifying Xcode 26.2 is installed") - let sdkVersion = try await guest.sh( - "DEVELOPER_DIR=\(xcodeApp)/Contents/Developer xcrun --sdk macosx --show-sdk-version" - ) - guard sdkVersion.hasPrefix("26.2") else { - throw VMError("expected macOS SDK 26.2 from \(xcodeApp), got \(sdkVersion)") - } - - step("enabling passwordless sudo for \(adminUser)") - try await guest.sudo( - "bash -c 'echo \"\(adminUser) ALL=(ALL) NOPASSWD: ALL\" > /etc/sudoers.d/\(adminUser) " - + "&& chmod 440 /etc/sudoers.d/\(adminUser)'" - ) - - step("pinning Xcode via boot LaunchDaemon") - let xcodeSelectPlist = """ - - - - - Labelcom.devbox.xcode-select - ProgramArguments - - /usr/bin/xcode-select - -s - \(xcodeApp) - - RunAtLoad - - - """ - let xcodeSelectPlistHex = xcodeSelectPlist.utf8 - .map { String(format: "%02x", $0) } - .joined() - try await guest.sh( - "printf '\(xcodeSelectPlistHex)' | xxd -r -p | " - + "sudo tee /Library/LaunchDaemons/com.devbox.xcode-select.plist > /dev/null && " - + "sudo chmod 644 /Library/LaunchDaemons/com.devbox.xcode-select.plist && " - + "sudo chown root:wheel /Library/LaunchDaemons/com.devbox.xcode-select.plist && " - + "sudo launchctl bootstrap system /Library/LaunchDaemons/com.devbox.xcode-select.plist" - ) - - step("installing Homebrew") - try await guest.sh( - "NONINTERACTIVE=1 /bin/bash -c \"$(curl -fsSL " - + "https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\"", - timeout: 1800 - ) - step("installing tools from Brewfile via brew bundle") - try guest.upload(localPath: brewfile, to: "/tmp/Brewfile") - try await guest.sh("brew bundle --file=/tmp/Brewfile", env: .brew, timeout: 1800) - - step("enabling autologin for \(adminUser)") - let encoded = kcpassword(guest.adminPass).base64EncodedString() - try await guest.sudo( - "bash -c 'echo \(encoded) | base64 -D > /etc/kcpassword && chmod 600 /etc/kcpassword " - + "&& defaults write /Library/Preferences/com.apple.loginwindow autoLoginUser \(adminUser)'" - ) - - step("verifying swift toolchain in guest") - print(try await guest.sh("xcrun swift --version")) - step("toolchain provisioning complete") -} - -let script = Script(usage: "vz run toolchain.swift ", min: 4) -let bundle = try script.bundle() -let xipPath = script[arg: 2] -let brewfilePath = script[arg: 3] - -try await Guest.session(bundle: bundle, adminPass: "vzvz") { guest in - try await provisionToolchain(guest, xip: xipPath, brewfile: brewfilePath) -} diff --git a/merge-queue/.gitignore b/merge-queue/.gitignore deleted file mode 100644 index 870e2ad9..00000000 --- a/merge-queue/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/vm/ -/.state/ diff --git a/merge-queue/Makefile b/merge-queue/Makefile deleted file mode 100644 index c71e9d38..00000000 --- a/merge-queue/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -VZ_DIR := $(CURDIR)/../vzy -VZ_BIN := $(VZ_DIR)/.build/release/vzy -DEVBOX := $(CURDIR)/../devbox -STATE := .state -BUNDLE ?= $(DEVBOX)/vm/devbox.bundle -ADMIN_USER ?= admin -ADMIN_PASS ?= vzvz -CANDIDATE ?= HEAD -BASE ?= origin/main - -.PHONY: bundle bar snapshots clean devbox-base -bundle: $(STATE)/post-ios - -bar: $(STATE)/post-ios - $(VZ_BIN) snapshot restore $(BUNDLE) post-ios - $(VZ_BIN) run $(CURDIR)/scripts/bar.swift $(BUNDLE) $(CANDIDATE) $(BASE) - -devbox-base: - $(MAKE) -C $(DEVBOX) post-toolchain - -$(STATE): - mkdir -p $(STATE) - -$(STATE)/ios: | devbox-base $(STATE) - $(VZ_BIN) snapshot restore $(BUNDLE) post-toolchain - $(VZ_BIN) run $(CURDIR)/scripts/ios.swift $(BUNDLE) - touch $@ - -$(STATE)/post-ios: $(STATE)/ios | $(STATE) - $(VZ_BIN) snapshot delete $(BUNDLE) post-ios 2>/dev/null || true - $(VZ_BIN) snapshot take $(BUNDLE) post-ios - touch $@ - -snapshots: - $(VZ_BIN) snapshot list $(BUNDLE) - -clean: - rm -rf $(STATE) diff --git a/merge-queue/scripts/bar.swift b/merge-queue/scripts/bar.swift deleted file mode 100644 index c54c6535..00000000 --- a/merge-queue/scripts/bar.swift +++ /dev/null @@ -1,92 +0,0 @@ -import Foundation -import VZKit - -final class DataBox: @unchecked Sendable { - var value = Data() -} - -@discardableResult -func host(_ args: [String], cwd: String? = nil) throws -> String { - let process = Process() - process.executableURL = URL(filePath: "/usr/bin/env") - process.arguments = args - if let cwd { process.currentDirectoryURL = URL(filePath: cwd) } - let out = Pipe() - let err = Pipe() - process.standardOutput = out - process.standardError = err - let outBox = DataBox() - let errBox = DataBox() - let group = DispatchGroup() - let queue = DispatchQueue(label: "mq-bar-host", attributes: .concurrent) - try process.run() - queue.async(group: group) { - outBox.value = (try? out.fileHandleForReading.readToEnd()) ?? Data() - } - queue.async(group: group) { - errBox.value = (try? err.fileHandleForReading.readToEnd()) ?? Data() - } - process.waitUntilExit() - group.wait() - guard process.terminationStatus == 0 else { - let stderr = String(decoding: errBox.value, as: UTF8.self) - throw VMError( - "host command failed (exit \(process.terminationStatus)): " - + "\(args.joined(separator: " "))\n\(stderr)" - ) - } - return String(decoding: outBox.value, as: UTF8.self) - .trimmingCharacters(in: .whitespacesAndNewlines) -} - -let script = Script(usage: "vz run bar.swift [candidate-ref] [base-ref]", min: 2) -let bundle = try script.bundle() -let candidateRef = script[arg: 2, default: "HEAD"] -let baseRef = script[arg: 3, default: "origin/main"] - -let cache = "grpc://100.121.199.61:9092" -let bazelFlags = "--remote_cache=\(cache) --remote_upload_local_results=false" -let remoteWork = "/Users/admin/work" - -let repoRoot = try host(["git", "rev-parse", "--show-toplevel"]) -let candidateSHA = try host(["git", "rev-parse", candidateRef], cwd: repoRoot) -let baseSHA = try host(["git", "rev-parse", baseRef], cwd: repoRoot) -step("candidate \(candidateSHA.prefix(8)) onto base \(baseSHA.prefix(8))") - -let work = NSTemporaryDirectory() + "mq-bar-work" -step("preparing candidate worktree at \(work)") -try? FileManager.default.removeItem(atPath: work) -try host(["git", "clone", "--local", "--quiet", "--no-checkout", repoRoot, work]) -try host(["git", "checkout", "--detach", "--quiet", candidateSHA], cwd: work) -do { - try host( - ["git", "-c", "user.name=merge-queue", "-c", "user.email=merge-queue@local", - "rebase", baseSHA], - cwd: work - ) -} catch { - try? host(["git", "rebase", "--abort"], cwd: work) - throw VMError( - "candidate \(candidateSHA.prefix(8)) does not rebase cleanly onto " - + "base \(baseSHA.prefix(8)) — rejecting: \(error)" - ) -} - -try await Guest.session(bundle: bundle, adminPass: "vzvz") { guest in - step("delivering candidate to guest \(remoteWork)") - try guest.rsync(localDir: work, to: remoteWork, exclude: []) - try await guest.sh("git config --global --add safe.directory \(remoteWork)") - - step("bazel test //... (first run fetches all external deps; slow)") - try await guest.sh( - "cd \(remoteWork) && bazelisk test //... \(bazelFlags) --flaky_test_attempts=3", - env: .brew, timeout: 10800 - ) - step("bazel run //tools/lint:check") - try await guest.sh( - "cd \(remoteWork) && bazelisk run //tools/lint:check", - env: .brew, timeout: 1800 - ) -} - -step("merge bar PASSED for candidate \(candidateSHA.prefix(8))") diff --git a/merge-queue/scripts/ios.swift b/merge-queue/scripts/ios.swift deleted file mode 100644 index 8b87b888..00000000 --- a/merge-queue/scripts/ios.swift +++ /dev/null @@ -1,22 +0,0 @@ -import Foundation -import VZKit - -func provisionIOS(_ guest: Guest) async throws { - if try await guest.test("xcrun simctl list devices available 2>/dev/null | grep -qi iPhone") { - step("an iPhone simulator is already available") - } else { - step("downloading iOS simulator runtime (multi-GB, slow)") - try await guest.sh("xcodebuild -downloadPlatform iOS", timeout: 5400) - } - - step("verifying an iPhone simulator is available") - try await guest.sh("xcrun simctl list devices available | grep -i iPhone") - step("ios provisioning complete") -} - -let script = Script(usage: "vz run ios.swift ", min: 2) -let bundle = try script.bundle() - -try await Guest.session(bundle: bundle, adminPass: "vzvz") { guest in - try await provisionIOS(guest) -}