From 20e5e8a8187e09f6a4a63cd6711fe074be729ca3 Mon Sep 17 00:00:00 2001 From: Chris Beiser Date: Sun, 19 Jul 2026 19:28:34 -0700 Subject: [PATCH] Add relevant iOS CI --- .github/workflows/ios-ci.yml | 81 ++++++++++++++++++++++++ .swiftlint.yml | 4 -- AGENTS.md | 4 +- scripts/swiftlint.sh | 2 +- solipsistweets/OnScreenTimeTracker.swift | 2 +- 5 files changed, 86 insertions(+), 7 deletions(-) create mode 100644 .github/workflows/ios-ci.yml diff --git a/.github/workflows/ios-ci.yml b/.github/workflows/ios-ci.yml new file mode 100644 index 0000000..b98224f --- /dev/null +++ b/.github/workflows/ios-ci.yml @@ -0,0 +1,81 @@ +name: iOS CI + +on: + workflow_dispatch: + pull_request: + push: + branches: + - main + +permissions: + contents: read + +concurrency: + group: ios-ci-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + lint: + name: SwiftLint + runs-on: macos-26 + timeout-minutes: 20 + + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Install SwiftLint + run: | + if ! command -v swiftlint >/dev/null 2>&1; then + brew install swiftlint + fi + + swiftlint version + + - name: Check formatting + run: | + scripts/swiftlint.sh fix + + if ! git diff --quiet -- solipsistweets EchoShareExtension; then + echo "::error::SwiftLint autofix/format changed files. Run scripts/swiftlint.sh fix and commit the result." + git diff -- solipsistweets EchoShareExtension + exit 1 + fi + + - name: Run SwiftLint + run: scripts/swiftlint.sh lint + + build: + name: Build + runs-on: macos-26 + timeout-minutes: 60 + + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Select Xcode 26 + run: | + set -euo pipefail + + if [ -d /Applications/Xcode_26.4.app ]; then + sudo xcode-select -s /Applications/Xcode_26.4.app + elif [ -d /Applications/Xcode_26.app ]; then + sudo xcode-select -s /Applications/Xcode_26.app + else + sudo xcode-select -s /Applications/Xcode.app + fi + + xcodebuild -version + xcodebuild -showsdks + + - name: Install SwiftLint + run: | + if ! command -v swiftlint >/dev/null 2>&1; then + brew install swiftlint + fi + + swiftlint version + + - name: Build + run: scripts/verify-full.sh diff --git a/.swiftlint.yml b/.swiftlint.yml index e17ccd7..78de46d 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -1,10 +1,6 @@ reporter: xcode strict: true -included: - - solipsistweets - - orion - excluded: - DerivedData - .context diff --git a/AGENTS.md b/AGENTS.md index 073c025..8d365fc 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -8,6 +8,8 @@ Use Verify Fast (`scripts/verify-fast.sh`) for changes isolated to the app targe Use Verify Full (`scripts/verify-full.sh`) when a change touches project settings, build scripts, or anything that should use the full verification path. It builds the `Verify Full` scheme. This repository has one app scheme, `solipsistweets`, and no watch target. +GitHub Actions runs `.github/workflows/ios-ci.yml` for pull requests, pushes to `main`, and manual dispatches. CI checks SwiftLint formatting and strict lint for both the app and share extension, then runs `scripts/verify-full.sh` as an unsigned simulator build. Signed device builds and installs remain local-only. + Use `scripts/build-simulator.sh` for a general compiler or smoke-check build and `scripts/build-device.sh` only when a signed iphoneos product is intentionally required. Both use repo-local `DerivedData/`; the simulator build is always unsigned and cannot inherit a physical-device destination. Override their destinations with `SIMULATOR_DESTINATION=...` or `DEVICE_DESTINATION=...`, respectively. Use `scripts/run-device.sh` to build the `solipsistweets` scheme, verify its signature, install it on a paired iPhone over Wi-Fi, and launch it. If more than one wireless iPhone is available, set `DEVICE_ID` to a listed device name, identifier, or UDID. The shared Conductor Run action invokes this script locally and is nonconcurrent because the physical device is shared. Runs keep output concise by default while native `xcodebuild` warnings and errors and `devicectl` errors remain visible. Set `RUN_VERBOSE=1` to restore full `xcodebuild` and `devicectl` output. @@ -52,7 +54,7 @@ For a new worktree, `scripts/seed-derived-data.sh` can copy a warm sibling `Deri SwiftLint is configured with focused safety/correctness rules in `.swiftlint.yml` and runs in strict mode. Broad size/name/shape rules and current style-only noise are disabled so formatting preferences do not drown out safety checks or block routine builds. -Run build-time lint with `scripts/swiftlint.sh build`; Xcode target phases run the same command during verification builds. Missing SwiftLint is a local warning but a CI error. Run the base config directly with `scripts/swiftlint.sh lint`. Run autofix-only style cleanup with `scripts/swiftlint.sh fix`. +Run build-time lint with `scripts/swiftlint.sh build`; Xcode target phases run the same command during verification builds. Missing SwiftLint is a local warning but a CI error. Run the base config directly with `scripts/swiftlint.sh lint`. Run autofix-only style cleanup with `scripts/swiftlint.sh fix`. With no paths supplied, both commands cover `solipsistweets` and `EchoShareExtension`. Install the optional pre-commit hook with `scripts/install-git-hooks.sh`; it sets `core.hooksPath` to `scripts/git-hooks`, runs the separate `.swiftlint-autofix.yml` path with SwiftLint `--fix --format` on staged Swift files, re-stages fixes, and aborts if a staged Swift file also has unstaged edits. Keep broad style gates out of strict lint unless existing code is baselined or fixed separately. diff --git a/scripts/swiftlint.sh b/scripts/swiftlint.sh index 50dd65d..4249645 100755 --- a/scripts/swiftlint.sh +++ b/scripts/swiftlint.sh @@ -10,7 +10,7 @@ if [[ $# -gt 0 ]]; then fi if [[ $# -eq 0 ]]; then - set -- solipsistweets + set -- . fi if ! command -v swiftlint >/dev/null 2>&1; then diff --git a/solipsistweets/OnScreenTimeTracker.swift b/solipsistweets/OnScreenTimeTracker.swift index 669098b..f9a6603 100644 --- a/solipsistweets/OnScreenTimeTracker.swift +++ b/solipsistweets/OnScreenTimeTracker.swift @@ -1,5 +1,5 @@ -import Foundation import Combine +import Foundation @MainActor final class OnScreenTimeTracker: ObservableObject {