remove gitnexus skills #91
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ci-${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| lint: | |
| runs-on: macos-15 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v5 | |
| - name: Select Xcode | |
| uses: maxim-lobanov/setup-xcode@v1 | |
| with: | |
| xcode-version: latest-stable | |
| - name: Install static-analysis tools | |
| run: brew install swiftformat swiftlint | |
| - name: Check formatting | |
| run: swiftformat --lint . | |
| - name: Lint | |
| run: swiftlint lint | |
| structure: | |
| runs-on: macos-15 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v5 | |
| - name: Select Xcode | |
| uses: maxim-lobanov/setup-xcode@v1 | |
| with: | |
| xcode-version: latest-stable | |
| - name: Check test target registration | |
| # Fails when a tracked test file is missing from its Xcode target's | |
| # Sources phase; a dropped test file would otherwise make CI shards | |
| # silently execute fewer tests. | |
| run: Scripts/check-test-registration.sh | |
| - name: Build EasyEngineCore standalone | |
| run: | | |
| xcodebuild \ | |
| -project EasyKey.xcodeproj \ | |
| -target EasyEngineCore \ | |
| -configuration Debug \ | |
| -destination "platform=macOS" \ | |
| build | |
| - name: Build EasyKeyKit standalone | |
| # Guards the explicit EasyKeyKit -> EasyEngineCore target dependency: | |
| # without it, Kit builds only when the app happens to link Core first. | |
| run: | | |
| xcodebuild \ | |
| -project EasyKey.xcodeproj \ | |
| -target EasyKeyKit \ | |
| -configuration Debug \ | |
| -destination "platform=macOS" \ | |
| build | |
| test: | |
| runs-on: macos-15 | |
| # Healthy shards finish in 2-29 minutes. A hung test (e.g. a system | |
| # permission dialog nobody dismisses on the hosted runner) must fail the | |
| # shard here instead of pending until the 6-hour runner cap or a manual | |
| # cancel, which left the coverage job waiting forever. | |
| timeout-minutes: 60 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| # Unit tests split across 4 parallel shards (~485 tests each). The | |
| # whole EasyKeyTests bundle was a single long pole: one hung/crashed | |
| # test stalled the entire suite for hours. Keep new test classes | |
| # balanced across the four shards below (the coverage job's 90% | |
| # threshold catches anything left out). | |
| - shard: unit-1 | |
| filter: >- | |
| -only-testing:EasyKeyTests/EngineCoreCoverageTests | |
| -only-testing:EasyKeyTests/KeySynthesizerPostingTests | |
| -only-testing:EasyKeyTests/MacroExpanderCoverageTests | |
| -only-testing:EasyKeyTests/TranslationModelTests | |
| -only-testing:EasyKeyTests/AppTranslationRuntimeTests | |
| -only-testing:EasyKeyTests/AppCoordinatorWiringTests | |
| -only-testing:EasyKeyTests/LocalizationTests | |
| -only-testing:EasyKeyTests/EngineCoverageGapTests | |
| -only-testing:EasyKeyTests/SettingsStoreTests | |
| -only-testing:EasyKeyTests/DomainTypeTests | |
| -only-testing:EasyKeyTests/ShortcutTests | |
| -only-testing:EasyKeyTests/TranslationCredentialStoreTests | |
| -only-testing:EasyKeyTests/TranslationPanelViewTests | |
| -only-testing:EasyKeyTests/KeyEventTests | |
| -only-testing:EasyKeyTests/StatusMenuBuilderTests | |
| -only-testing:EasyKeyTests/VietnameseEncodingTests | |
| -only-testing:EasyKeyTests/ClipboardServicesExtendedTests | |
| -only-testing:EasyKeyTests/LocalizationStoreSupplementTests | |
| -only-testing:EasyKeyTests/SessionSlotTests | |
| -only-testing:EasyKeyTests/ClipboardViewRenderingTests | |
| -only-testing:EasyKeyTests/ClipboardServicesTests | |
| -only-testing:EasyKeyTests/TranslationPanelGeometryTests | |
| -only-testing:EasyKeyTests/SelectedTextSimulatorTests | |
| -only-testing:EasyKeyTests/LoginItemControllerTests | |
| -only-testing:EasyKeyTests/EasyKeySettingsDeltaTests | |
| -only-testing:EasyKeyTests/AccessibilityRePromptTests | |
| -only-testing:EasyKeyTests/ConformanceFixtureTests | |
| -only-testing:EasyKeyTests/KeyboardServicePauseIsolationTests | |
| -only-testing:EasyKeyTests/SettingsRepositoryMigrationTests | |
| -only-testing:EasyKeyTests/UpdateServiceTestModeTests | |
| -only-testing:EasyKeyTests/KeySynthesizerEventOrderingTests | |
| - shard: unit-2 | |
| filter: >- | |
| -only-testing:EasyKeyTests/AppLogicCoverageTests | |
| -only-testing:EasyKeyTests/KitCoverageGapTests | |
| -only-testing:EasyKeyTests/KeyboardPipelineCoverageTests | |
| -only-testing:EasyKeyTests/KeyboardInputPipelineProcessTests | |
| -only-testing:EasyKeyTests/DeepLTranslationProviderTests | |
| -only-testing:EasyKeyTests/OpenAITranslationProviderTests | |
| -only-testing:EasyKeyTests/OpenAICompatibleTranslationProviderTests | |
| -only-testing:EasyKeyTests/AnthropicTranslationProviderTests | |
| -only-testing:EasyKeyTests/AnthropicCompatProviderTests | |
| -only-testing:EasyKeyTests/KeyboardServiceIntegrationTests | |
| -only-testing:EasyKeyTests/TranslationOptionsTests | |
| -only-testing:EasyKeyTests/ClipboardHistoryTests | |
| -only-testing:EasyKeyTests/TranslationSpeechControllerTests | |
| -only-testing:EasyKeyTests/FocusedElementInspectorExtendedTests | |
| -only-testing:EasyKeyTests/GeminiTranslationProviderTests | |
| -only-testing:EasyKeyTests/PasteboardClassifierTests | |
| -only-testing:EasyKeyTests/MacroStoreTests | |
| -only-testing:EasyKeyTests/ClipboardPersistenceTests | |
| -only-testing:EasyKeyTests/ObservableSettingsStoreTests | |
| -only-testing:EasyKeyTests/ShortcutKeyCaptureTests | |
| -only-testing:EasyKeyTests/AppCompatibilityTests | |
| -only-testing:EasyKeyTests/ClipboardHotKeyControllerTests | |
| -only-testing:EasyKeyTests/DeepLCredentialValidationTests | |
| -only-testing:EasyKeyTests/UpdateServiceTests | |
| -only-testing:EasyKeyTests/AppLogTests | |
| -only-testing:EasyKeyTests/ConverterTests | |
| -only-testing:EasyKeyTests/ValidatedTranslationEndpointTests | |
| -only-testing:EasyKeyTests/KeyboardInputPipelineAppSwitchTests | |
| -only-testing:EasyKeyTests/KeyboardTapIsolationTests | |
| -only-testing:EasyKeyTests/SettingsStoreAsyncWriteTests | |
| -only-testing:EasyKeyTests/CommandCDoublePressBoundaryTests | |
| -only-testing:EasyKeyTests/KeyboardPipelineCacheTimingTests | |
| -skip-testing:EasyKeyTests/AppLogicCoverageTests/testAppleTranslationSessionBridge_AttachWithDefaultSleep_CancellationCompletesAttach | |
| -skip-testing:EasyKeyTests/AppLogicCoverageTests/testAppleTranslationSessionBridge_TranslateWithNoDeliveredSession_RequestsConfigurationAndThrows | |
| # The two testAppleTranslationSessionBridge_* tests above construct a real | |
| # TranslationSession and crash the test process (SIGSEGV) on hosted runners | |
| # (no system translation daemon); they run in the non-blocking known-broken | |
| # shard below. | |
| # Real-window click-then-verify (sheet presentation) — hosted runners cannot | |
| # key an AppKit window, so presentation blocks the shard for the full per-test | |
| # timeout. Runs in the known-broken shard for coverage. | |
| - shard: unit-3 | |
| filter: >- | |
| -only-testing:EasyKeyTests/ViewRenderingCoverageTests | |
| -only-testing:EasyKeyTests/ClipboardPayloadStoreTests | |
| -only-testing:EasyKeyTests/ClipboardThumbnailLoaderTests | |
| -only-testing:EasyKeyTests/ClipboardKeyStoreTests | |
| -only-testing:EasyKeyTests/PasteboardWriterTests | |
| -only-testing:EasyKeyTests/ClipboardPanelPresenterTests | |
| -only-testing:EasyKeyTests/PasteboardSnapshotTests | |
| -only-testing:EasyKeyTests/ClipboardPanelPresenterExtendedTests | |
| -only-testing:EasyKeyTests/ClipboardActionCoordinatorExtendedTests | |
| -only-testing:EasyKeyTests/ClipboardWriteSuppressorTests | |
| -only-testing:EasyKeyTests/VietnameseEngineTonePlacementTests | |
| -only-testing:EasyKeyTests/AppCoordinatorTests | |
| -only-testing:EasyKeyTests/TranslationDomainModelTests | |
| -only-testing:EasyKeyTests/StatusItemControllerTests | |
| -only-testing:EasyKeyTests/SmartSwitchControllerTests | |
| -only-testing:EasyKeyTests/ConverterEdgeCaseTests | |
| -only-testing:EasyKeyTests/KeyboardServiceStateTests | |
| -only-testing:EasyKeyTests/SessionStateTests | |
| -only-testing:EasyKeyTests/ClipboardHistoryModelTests | |
| -only-testing:EasyKeyTests/VietnameseCharactersTests | |
| -only-testing:EasyKeyTests/LiveConfidenceTests | |
| -only-testing:EasyKeyTests/KeySynthesizerTests | |
| -only-testing:EasyKeyTests/AppleTranslationProviderTests | |
| -only-testing:EasyKeyTests/KeySynthesizerUtilityTests | |
| -only-testing:EasyKeyTests/ClipboardActionCoordinatorTests | |
| -only-testing:EasyKeyTests/KeyboardDiagnosticsRecorderTests | |
| -only-testing:EasyKeyTests/ClipboardMonitorTests | |
| -only-testing:EasyKeyTests/ClipboardPanelGeometryTests | |
| -only-testing:EasyKeyTests/GoogleCredentialValidationTests | |
| -only-testing:EasyKeyTests/WorkspaceObserverTests | |
| -only-testing:EasyKeyTests/AppCoordinatorLifecycleTests | |
| -only-testing:EasyKeyTests/AppMainMenuInstallerTests | |
| -only-testing:EasyKeyTests/KeyboardInputPipelineSettingsUpdateTests | |
| -only-testing:EasyKeyTests/AppCoordinatorConcurrencyTests | |
| -only-testing:EasyKeyTests/KeyboardInputPipelineLanguageToggleTests | |
| -only-testing:EasyKeyTests/LoginHelperHardeningTests | |
| -only-testing:EasyKeyTests/SmartSwitchStoreAsyncSaveTests | |
| -skip-testing:EasyKeyTests/ViewRenderingCoverageTests/testAboutSettingsView_OpenLicensesButton_PresentsSheet | |
| - shard: unit-4 | |
| filter: >- | |
| -only-testing:EasyKeyTests/VietnameseEngineEdgeCaseTests | |
| -only-testing:EasyKeyTests/ViewRenderingTests | |
| -only-testing:EasyKeyTests/VietnameseEngineTests | |
| -only-testing:EasyKeyTests/TranslationSettingsModelTests | |
| -only-testing:EasyKeyTests/MacroStoreEdgeCaseTests | |
| -only-testing:EasyKeyTests/AccessibilitySelectedTextReaderTests | |
| -only-testing:EasyKeyTests/SelectedTextCaptureCoordinatorTests | |
| -only-testing:EasyKeyTests/GoogleTranslationProviderTests | |
| -only-testing:EasyKeyTests/TranslationPanelPresenterTests | |
| -only-testing:EasyKeyTests/TranslationProviderResolverTests | |
| -only-testing:EasyKeyTests/TranslationModelCatalogTests | |
| -only-testing:EasyKeyTests/SmartSwitchStoreEdgeCaseTests | |
| -only-testing:EasyKeyTests/TranslationHotKeyControllerTests | |
| -only-testing:EasyKeyTests/KeyboardInputPipelineStaticTests | |
| -only-testing:EasyKeyTests/FocusedElementInspectorTests | |
| -only-testing:EasyKeyTests/SettingsRepositoryEdgeCaseTests | |
| -only-testing:EasyKeyTests/SmartSwitchStoreTests | |
| -only-testing:EasyKeyTests/HostSafetyTests | |
| -only-testing:EasyKeyTests/KeyboardEventTapTests | |
| -only-testing:EasyKeyTests/ClipboardOptionsTests | |
| -only-testing:EasyKeyTests/ClipboardRowPresenterTests | |
| -only-testing:EasyKeyTests/LogExporterTests | |
| -only-testing:EasyKeyTests/ArchitectureFitnessTests | |
| -only-testing:EasyKeyTests/SettingsWindowPresenterTests | |
| -only-testing:EasyKeyTests/KeychainAccessibilityMigrationTests | |
| -only-testing:EasyKeyTests/CarbonHotKeyIsolationTests | |
| -only-testing:EasyKeyTests/KeyboardServiceLatencyTests | |
| -only-testing:EasyKeyTests/LoginHelperWatchdogTests | |
| -only-testing:EasyKeyTests/SynthesizePasteIsolationTests | |
| - shard: ui-1 | |
| filter: >- | |
| -only-testing:EasyKeyUITests/SettingsCoverageTests | |
| -skip-testing:EasyKeyUITests/SettingsCoverageTests/testTranslationSettingsAppleLanguageSettingsExists | |
| - shard: ui-2 | |
| filter: >- | |
| -only-testing:EasyKeyUITests/SettingsInteractionTests | |
| -skip-testing:EasyKeyUITests/SettingsInteractionTests/testEncodingTypeInPreviewField | |
| -skip-testing:EasyKeyUITests/SettingsInteractionTests/testMacroSettingsSearchTyping | |
| - shard: ui-3 | |
| filter: >- | |
| -only-testing:EasyKeyUITests/SettingsNavigationTests | |
| -skip-testing:EasyKeyUITests/SettingsNavigationTests/testSidebarToggleHidesAndShows | |
| - shard: ui-4 | |
| filter: >- | |
| -only-testing:EasyKeyUITests/OnboardingCoverageTests | |
| -only-testing:EasyKeyUITests/SettingsAccessibilityTests | |
| -skip-testing:EasyKeyUITests/OnboardingCoverageTests/testOnboardingAccessibilityStepHasGrantButton | |
| -skip-testing:EasyKeyUITests/OnboardingCoverageTests/testOnboardingBackButtonReturnsToWelcome | |
| -skip-testing:EasyKeyUITests/OnboardingCoverageTests/testOnboardingContinueToAccessibilityStep | |
| -skip-testing:EasyKeyUITests/OnboardingCoverageTests/testOnboardingFinishButtonPresent | |
| -skip-testing:EasyKeyUITests/OnboardingCoverageTests/testOnboardingFinishDismisses | |
| -skip-testing:EasyKeyUITests/OnboardingCoverageTests/testOnboardingKeyboardReturnCompletes | |
| -skip-testing:EasyKeyUITests/OnboardingCoverageTests/testOnboardingReadyStepAppears | |
| -skip-testing:EasyKeyUITests/OnboardingCoverageTests/testOnboardingTypingMethodStepHasPickers | |
| - shard: ui-5 | |
| filter: >- | |
| -only-testing:EasyKeyUITests/SettingsWorkflowTests | |
| -only-testing:EasyKeyUITests/EasyKeyUITests | |
| -skip-testing:EasyKeyUITests/SettingsWorkflowTests/testAboutShowsOpenSourceLicenses | |
| -skip-testing:EasyKeyUITests/SettingsWorkflowTests/testOnboardingAccessibilityStepShowsGrantButton | |
| -skip-testing:EasyKeyUITests/SettingsWorkflowTests/testOnboardingStepThroughAllPages | |
| -skip-testing:EasyKeyUITests/SettingsWorkflowTests/testTranslationSettingsExpandsProviderBeforeConfiguringCredentials | |
| # Real-window click-then-verify-effect tests, plus the Apple | |
| # TranslationKit unit tests. GitHub-hosted macOS runners cannot make an | |
| # AppKit window key (accessibility tree is queryable, isHittable reports | |
| # true, but window activation never actually lands — see AppDelegate.swift's | |
| # activation-policy comment and fix-test.md), and constructing a real | |
| # TranslationSession crashes the test process with SIGSEGV because the | |
| # hosted runner has no system translation daemon. Kept running for | |
| # coverage and visibility, but never blocks merge; move to a self-hosted | |
| # runner with a real logged-in GUI session to make these count for real. | |
| - shard: ui-known-broken-on-hosted-runner | |
| filter: >- | |
| -only-testing:EasyKeyUITests/OnboardingCoverageTests/testOnboardingAccessibilityStepHasGrantButton | |
| -only-testing:EasyKeyUITests/OnboardingCoverageTests/testOnboardingBackButtonReturnsToWelcome | |
| -only-testing:EasyKeyUITests/OnboardingCoverageTests/testOnboardingContinueToAccessibilityStep | |
| -only-testing:EasyKeyUITests/OnboardingCoverageTests/testOnboardingFinishButtonPresent | |
| -only-testing:EasyKeyUITests/OnboardingCoverageTests/testOnboardingFinishDismisses | |
| -only-testing:EasyKeyUITests/OnboardingCoverageTests/testOnboardingKeyboardReturnCompletes | |
| -only-testing:EasyKeyUITests/OnboardingCoverageTests/testOnboardingReadyStepAppears | |
| -only-testing:EasyKeyUITests/OnboardingCoverageTests/testOnboardingTypingMethodStepHasPickers | |
| -only-testing:EasyKeyUITests/SettingsCoverageTests/testTranslationSettingsAppleLanguageSettingsExists | |
| -only-testing:EasyKeyUITests/SettingsInteractionTests/testEncodingTypeInPreviewField | |
| -only-testing:EasyKeyUITests/SettingsInteractionTests/testMacroSettingsSearchTyping | |
| -only-testing:EasyKeyUITests/SettingsNavigationTests/testSidebarToggleHidesAndShows | |
| -only-testing:EasyKeyUITests/SettingsWorkflowTests/testAboutShowsOpenSourceLicenses | |
| -only-testing:EasyKeyUITests/SettingsWorkflowTests/testOnboardingAccessibilityStepShowsGrantButton | |
| -only-testing:EasyKeyUITests/SettingsWorkflowTests/testOnboardingStepThroughAllPages | |
| -only-testing:EasyKeyUITests/SettingsWorkflowTests/testTranslationSettingsExpandsProviderBeforeConfiguringCredentials | |
| -only-testing:EasyKeyTests/AppLogicCoverageTests/testAppleTranslationSessionBridge_AttachWithDefaultSleep_CancellationCompletesAttach | |
| -only-testing:EasyKeyTests/AppLogicCoverageTests/testAppleTranslationSessionBridge_TranslateWithNoDeliveredSession_RequestsConfigurationAndThrows | |
| -only-testing:EasyKeyTests/ViewRenderingCoverageTests/testAboutSettingsView_OpenLicensesButton_PresentsSheet | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v5 | |
| - name: Select Xcode | |
| uses: maxim-lobanov/setup-xcode@v1 | |
| with: | |
| xcode-version: latest-stable | |
| - name: Resolve SPM dependencies | |
| run: | | |
| xcodebuild \ | |
| -project EasyKey.xcodeproj \ | |
| -scheme EasyKeyApp \ | |
| -resolvePackageDependencies | |
| - name: Run tests with coverage | |
| # ui-known-broken-on-hosted-runner never blocks merge: those tests are real but | |
| # can't pass on a GitHub-hosted macOS runner (see matrix comment above / fix-test.md). | |
| # No -retry-tests-on-failure: a test-process crash makes xcodebuild re-run the | |
| # ENTIRE shard, which is how a single SIGSEGV turned into multi-hour runs. | |
| # Per-test timeouts (10 min max) bound a hung test so the shard fails in | |
| # minutes instead of pending until the job's 60-minute timeout. | |
| continue-on-error: ${{ matrix.shard == 'ui-known-broken-on-hosted-runner' }} | |
| run: | | |
| xcodebuild test \ | |
| -project EasyKey.xcodeproj \ | |
| -scheme EasyKeyApp \ | |
| -destination "platform=macOS" \ | |
| -derivedDataPath build \ | |
| -clonedSourcePackagesDirPath build/SourcePackages \ | |
| -resultBundlePath build/TestResults.xcresult \ | |
| -enableCodeCoverage YES \ | |
| -test-timeouts-enabled YES \ | |
| -default-test-execution-time-allowance 600 \ | |
| -maximum-test-execution-time-allowance 600 \ | |
| ${{ matrix.filter }} | |
| - name: Fail shards that executed zero tests | |
| # xcodebuild succeeds when a filter matches no tests at all (e.g. a | |
| # suite dropped from the target), which would turn this shard | |
| # false-green. The known-broken shard is exempt: a test-process crash | |
| # at launch can legitimately leave it with zero executed tests. | |
| if: matrix.shard != 'ui-known-broken-on-hosted-runner' | |
| run: Scripts/check-shard-tests.sh build/TestResults.xcresult | |
| - name: Upload shard result bundle | |
| if: always() | |
| uses: actions/upload-artifact@v5 | |
| with: | |
| name: xcresult-${{ matrix.shard }} | |
| path: build/TestResults.xcresult | |
| retention-days: 14 | |
| coverage: | |
| needs: test | |
| runs-on: macos-15 | |
| timeout-minutes: 30 | |
| env: | |
| COVERAGE_THRESHOLD: "90" | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v5 | |
| - name: Select Xcode | |
| uses: maxim-lobanov/setup-xcode@v1 | |
| with: | |
| xcode-version: latest-stable | |
| - name: Download shard result bundles | |
| uses: actions/download-artifact@v5 | |
| with: | |
| pattern: xcresult-* | |
| path: shards | |
| - name: Merge result bundles | |
| run: | | |
| # download-artifact unwraps the .xcresult bundle directory on upload/download, | |
| # so each shard dir *is* the bundle content, not a TestResults.xcresult child. | |
| # xcresulttool requires the .xcresult extension to recognize the bundle, so | |
| # rename each shard dir before merging. | |
| for dir in shards/*/; do | |
| mv "$dir" "${dir%/}.xcresult" | |
| done | |
| xcrun xcresulttool merge shards/*.xcresult \ | |
| --output-path merged.xcresult | |
| - name: Enforce coverage gate | |
| run: Scripts/check-coverage.sh merged.xcresult "$COVERAGE_THRESHOLD" | |
| - name: Upload merged result bundle | |
| if: always() | |
| uses: actions/upload-artifact@v5 | |
| with: | |
| name: test-results | |
| path: merged.xcresult | |
| retention-days: 14 |