unit_tests.yml 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. name: zzz [DO NOT RUN] Automated unit tests
  2. on:
  3. pull_request:
  4. branches:
  5. - dev
  6. types: [opened, synchronize]
  7. paths-ignore:
  8. - '**.md'
  9. - '**/README'
  10. - '**.yml'
  11. - '**.txt'
  12. push:
  13. branches:
  14. - dev
  15. paths-ignore:
  16. - '**.md'
  17. - '**/README'
  18. - '**.yml'
  19. - '**.txt'
  20. jobs:
  21. # Guards the TrioAlgorithm SPM package declared in Package.swift.
  22. #
  23. # Package.swift is a "shadow" package: it compiles a hand-enumerated subset of
  24. # the app's sources so the oref algorithm builds standalone on macOS, which is
  25. # what lets CLI tools replay recorded inputs against it.
  26. #
  27. # The `test` job below cannot catch drift in that list, because the Xcode
  28. # target globs whole directories. Any commit that adds a cross-file dependency
  29. # inside an already-listed file breaks `swift test` while `test` stays green.
  30. # This job is the only thing that notices.
  31. #
  32. # Runs in parallel with `test` and needs no simulator, so it reports in well
  33. # under a minute.
  34. algorithm-package:
  35. name: Algorithm Package (swift test)
  36. runs-on: macos-26
  37. if: github.repository_owner == 'nightscout'
  38. steps:
  39. - name: Select Xcode version
  40. run: sudo xcode-select -s /Applications/Xcode_26.2.app/Contents/Developer
  41. # No submodules: the package declares no external dependencies and
  42. # compiles only files under Trio/Sources and TrioTests/OpenAPSSwiftTests.
  43. - name: Checkout code
  44. uses: actions/checkout@v5
  45. with:
  46. fetch-depth: 1
  47. - name: Restore cache
  48. id: spm-cache-restore
  49. uses: actions/cache/restore@v5
  50. with:
  51. path: .build
  52. key: ${{ runner.os }}-spm-algorithm-${{ hashFiles('Package.swift', 'Trio/Sources/**/*.swift', 'TrioTests/OpenAPSSwiftTests/**/*.swift') }}
  53. restore-keys: |
  54. ${{ runner.os }}-spm-algorithm-
  55. - name: Show Swift version
  56. run: swift --version
  57. - name: Run algorithm tests
  58. run: time swift test
  59. - name: Save cache
  60. if: always() && steps.spm-cache-restore.outputs.cache-hit != 'true'
  61. uses: actions/cache/save@v5
  62. with:
  63. path: .build
  64. key: ${{ runner.os }}-spm-algorithm-${{ hashFiles('Package.swift', 'Trio/Sources/**/*.swift', 'TrioTests/OpenAPSSwiftTests/**/*.swift') }}
  65. - name: Annotate algorithm package results
  66. if: always()
  67. run: |
  68. if [ "${{ job.status }}" = "success" ]; then
  69. echo "::notice title=Algorithm Package::✅ swift test passed"
  70. echo "✅ Algorithm package builds standalone on macOS and all tests passed" >> $GITHUB_STEP_SUMMARY
  71. else
  72. echo "::error title=Algorithm Package::❌ swift test failed"
  73. {
  74. echo "## ❌ Algorithm package (\`swift test\`) failed"
  75. echo ""
  76. echo "\`Package.swift\` enumerates its sources by hand, so it drifts when a"
  77. echo "listed file gains a dependency on a file that is not listed."
  78. echo ""
  79. echo "If the error is \`cannot find 'X' in scope\`, add the file declaring \`X\`"
  80. echo "to \`algorithmModels\` or \`algorithmHelpers\` in \`Package.swift\`."
  81. } >> $GITHUB_STEP_SUMMARY
  82. fi
  83. shell: bash
  84. test:
  85. name: Run Unit Tests
  86. runs-on: macos-26
  87. if: github.repository_owner == 'nightscout'
  88. steps:
  89. - name: Select Xcode version
  90. run: sudo xcode-select -s /Applications/Xcode_26.2.app/Contents/Developer
  91. - name: Checkout code
  92. uses: actions/checkout@v5
  93. with:
  94. fetch-depth: 1
  95. submodules: recursive
  96. - name: Restore cache
  97. id: cache-restore
  98. uses: actions/cache/restore@v5
  99. with:
  100. path: |
  101. /Users/runner/Library/Developer/Xcode/DerivedData
  102. .build
  103. key: ${{ runner.os }}-trio-${{ hashFiles('**/*.swift', '**/*.xcodeproj', '**/*.xcworkspace') }}
  104. restore-keys: |
  105. ${{ runner.os }}-trio-
  106. - name: Show cache contents before build
  107. run: |
  108. echo "📂 Contents of DerivedData:"
  109. ls -lah /Users/runner/Library/Developer/Xcode/DerivedData || echo "Directory not found"
  110. echo ""
  111. echo "📂 Contents of .build:"
  112. ls -lah .build || echo ".build directory not found"
  113. - name: List available simulators
  114. run: xcrun simctl list devices available
  115. - name: Build for testing
  116. run: |
  117. set -o pipefail && \
  118. time xcodebuild build-for-testing \
  119. -workspace Trio.xcworkspace \
  120. -scheme "Trio Tests" \
  121. -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' \
  122. - name: Check for uncommitted changes
  123. run: |
  124. CHANGES=$(git status --porcelain)
  125. if [ -n "$CHANGES" ]; then
  126. echo "Uncommitted changes detected:"
  127. echo "$CHANGES"
  128. echo "$CHANGES" | while read -r line; do
  129. FILE=$(echo $line | cut -c4-)
  130. echo "::warning file=$FILE::Uncommitted change detected"
  131. done
  132. exit 0
  133. else
  134. echo "No uncommitted changes detected."
  135. fi
  136. shell: bash
  137. - name: Show cache contents after build
  138. run: |
  139. echo "📂 Updated DerivedData contents:"
  140. du -sh /Users/runner/Library/Developer/Xcode/DerivedData || echo "Directory not found"
  141. ls -lah /Users/runner/Library/Developer/Xcode/DerivedData || echo "Directory not found"
  142. echo ""
  143. echo "📂 Updated .build contents:"
  144. du -sh .build || echo ".build directory not found"
  145. ls -lah .build || echo ".build directory not found"
  146. - name: Save cache
  147. if: steps.cache-restore.outputs.cache-hit != 'true'
  148. uses: actions/cache/save@v5
  149. with:
  150. path: |
  151. /Users/runner/Library/Developer/Xcode/DerivedData
  152. .build
  153. key: ${{ runner.os }}-trio-${{ hashFiles('**/*.swift', '**/*.xcodeproj', '**/*.xcworkspace') }}
  154. - name: Run tests
  155. run: |
  156. set -o pipefail
  157. time xcodebuild test-without-building \
  158. -workspace Trio.xcworkspace \
  159. -scheme "Trio Tests" \
  160. -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' \
  161. $([ "$ENABLE_PARALLEL_TESTING" = "true" ] && echo "-parallel-testing-enabled YES") \
  162. 2>&1 | tee xcodebuild.log
  163. - name: Annotate test results
  164. if: always()
  165. run: |
  166. if [ -f xcodebuild.log ]; then
  167. if grep -q "Failing tests:" xcodebuild.log; then
  168. echo "::error title=Unit Tests Failed::Some tests failed"
  169. echo "## ❌ Some tests failed:" >> $GITHUB_STEP_SUMMARY
  170. grep -A 20 "Failing tests:" xcodebuild.log | \
  171. grep -E '^\s+[A-Za-z0-9]+\..+\(\)' | \
  172. sed 's/^/ - /' >> $GITHUB_STEP_SUMMARY
  173. echo "::group::Failed Test List"
  174. grep -A 20 "Failing tests:" xcodebuild.log | \
  175. grep -E '^\s+[A-Za-z0-9]+\..+\(\)' | \
  176. sed 's/^/ - /'
  177. echo "::endgroup::"
  178. else
  179. echo "::notice title=Unit Tests Passed::✅ All tests passed"
  180. echo "✅ All tests passed" >> $GITHUB_STEP_SUMMARY
  181. fi
  182. else
  183. echo "::warning::Test log (xcodebuild.log) not found"
  184. fi