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
50 changes: 30 additions & 20 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,20 @@ env:
SCHEME: "Codeagogo"
DESTINATION: "platform=macOS"

# Explicit bash runs steps with `-eo pipefail`, so an xcodebuild failure is not
# masked by the exit status of the xcbeautify formatter it is piped into.
defaults:
run:
shell: bash

jobs:
lint:
name: SwiftLint
runs-on: macos-14
runs-on: macos-26

steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v7

- name: Install SwiftLint
run: brew install swiftlint
Expand All @@ -27,22 +33,22 @@ jobs:

audit:
name: Dependency Audit
runs-on: macos-14
runs-on: macos-26

steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v7

- name: Audit Dependencies
run: ./scripts/audit-dependencies.sh

secrets:
name: Secrets Scan
runs-on: macos-14
runs-on: macos-26

steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v7
with:
fetch-depth: 0

Expand All @@ -54,26 +60,26 @@ jobs:

license-headers:
name: License Headers
runs-on: macos-14
runs-on: macos-26

steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v7

- name: Check license headers
run: ./scripts/license-header.sh --check

build-and-test:
name: Build and Test
runs-on: macos-14
runs-on: macos-26
needs: [lint, audit, secrets, license-headers]

steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v7

- name: Select Xcode
run: sudo xcode-select -s /Applications/Xcode_16.2.app/Contents/Developer
run: sudo xcode-select -s /Applications/Xcode_26.6.app/Contents/Developer

- name: Show Xcode version
run: xcodebuild -version
Expand All @@ -88,46 +94,50 @@ jobs:
CODE_SIGNING_REQUIRED=NO \
ENABLE_HARDENED_RUNTIME=NO \
ENABLE_APP_SANDBOX=NO \
| xcpretty
| xcbeautify

- name: Unit Tests
run: |
xcodebuild test \
-scheme "$SCHEME" \
-destination "$DESTINATION" \
-only-testing:"CodeagogoTests" \
-testPlan "Codeagogo-Unit" \
-configuration Debug \
CODE_SIGN_IDENTITY="-" \
CODE_SIGNING_REQUIRED=NO \
ENABLE_HARDENED_RUNTIME=NO \
ENABLE_APP_SANDBOX=NO \
| xcpretty
| xcbeautify

# The UI tests live only in the Codeagogo-UI test plan (it also skips the
# SearchPanelUITests suite, which hangs XCUITest). GitHub's macOS runners
# have a logged-in GUI session, which XCUITest needs; no display required.
- name: UI Tests
timeout-minutes: 20
run: |
xcodebuild test \
-scheme "$SCHEME" \
-destination "$DESTINATION" \
-only-testing:"CodeagogoUITests" \
-testPlan "Codeagogo-UI" \
-configuration Debug \
CODE_SIGN_IDENTITY="-" \
CODE_SIGNING_REQUIRED=YES \
ENABLE_HARDENED_RUNTIME=NO \
ENABLE_APP_SANDBOX=NO \
| xcpretty
| xcbeautify

build-artifact:
name: Build Release Artifact
runs-on: macos-14
runs-on: macos-26
needs: build-and-test
if: github.event_name == 'push' && github.ref == 'refs/heads/main'

steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v7

- name: Select Xcode
run: sudo xcode-select -s /Applications/Xcode_16.2.app/Contents/Developer
run: sudo xcode-select -s /Applications/Xcode_26.6.app/Contents/Developer

- name: Install Apple Certificate
env:
Expand Down Expand Up @@ -180,7 +190,7 @@ jobs:
zip -r "Codeagogo-macOS.zip" "Codeagogo.app"

- name: Upload Artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: Codeagogo-macOS
path: artifact/Codeagogo-macOS.zip
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ env:
jobs:
release:
name: Create Release
runs-on: macos-14
runs-on: macos-26
permissions:
contents: write

Expand All @@ -28,7 +28,7 @@ jobs:
fi

- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v7
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
Expand Down Expand Up @@ -107,7 +107,7 @@ jobs:
git push origin "v${{ inputs.version }}"

- name: Select Xcode
run: sudo xcode-select -s /Applications/Xcode_16.2.app/Contents/Developer
run: sudo xcode-select -s /Applications/Xcode_26.6.app/Contents/Developer

- name: Install Apple Certificate
if: env.APPLE_CERTIFICATE_BASE64 != ''
Expand Down Expand Up @@ -174,7 +174,7 @@ jobs:
zip -r "Codeagogo-v${{ inputs.version }}-macOS.zip" "Codeagogo.app"

- name: Create GitHub Release
uses: softprops/action-gh-release@v2
uses: softprops/action-gh-release@v3
with:
tag_name: v${{ inputs.version }}
name: Codeagogo v${{ inputs.version }}
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

