From 407d9cb82cc66f29840559427a7a1d57e94cb2d9 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sat, 24 Oct 2026 12:31:17 -0500 Subject: [PATCH 1/8] Build with Xcode 27.1 in GitHub Actions Apps built with the iOS 27.0 SDK are letterboxed on iPhone Duo's inner display; the 27.1 SDK runs them full screen. Xcode 27.1 is the default on the xcode-27 runner image. CircleCI stays on 27.0 so it keeps checking that the workspace still builds with 27.0. --- .github/workflows/build_loop.yml | 2 +- .github/workflows/build_loop_auto.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_loop.yml b/.github/workflows/build_loop.yml index 3a93a9fdc6..c6930d46c9 100644 --- a/.github/workflows/build_loop.yml +++ b/.github/workflows/build_loop.yml @@ -171,7 +171,7 @@ jobs: (vars.SCHEDULED_SYNC != 'false' && needs.check_status.outputs.NEW_COMMITS == 'true' ) steps: - name: Select Xcode version - run: "sudo xcode-select --switch /Applications/Xcode_27.0.app/Contents/Developer" + run: "sudo xcode-select --switch /Applications/Xcode_27.1.app/Contents/Developer" - name: Checkout Repo for building uses: actions/checkout@v5 diff --git a/.github/workflows/build_loop_auto.yml b/.github/workflows/build_loop_auto.yml index 83c12b1087..7619f088f0 100644 --- a/.github/workflows/build_loop_auto.yml +++ b/.github/workflows/build_loop_auto.yml @@ -199,7 +199,7 @@ jobs: (vars.SCHEDULED_SYNC != 'false' && needs.check_status.outputs.NEW_COMMITS == 'true' ) steps: - name: Select Xcode version - run: "sudo xcode-select --switch /Applications/Xcode_27.0.app/Contents/Developer" + run: "sudo xcode-select --switch /Applications/Xcode_27.1.app/Contents/Developer" - name: Checkout Repo for building uses: actions/checkout@v5 From 15f699a316c9dd886e8a3deed5ef75b447203863 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Thu, 5 Nov 2026 20:51:20 -0600 Subject: [PATCH 2/8] Fail certificate setup when Match fails and no renewal will run The certs step ignored the fastlane certs exit status so that the renewal check could nuke and recreate an expired certificate. When the check finds only other, valid Distribution certificates in the team, no renewal runs, the job still succeeded, and the build later failed at signing with the same Match error. Record the certs result and fail the job in that case, pointing to Match's error about the certificate stored in Match-Secrets. Reported in LoopKit/Loop#2661. --- .github/workflows/create_certs.yml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/create_certs.yml b/.github/workflows/create_certs.yml index 9ec166f9fd..6ee4c6c645 100644 --- a/.github/workflows/create_certs.yml +++ b/.github/workflows/create_certs.yml @@ -52,9 +52,15 @@ jobs: # Create or update Distribution certificate and provisioning profiles - name: Check and create or update Distribution certificate and profiles if needed + id: certs run: | echo "Running Fastlane certs lane..." - bundle exec fastlane certs || true # ignore and continue on errors without annotating an exit code + # Continue on errors without annotating an exit code; set_output fails the job if no renewal follows + if bundle exec fastlane certs; then + echo "certs_failed=false" >> $GITHUB_OUTPUT + else + echo "certs_failed=true" >> $GITHUB_OUTPUT + fi - name: Check Distribution certificate and launch Nuke certificates if needed run: bundle exec fastlane check_and_renew_certificates id: check_certs @@ -87,6 +93,11 @@ jobs: if [ "$FORCE_NUKE_CERTS" = "true" ]; then echo "::warning::‼️ Nuking of certificates was forced because the repository variable FORCE_NUKE_CERTS is set to 'true'." fi + # Fail if the certificate setup failed and no renewal will replace it + if [ "${{ steps.certs.outputs.certs_failed }}" = "true" ] && [ "$CERT_STATUS" != "true" ] && [ "$FORCE_NUKE_CERTS" != "true" ]; then + echo "::error::❌ Certificate setup failed, but no expired or missing Distribution certificate was found, so automated renewal will not run. See the Fastlane Match error in the 'Check and create or update Distribution certificate and profiles if needed' step: it is about the certificate stored in your Match-Secrets repository." + exit 1 + fi # Nuke Certs if needed, and if the repository variable ENABLE_NUKE_CERTS is set to 'true', or if FORCE_NUKE_CERTS is set to 'true', which will always force certs to be nuked nuke_certs: name: Nuke certificates From ffcbb5cc635343bdbc2537e5f8192da4ddc42269 Mon Sep 17 00:00:00 2001 From: marionbarker Date: Mon, 9 Nov 2026 12:05:08 -0800 Subject: [PATCH 3/8] Bump version to 3.14.12 --- VersionOverride.xcconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VersionOverride.xcconfig b/VersionOverride.xcconfig index 67978ed733..5addab6eb6 100644 --- a/VersionOverride.xcconfig +++ b/VersionOverride.xcconfig @@ -8,5 +8,5 @@ // Version [for DIY Loop] // configure the version number in LoopWorkspace -LOOP_MARKETING_VERSION = 3.14.11 +LOOP_MARKETING_VERSION = 3.14.12 CURRENT_PROJECT_VERSION = 57 From 9274005c51d6d75c57dd95062315fee23d7e93ed Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Tue, 10 Nov 2026 10:51:42 -0600 Subject: [PATCH 4/8] Point the certificate error at deleting Match-Secrets Wording from marionbarker's review of LoopKit/LoopWorkspace#573, tested on her fork, with "is not valid" softened to "could not use": Match can also fail on a wrong MATCH_PASSWORD or a profile problem. --- .github/workflows/create_certs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/create_certs.yml b/.github/workflows/create_certs.yml index 6ee4c6c645..92dff16b12 100644 --- a/.github/workflows/create_certs.yml +++ b/.github/workflows/create_certs.yml @@ -95,7 +95,7 @@ jobs: fi # Fail if the certificate setup failed and no renewal will replace it if [ "${{ steps.certs.outputs.certs_failed }}" = "true" ] && [ "$CERT_STATUS" != "true" ] && [ "$FORCE_NUKE_CERTS" != "true" ]; then - echo "::error::❌ Certificate setup failed, but no expired or missing Distribution certificate was found, so automated renewal will not run. See the Fastlane Match error in the 'Check and create or update Distribution certificate and profiles if needed' step: it is about the certificate stored in your Match-Secrets repository." + echo "::error::❌ Fastlane Match could not use the Distribution certificate in your Match-Secrets repository, and automated renewal will not run because another valid certificate exists. Delete https://github.com/${{ github.repository_owner }}/Match-Secrets and run action again: https://loopkit.github.io/loopdocs/browser/bb-errors/#delete-match-secrets" exit 1 fi # Nuke Certs if needed, and if the repository variable ENABLE_NUKE_CERTS is set to 'true', or if FORCE_NUKE_CERTS is set to 'true', which will always force certs to be nuked From c95bf5990ac0a07aed64a6d9e4fd15bea8df1f05 Mon Sep 17 00:00:00 2001 From: marionbarker Date: Tue, 10 Nov 2026 12:45:33 -0800 Subject: [PATCH 5/8] update submodules: * EversenseKit: read glucose right after connecting; send sensorStart for each new sensor * G7SensorKit: reconnect with a start delay so readings don't stop for hours while Loop is in the background * Loop: status screen layout for iPhone Duo's inner display * LoopKit: refresh glucose rate formatting when display units change; read settings saved by next-dev builds with presets * MedtrumKit: reconnect after a Bluetooth reset, keep unsaved patch settings on sync, base reset detection, patch change delivery state, new instruction screens * OmnipodKit: fix a crash from a replaced or forgotten pod connection; log connect setup and failed exchanges; record a bolus cut short by a pod fault --- EversenseKit | 2 +- G7SensorKit | 2 +- Loop | 2 +- LoopKit | 2 +- MedtrumKit | 2 +- OmnipodKit | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/EversenseKit b/EversenseKit index e7a1850fd2..f032110b5c 160000 --- a/EversenseKit +++ b/EversenseKit @@ -1 +1 @@ -Subproject commit e7a1850fd28665de2e61831d606abc1e4112c545 +Subproject commit f032110b5c432d078a0146c681eb21f34f062226 diff --git a/G7SensorKit b/G7SensorKit index dd91f465b8..dccdcfeea9 160000 --- a/G7SensorKit +++ b/G7SensorKit @@ -1 +1 @@ -Subproject commit dd91f465b8b7392354b74463b9b9cc7aae32db9f +Subproject commit dccdcfeea988c2b542cebb3bca91418f5d5a63da diff --git a/Loop b/Loop index 7bb1749228..b05f7be3c6 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit 7bb17492288f6a6ea76e427277e2d82661dd0a3e +Subproject commit b05f7be3c62636cc925ff4bfec46407a8fcbcb96 diff --git a/LoopKit b/LoopKit index 915f58309f..79f4291b22 160000 --- a/LoopKit +++ b/LoopKit @@ -1 +1 @@ -Subproject commit 915f58309ff61b6def4981df09dfd96e40bc50af +Subproject commit 79f4291b226222b8b08a7e75af618ca496c63831 diff --git a/MedtrumKit b/MedtrumKit index c33699595b..41a8202bd3 160000 --- a/MedtrumKit +++ b/MedtrumKit @@ -1 +1 @@ -Subproject commit c33699595b6f636d8ca1bff377a8765df5597c34 +Subproject commit 41a8202bd31fef12c9232c1a862afae00a387bc5 diff --git a/OmnipodKit b/OmnipodKit index 0c6d68b00d..859215ebc1 160000 --- a/OmnipodKit +++ b/OmnipodKit @@ -1 +1 @@ -Subproject commit 0c6d68b00d45f4fecd9b0fc0477fc00e2d7e4c02 +Subproject commit 859215ebc15e89078bf31d92d63a249b10949200 From 3a99f5267f028bf2ea167e48d7f602c16be2efa7 Mon Sep 17 00:00:00 2001 From: marionbarker Date: Tue, 10 Nov 2026 13:47:49 -0800 Subject: [PATCH 6/8] remove confusing message, skip fastlane check in yml files --- .github/workflows/add_identifiers.yml | 3 +++ .github/workflows/build_loop.yml | 1 + .github/workflows/build_loop_auto.yml | 1 + .github/workflows/create_certs.yml | 1 + .github/workflows/validate_secrets.yml | 3 +++ 5 files changed, 9 insertions(+) diff --git a/.github/workflows/add_identifiers.yml b/.github/workflows/add_identifiers.yml index 71bf56f91f..2bc22dbfb7 100644 --- a/.github/workflows/add_identifiers.yml +++ b/.github/workflows/add_identifiers.yml @@ -3,6 +3,9 @@ run-name: Add Identifiers (${{ github.ref_name }}) on: workflow_dispatch: +env: + FASTLANE_SKIP_UPDATE_CHECK: true + jobs: validate: name: Validate diff --git a/.github/workflows/build_loop.yml b/.github/workflows/build_loop.yml index c6930d46c9..6561445c39 100644 --- a/.github/workflows/build_loop.yml +++ b/.github/workflows/build_loop.yml @@ -8,6 +8,7 @@ env: UPSTREAM_REPO: LoopKit/LoopWorkspace UPSTREAM_BRANCH: ${{ github.ref_name }} # branch on upstream repository to sync from (replace with specific branch name if needed) TARGET_BRANCH: ${{ github.ref_name }} # target branch on fork to be kept in sync + FASTLANE_SKIP_UPDATE_CHECK: true jobs: # use a single runner for these sequential steps diff --git a/.github/workflows/build_loop_auto.yml b/.github/workflows/build_loop_auto.yml index 7619f088f0..98ec3964b9 100644 --- a/.github/workflows/build_loop_auto.yml +++ b/.github/workflows/build_loop_auto.yml @@ -12,6 +12,7 @@ env: UPSTREAM_REPO: LoopKit/LoopWorkspace UPSTREAM_BRANCH: ${{ github.ref_name }} # branch on upstream repository to sync from (replace with specific branch name if needed) TARGET_BRANCH: ${{ github.ref_name }} # target branch on fork to be kept in sync + FASTLANE_SKIP_UPDATE_CHECK: true jobs: # use a single runner for these sequential steps diff --git a/.github/workflows/create_certs.yml b/.github/workflows/create_certs.yml index 92dff16b12..69c2f10a29 100644 --- a/.github/workflows/create_certs.yml +++ b/.github/workflows/create_certs.yml @@ -11,6 +11,7 @@ env: FASTLANE_KEY_ID: ${{ secrets.FASTLANE_KEY_ID }} FASTLANE_ISSUER_ID: ${{ secrets.FASTLANE_ISSUER_ID }} FASTLANE_KEY: ${{ secrets.FASTLANE_KEY }} + FASTLANE_SKIP_UPDATE_CHECK: true jobs: validate: diff --git a/.github/workflows/validate_secrets.yml b/.github/workflows/validate_secrets.yml index b07655d5d9..1718bcd7f8 100644 --- a/.github/workflows/validate_secrets.yml +++ b/.github/workflows/validate_secrets.yml @@ -2,6 +2,9 @@ name: 1. Validate Secrets run-name: Validate Secrets (${{ github.ref_name }}) on: [workflow_call, workflow_dispatch] +env: + FASTLANE_SKIP_UPDATE_CHECK: true + jobs: validate-access-token: name: Access From 025c47954b53de01488d15b19f2a43401413a7c6 Mon Sep 17 00:00:00 2001 From: marionbarker Date: Tue, 10 Nov 2026 15:15:46 -0800 Subject: [PATCH 7/8] phase out build_loop_auto, restore cron to build_loop, update run names --- .github/workflows/build_loop.yml | 32 +++++++++++++++++++++++++-- .github/workflows/build_loop_auto.yml | 32 ++------------------------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/.github/workflows/build_loop.yml b/.github/workflows/build_loop.yml index 6561445c39..f0fcabcdd2 100644 --- a/.github/workflows/build_loop.yml +++ b/.github/workflows/build_loop.yml @@ -1,7 +1,11 @@ -name: 4. Build Loop Manual -run-name: Build Loop Manual (${{ github.ref_name }}) +name: 4. Build Loop +run-name: Build Loop (${{ github.ref_name }}) on: workflow_dispatch: + schedule: + # Check for updates every Sunday + # Later logic builds if there are updates or if it is the 2nd Sunday of the month + - cron: "33 7 * * 0" # Sunday at UTC 7:33 env: GH_PAT: ${{ secrets.GH_PAT }} @@ -145,6 +149,30 @@ jobs: echo "is_second_instance=false" >> "$GITHUB_OUTPUT" fi + # When a scheduled run finds nothing new to build, cancel the run so it shows + # as "cancelled" instead of "success" — a green check should always mean a + # new build was made. + cancel_when_no_build: + needs: check_status + name: Cancel run when there is nothing to build + runs-on: ubuntu-26.04 + permissions: + actions: write + if: | + github.event_name == 'schedule' && + !(vars.SCHEDULED_BUILD != 'false' && needs.check_status.outputs.IS_SECOND_IN_MONTH == 'true') && + !(vars.SCHEDULED_SYNC != 'false' && needs.check_status.outputs.NEW_COMMITS == 'true') + steps: + - name: Cancel the run + env: + GH_TOKEN: ${{ github.token }} + run: | + echo "Repository is up to date and no monthly build is due — cancelling this run so it is not reported as a successful build." >> "$GITHUB_STEP_SUMMARY" + gh run cancel ${{ github.run_id }} --repo ${{ github.repository }} + # Keep the job alive until the cancellation lands, so the run ends as + # "cancelled" rather than completing successfully first. + sleep 300 + # Checks if Distribution certificate is present and valid, optionally nukes and # creates new certs if the repository variable ENABLE_NUKE_CERTS == 'true' # only run if a build is planned diff --git a/.github/workflows/build_loop_auto.yml b/.github/workflows/build_loop_auto.yml index 98ec3964b9..d7afdf2765 100644 --- a/.github/workflows/build_loop_auto.yml +++ b/.github/workflows/build_loop_auto.yml @@ -1,11 +1,7 @@ -name: 4. Build Loop Auto -run-name: Build Loop Auto (${{ github.ref_name }}) +name: zzz Phasing Out +run-name: Phasing Out (${{ github.ref_name }}) on: workflow_dispatch: - schedule: - # Check for updates every Sunday - # Later logic builds if there are updates or if it is the 2nd Sunday of the month - - cron: "33 7 * * 0" # Sunday at UTC 7:33 env: GH_PAT: ${{ secrets.GH_PAT }} @@ -149,30 +145,6 @@ jobs: echo "is_second_instance=false" >> "$GITHUB_OUTPUT" fi - # When a scheduled run finds nothing new to build, cancel the run so it shows - # as "cancelled" instead of "success" — a green check should always mean a - # new build was made. - cancel_when_no_build: - needs: check_status - name: Cancel run when there is nothing to build - runs-on: ubuntu-26.04 - permissions: - actions: write - if: | - github.event_name == 'schedule' && - !(vars.SCHEDULED_BUILD != 'false' && needs.check_status.outputs.IS_SECOND_IN_MONTH == 'true') && - !(vars.SCHEDULED_SYNC != 'false' && needs.check_status.outputs.NEW_COMMITS == 'true') - steps: - - name: Cancel the run - env: - GH_TOKEN: ${{ github.token }} - run: | - echo "Repository is up to date and no monthly build is due — cancelling this run so it is not reported as a successful build." >> "$GITHUB_STEP_SUMMARY" - gh run cancel ${{ github.run_id }} --repo ${{ github.repository }} - # Keep the job alive until the cancellation lands, so the run ends as - # "cancelled" rather than completing successfully first. - sleep 300 - # Checks if Distribution certificate is present and valid, optionally nukes and # creates new certs if the repository variable ENABLE_NUKE_CERTS == 'true' # only run if a build is planned From 98963f4c597638cbad0e841a27bdfa328a920656 Mon Sep 17 00:00:00 2001 From: marionbarker Date: Wed, 11 Nov 2026 07:23:17 -0800 Subject: [PATCH 8/8] update submodule translations: * Updated translations from lokalise on Tue Nov 10 16:15:24 PST 2026; * Updated some Czech strings --- EversenseKit | 2 +- Loop | 2 +- LoopKit | 2 +- LoopSupport | 2 +- MedtrumKit | 2 +- MinimedKit | 2 +- OmnipodKit | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/EversenseKit b/EversenseKit index f032110b5c..9a3f3ec6f5 160000 --- a/EversenseKit +++ b/EversenseKit @@ -1 +1 @@ -Subproject commit f032110b5c432d078a0146c681eb21f34f062226 +Subproject commit 9a3f3ec6f5f707071d52d52ec1db975f0c2a390d diff --git a/Loop b/Loop index b05f7be3c6..813f07cb18 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit b05f7be3c62636cc925ff4bfec46407a8fcbcb96 +Subproject commit 813f07cb18bf0d31c2dbd720b68703e454d9691e diff --git a/LoopKit b/LoopKit index 79f4291b22..a7b43f4d8e 160000 --- a/LoopKit +++ b/LoopKit @@ -1 +1 @@ -Subproject commit 79f4291b226222b8b08a7e75af618ca496c63831 +Subproject commit a7b43f4d8e3cfcafe287c96303be13aff23492cd diff --git a/LoopSupport b/LoopSupport index 929bee8bd4..aad2874e31 160000 --- a/LoopSupport +++ b/LoopSupport @@ -1 +1 @@ -Subproject commit 929bee8bd484cc915fa6c303e7fdade61db34c0e +Subproject commit aad2874e31151ccaa30b5dbcc96348e1191a24e4 diff --git a/MedtrumKit b/MedtrumKit index 41a8202bd3..043bcec5b5 160000 --- a/MedtrumKit +++ b/MedtrumKit @@ -1 +1 @@ -Subproject commit 41a8202bd31fef12c9232c1a862afae00a387bc5 +Subproject commit 043bcec5b5656dddcd6273a85a1b4577703c631b diff --git a/MinimedKit b/MinimedKit index a7b26858e3..cce1a492f5 160000 --- a/MinimedKit +++ b/MinimedKit @@ -1 +1 @@ -Subproject commit a7b26858e3073ac8881e7303b675c6b0f8c51ee9 +Subproject commit cce1a492f5d8e1501681b3ddf0c6383670e778fc diff --git a/OmnipodKit b/OmnipodKit index 859215ebc1..8df3d7bea3 160000 --- a/OmnipodKit +++ b/OmnipodKit @@ -1 +1 @@ -Subproject commit 859215ebc15e89078bf31d92d63a249b10949200 +Subproject commit 8df3d7bea37dead538acba735901cebd29f0f668