## [Unreleased]

### Fixed
- **Settings window on smaller screens**: The Settings window had a fixed 1060pt height, so on shorter displays (such as a 13" MacBook Air) its bottom extended off-screen and the logging and diagnostics controls could not be reached. It now opens at most as tall as the screen's visible area, scrolls when the content doesn't fit, and can be resized between 480pt and its full height.

## [1.1.1] - 2026-06

### Fixed
Expand Down
2 changes: 2 additions & 0 deletions Codeagogo/CodeagogoApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ struct Snomed_LookupApp: App {
Settings {
SettingsView()
}
// Size the window from SettingsView's min/ideal/max height so it fits the screen.
.windowResizability(.contentSize)
.commands {
// Add items in the Help menu (native place for diagnostics)
CommandGroup(after: .help) {
Expand Down
22 changes: 21 additions & 1 deletion Codeagogo/SettingsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@
.foregroundStyle(.secondary)
.font(.footnote)
.padding(.top, 4)

Check warning on line 245 in Codeagogo/SettingsView.swift

View workflow job for this annotation

GitHub Actions / SwiftLint

Lines should not have trailing whitespace (trailing_whitespace)
GroupBox("FHIR Endpoint") {
VStack(alignment: .leading, spacing: 10) {
HStack(alignment: .center) {
Expand Down Expand Up @@ -356,7 +356,7 @@

GroupBox("Privacy") {
VStack(alignment: .leading, spacing: 10) {
Text("A random anonymous identifier is included in terminology server requests to help count active installations. It contains no personal information.")

Check warning on line 359 in Codeagogo/SettingsView.swift

View workflow job for this annotation

GitHub Actions / SwiftLint

Line should be 150 characters or less; currently it has 173 characters (line_length)
.foregroundStyle(.secondary)
.font(.footnote)

Expand Down Expand Up @@ -414,7 +414,27 @@
}
.padding(16)
}
.frame(width: 520, height: 1060)
.frame(width: 520)
.frame(minHeight: Self.minimumHeight, idealHeight: Self.fittingHeight, maxHeight: Self.contentHeight)
}

// MARK: - Window Sizing

/// Height at which all settings are visible without scrolling.
private static let contentHeight: CGFloat = 1060

/// Smallest height the window can be resized to.
private static let minimumHeight: CGFloat = 480

/// Space reserved for the window's title bar when fitting it to the screen.
private static let titleBarAllowance: CGFloat = 40

/// Initial window height: the full content height, capped to the main screen's
/// visible area so the window never extends past the bottom of smaller screens.
/// The scroll view handles the overflow.
private static var fittingHeight: CGFloat {
guard let visibleHeight = NSScreen.main?.visibleFrame.height else { return contentHeight }
return max(minimumHeight, min(contentHeight, visibleHeight - titleBarAllowance))
}

// MARK: - Code System Helpers
Expand All @@ -440,4 +460,4 @@
}
}
}

Check warning on line 463 in Codeagogo/SettingsView.swift

View workflow job for this annotation

GitHub Actions / SwiftLint

Files should have a single trailing newline (trailing_newline)
17 changes: 17 additions & 0 deletions CodeagogoUITests/CodeagogoUITestCase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,21 @@ class SNOMEDLookupUITestCase: XCTestCase {
}
return settingsWindow
}

/// Scrolls the window's scroll view until `element` can be clicked.
///
/// The Settings window is taller than small screens (such as CI runners),
/// so controls near the bottom of its scroll view start out off-screen and
/// are not hittable until scrolled into view.
///
/// - Parameters:
/// - element: The element to bring into view.
/// - window: The window containing the scroll view.
func scrollIntoView(_ element: XCUIElement, in window: XCUIElement) {
let scrollView = window.scrollViews.firstMatch
guard scrollView.exists else { return }
for _ in 0..<10 where !element.isHittable {
scrollView.scroll(byDeltaX: 0, deltaY: -200)
}
}
}
2 changes: 2 additions & 0 deletions CodeagogoUITests/SettingsViewUITests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ final class SettingsViewUITests: SNOMEDLookupUITestCase {
XCTFail("Debug logging toggle not found")
return
}
scrollIntoView(toggle, in: settingsWindow)
let initialValue = toggle.value as? Int ?? 0
toggle.click()
let newValue = toggle.value as? Int ?? 0
Expand All @@ -212,6 +213,7 @@ final class SettingsViewUITests: SNOMEDLookupUITestCase {
return
}
XCTAssertTrue(button.isEnabled, "Diagnostics button should be enabled")
scrollIntoView(button, in: settingsWindow)
button.click()
// Button should still exist after clicking
XCTAssertTrue(button.exists,
Expand Down
Loading