From dd8e574340be43840fef409bdac028249060e70f Mon Sep 17 00:00:00 2001 From: Alasdair McCall Date: Tue, 19 May 2026 15:35:13 +0100 Subject: [PATCH 1/7] ALFMOB-203: migrate fastlane match repo to Mindera/Alfie-match Swap MATCH_GIT_URL and MATCH_GIT_BRANCH in fastlane/.env.default from the lapsed Bitbucket repo to the new GitHub-hosted match repo, and rewrite the release-job SSH setup step in alfie.yml to use the MATCH_GIT_SSH_KEY secret against github.com host keys. The matching MATCH_GIT_URL Actions secret on Mindera/Alfie-iOS has been updated separately; that secret is the live override at alfie.yml:198, the .env.default change keeps local dev coherent. --- .github/workflows/alfie.yml | 8 ++++---- fastlane/.env.default | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/alfie.yml b/.github/workflows/alfie.yml index 824695bd..ed631361 100644 --- a/.github/workflows/alfie.yml +++ b/.github/workflows/alfie.yml @@ -158,12 +158,12 @@ jobs: bundle config set --local path 'vendor/bundle' bundle install --jobs 4 --retry 3 - - name: Set up SSH for Bitbucket + - name: Set up SSH for match repo run: | mkdir -p ~/.ssh - echo "${{ secrets.BITBUCKET_SSH_KEY }}" > ~/.ssh/id_rsa - chmod 600 ~/.ssh/id_rsa - ssh-keyscan -t rsa bitbucket.org >> ~/.ssh/known_hosts + echo "${{ secrets.MATCH_GIT_SSH_KEY }}" > ~/.ssh/id_ed25519 + chmod 600 ~/.ssh/id_ed25519 + ssh-keyscan -t rsa,ecdsa,ed25519 github.com >> ~/.ssh/known_hosts - name: Import GPG Private Key and Decrypt sensitive files env: diff --git a/fastlane/.env.default b/fastlane/.env.default index a851f4b7..5ab66130 100644 --- a/fastlane/.env.default +++ b/fastlane/.env.default @@ -48,8 +48,8 @@ MATCH_READONLY=true MATCH_APP_IDENTIFIER=${APP_IDENTIFIER} -MATCH_GIT_URL="git@bitbucket.org:mindera/ios-certificates.git" -MATCH_GIT_BRANCH="alfie" +MATCH_GIT_URL="git@github.com:Mindera/Alfie-match.git" +MATCH_GIT_BRANCH="main" MATCH_SHALLOW_CLONE=true MATCH_CLONE_BRANCH_DIRECTLY=true From 0c4293bd93f8c4b69eb67e441acc1141780a9f4d Mon Sep 17 00:00:00 2001 From: Alasdair McCall Date: Tue, 19 May 2026 15:35:19 +0100 Subject: [PATCH 2/7] ALFMOB-203: build test bundles in verify.sh verify.sh chains build-for-verification.sh into test-for-verification.sh --skip-build, which uses xcodebuild test-without-building. That action requires test target bundles to already exist on disk, but a plain `build` only produces the main app product. Swap `build` for `build-for-testing` in both xcodebuild invocations so the test bundles get produced and the skip-build test step has artefacts to run against. Pre-existing bug surfaced while verifying the match migration. --- Alfie/scripts/build-for-verification.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Alfie/scripts/build-for-verification.sh b/Alfie/scripts/build-for-verification.sh index f7c5dc07..76f0a99b 100755 --- a/Alfie/scripts/build-for-verification.sh +++ b/Alfie/scripts/build-for-verification.sh @@ -14,12 +14,12 @@ echo "📂 Project: $PROJECT_FILE" echo "📱 Scheme: $SCHEME" echo "" -# Try to build with generic iOS Simulator destination (most portable) -echo "🎯 Attempting build with generic iOS Simulator destination..." +# Try to build test bundles with generic iOS Simulator destination (most portable) +echo "🎯 Attempting build-for-testing with generic iOS Simulator destination..." xcodebuild -project "$PROJECT_FILE" \ -scheme "$SCHEME" \ -destination 'platform=iOS Simulator,name=Any iOS Simulator Device' \ - build 2>&1 | tee /tmp/alfie_build.log + build-for-testing 2>&1 | tee /tmp/alfie_build.log BUILD_RESULT=${PIPESTATUS[0]} @@ -53,11 +53,11 @@ if grep -q "Unable to find a device matching the provided destination" /tmp/alfi echo "📱 Using simulator: $SIMULATOR_NAME ($SIMULATOR_ID)" echo "" - # Build with specific simulator + # Build test bundles with specific simulator xcodebuild -project "$PROJECT_FILE" \ -scheme "$SCHEME" \ -destination "id=$SIMULATOR_ID" \ - build 2>&1 | tee /tmp/alfie_build.log + build-for-testing 2>&1 | tee /tmp/alfie_build.log BUILD_RESULT=${PIPESTATUS[0]} From 29891330bb0c83721fe3d8496158fbf471df758c Mon Sep 17 00:00:00 2001 From: Alasdair McCall Date: Tue, 19 May 2026 15:45:58 +0100 Subject: [PATCH 3/7] ALFMOB-203: refresh Gemfile.lock and allow parallel UI tests - Refresh Gemfile.lock against current Bundler/Ruby toolchain. - Drop `parallelizable = "NO"` on AlfieUITests scheme so UI tests can run in parallel. --- .../xcschemes/AlfieUITests.xcscheme | 3 +- Gemfile.lock | 108 +++++++++--------- 2 files changed, 57 insertions(+), 54 deletions(-) diff --git a/Alfie/Alfie.xcodeproj/xcshareddata/xcschemes/AlfieUITests.xcscheme b/Alfie/Alfie.xcodeproj/xcshareddata/xcschemes/AlfieUITests.xcscheme index 6fb9f2de..97cf6207 100644 --- a/Alfie/Alfie.xcodeproj/xcshareddata/xcschemes/AlfieUITests.xcscheme +++ b/Alfie/Alfie.xcodeproj/xcshareddata/xcschemes/AlfieUITests.xcscheme @@ -15,8 +15,7 @@ shouldAutocreateTestPlan = "YES"> + skipped = "NO"> = 2.0.2, < 8.0) artifactory (3.0.17) atomos (0.1.3) aws-eventstream (1.4.0) - aws-partitions (1.1196.0) - aws-sdk-core (3.240.0) + aws-partitions (1.1250.0) + aws-sdk-core (3.247.0) aws-eventstream (~> 1, >= 1.3.0) aws-partitions (~> 1, >= 1.992.0) aws-sigv4 (~> 1.9) @@ -17,18 +17,19 @@ GEM bigdecimal jmespath (~> 1, >= 1.6.1) logger - aws-sdk-kms (1.118.0) - aws-sdk-core (~> 3, >= 3.239.1) + aws-sdk-kms (1.125.0) + aws-sdk-core (~> 3, >= 3.247.0) aws-sigv4 (~> 1.5) - aws-sdk-s3 (1.208.0) - aws-sdk-core (~> 3, >= 3.234.0) + aws-sdk-s3 (1.222.0) + aws-sdk-core (~> 3, >= 3.247.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.5) aws-sigv4 (1.12.1) aws-eventstream (~> 1, >= 1.0.2) babosa (1.0.4) - base64 (0.2.0) - bigdecimal (4.0.1) + base64 (0.3.0) + benchmark (0.5.0) + bigdecimal (4.1.2) claide (1.1.0) colored (1.2) colored2 (3.1.2) @@ -42,7 +43,7 @@ GEM dotenv (2.8.1) emoji_regex (3.2.3) excon (0.112.0) - faraday (1.10.4) + faraday (1.10.5) faraday-em_http (~> 1.0) faraday-em_synchrony (~> 1.0) faraday-excon (~> 1.1) @@ -61,25 +62,26 @@ GEM faraday-em_synchrony (1.0.1) faraday-excon (1.1.0) faraday-httpclient (1.0.1) - faraday-multipart (1.1.1) + faraday-multipart (1.2.0) multipart-post (~> 2.0) faraday-net_http (1.0.2) faraday-net_http_persistent (1.2.0) faraday-patron (1.0.0) faraday-rack (1.0.0) - faraday-retry (1.0.3) + faraday-retry (1.0.4) faraday_middleware (1.2.1) faraday (~> 1.0) - fastimage (2.4.0) - fastlane (2.230.0) - CFPropertyList (>= 2.3, < 4.0.0) - abbrev (~> 0.1.2) + fastimage (2.4.1) + fastlane (2.234.0) + CFPropertyList (>= 2.3, < 5.0.0) + abbrev (~> 0.1) addressable (>= 2.8, < 3.0.0) artifactory (~> 3.0) - aws-sdk-s3 (~> 1.0) + aws-sdk-s3 (~> 1.197) babosa (>= 1.0.3, < 2.0.0) - base64 (~> 0.2.0) - bundler (>= 1.12.0, < 3.0.0) + base64 (~> 0.2) + benchmark (>= 0.1.0) + bundler (>= 1.17.3, < 5.0.0) colored (~> 1.2) commander (~> 4.6) csv (~> 3.3) @@ -90,11 +92,11 @@ GEM faraday-cookie_jar (~> 0.0.6) faraday_middleware (~> 1.0) fastimage (>= 2.1.0, < 3.0.0) - fastlane-sirp (>= 1.0.0) + fastlane-sirp (>= 1.1.0) gh_inspector (>= 1.1.2, < 2.0.0) google-apis-androidpublisher_v3 (~> 0.3) google-apis-playcustomapp_v1 (~> 0.1) - google-cloud-env (>= 1.6.0, < 2.0.0) + google-cloud-env (>= 1.6.0, <= 2.1.1) google-cloud-storage (~> 1.31) highline (~> 2.0) http-cookie (~> 1.0.5) @@ -103,10 +105,11 @@ GEM logger (>= 1.6, < 2.0) mini_magick (>= 4.9.4, < 5.0.0) multipart-post (>= 2.0.0, < 3.0.0) - mutex_m (~> 0.3.0) + mutex_m (~> 0.3) naturally (~> 2.2) - nkf (~> 0.2.0) + nkf (~> 0.2) optparse (>= 0.1.1, < 1.0.0) + ostruct (>= 0.1.0) plist (>= 3.1.0, < 4.0.0) rubyzip (>= 2.0.0, < 3.0.0) security (= 0.1.5) @@ -119,41 +122,42 @@ GEM xcodeproj (>= 1.13.0, < 2.0.0) xcpretty (~> 0.4.1) xcpretty-travis-formatter (>= 0.0.3, < 2.0.0) - fastlane-sirp (1.0.0) - sysrandom (~> 1.0) + fastlane-sirp (1.1.0) gh_inspector (1.1.3) - google-apis-androidpublisher_v3 (0.54.0) - google-apis-core (>= 0.11.0, < 2.a) - google-apis-core (0.11.3) + google-apis-androidpublisher_v3 (0.100.0) + google-apis-core (>= 0.15.0, < 2.a) + google-apis-core (0.18.0) addressable (~> 2.5, >= 2.5.1) - googleauth (>= 0.16.2, < 2.a) - httpclient (>= 2.8.1, < 3.a) + googleauth (~> 1.9) + httpclient (>= 2.8.3, < 3.a) mini_mime (~> 1.0) + mutex_m representable (~> 3.0) retriable (>= 2.0, < 4.a) - rexml - google-apis-iamcredentials_v1 (0.17.0) - google-apis-core (>= 0.11.0, < 2.a) - google-apis-playcustomapp_v1 (0.13.0) - google-apis-core (>= 0.11.0, < 2.a) - google-apis-storage_v1 (0.31.0) - google-apis-core (>= 0.11.0, < 2.a) + google-apis-iamcredentials_v1 (0.27.0) + google-apis-core (>= 0.15.0, < 2.a) + google-apis-playcustomapp_v1 (0.17.0) + google-apis-core (>= 0.15.0, < 2.a) + google-apis-storage_v1 (0.62.0) + google-apis-core (>= 0.15.0, < 2.a) google-cloud-core (1.8.0) google-cloud-env (>= 1.0, < 3.a) google-cloud-errors (~> 1.0) - google-cloud-env (1.6.0) - faraday (>= 0.17.3, < 3.0) - google-cloud-errors (1.5.0) - google-cloud-storage (1.47.0) + google-cloud-env (2.1.1) + faraday (>= 1.0, < 3.a) + google-cloud-errors (1.6.0) + google-cloud-storage (1.60.0) addressable (~> 2.8) digest-crc (~> 0.4) - google-apis-iamcredentials_v1 (~> 0.1) - google-apis-storage_v1 (~> 0.31.0) + google-apis-core (>= 0.18, < 2) + google-apis-iamcredentials_v1 (~> 0.18) + google-apis-storage_v1 (>= 0.42) google-cloud-core (~> 1.6) - googleauth (>= 0.16.2, < 2.a) + googleauth (~> 1.9) mini_mime (~> 1.0) - googleauth (1.8.1) - faraday (>= 0.17.3, < 3.a) + googleauth (1.11.2) + faraday (>= 1.0, < 3.a) + google-cloud-env (~> 2.1) jwt (>= 1.4, < 3.0) multi_json (~> 1.11) os (>= 0.9, < 2.0) @@ -164,13 +168,13 @@ GEM httpclient (2.9.0) mutex_m jmespath (1.6.2) - json (2.18.0) + json (2.19.5) jwt (2.10.2) base64 logger (1.7.0) mini_magick (4.13.2) mini_mime (1.1.5) - multi_json (1.18.0) + multi_json (1.21.1) multipart-post (2.4.1) mutex_m (0.3.0) nanaimo (0.4.0) @@ -178,14 +182,15 @@ GEM nkf (0.2.0) optparse (0.8.1) os (1.1.4) + ostruct (0.6.3) plist (3.7.2) - public_suffix (7.0.0) - rake (13.3.1) + public_suffix (7.0.5) + rake (13.4.2) representable (3.2.0) declarative (< 0.1.0) trailblazer-option (>= 0.1.1, < 0.2.0) uber (< 0.2.0) - retriable (3.1.2) + retriable (3.4.1) rexml (3.4.4) rouge (3.28.0) ruby2_keywords (0.0.5) @@ -199,7 +204,6 @@ GEM simctl (1.6.10) CFPropertyList naturally - sysrandom (1.0.5) terminal-notifier (2.0.0) terminal-table (3.0.2) unicode-display_width (>= 1.1.1, < 3) From 4ac81e3abc30b36a7bdb278033be2c658b027c10 Mon Sep 17 00:00:00 2001 From: Alasdair McCall Date: Tue, 19 May 2026 15:53:11 +0100 Subject: [PATCH 4/7] ALFMOB-203: TEMP allow workflow_dispatch on release job MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Temporary verification commit — relaxes the release-job gate so a manual `gh workflow run` can exercise the migrated match path end-to-end on this PR branch before merging. Revert before merge. --- .github/workflows/alfie.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/alfie.yml b/.github/workflows/alfie.yml index ed631361..97d734fa 100644 --- a/.github/workflows/alfie.yml +++ b/.github/workflows/alfie.yml @@ -129,7 +129,7 @@ jobs: needs: [setup, unit-tests] runs-on: macos-15 timeout-minutes: 60 - if: github.event_name == 'push' + if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' steps: - name: Checkout Code uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 From 24ce59f3c1b851d900b55a2a84118999b5940bbb Mon Sep 17 00:00:00 2001 From: Alasdair McCall Date: Tue, 19 May 2026 16:55:30 +0100 Subject: [PATCH 5/7] ALFMOB-203: install Brewfile formulas in release job MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The release job uses `git secret reveal` (from the git-secret formula in Brewfile) to decrypt sensitive files, but never ran `brew bundle install`. The setup and unit-tests jobs both do; release alone was relying on git-secret being present without ever installing it. Add the missing step, mirroring the unit-tests job's setup. Surfaced during workflow_dispatch verification of the match migration — release job had been failing earlier on the SSH step, masking this. --- .github/workflows/alfie.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/alfie.yml b/.github/workflows/alfie.yml index 97d734fa..c5f88398 100644 --- a/.github/workflows/alfie.yml +++ b/.github/workflows/alfie.yml @@ -153,6 +153,10 @@ jobs: restore-keys: | spm-${{ runner.os }}- + - name: Install Homebrew formulas + run: | + brew bundle install + - name: Configure Bundler run: | bundle config set --local path 'vendor/bundle' From 13075969c3c70a7e2b5336d44d17760cee0e30e9 Mon Sep 17 00:00:00 2001 From: Alasdair McCall Date: Tue, 19 May 2026 17:39:16 +0100 Subject: [PATCH 6/7] ALFMOB-203: bump runners to macos-26 for iOS 26 SDK MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apple now rejects TestFlight uploads built against pre-iOS 26 SDKs: Validation failed SDK version issue. This app was built with the iOS 18.5 SDK. All iOS and iPadOS apps must be built with the iOS 26 SDK or later, included in Xcode 26 or later. The macos-15 runner image ships with an Xcode that produces the iOS 18.5 SDK. Bump all three jobs (setup, unit-tests, release) to macos-26, which carries Xcode 26 by default. Surfaced after the match migration started reaching upload_to_testflight for the first time in months — match itself works, this was the next gate up. --- .github/workflows/alfie.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/alfie.yml b/.github/workflows/alfie.yml index c5f88398..af6eaf3b 100644 --- a/.github/workflows/alfie.yml +++ b/.github/workflows/alfie.yml @@ -21,7 +21,7 @@ env: jobs: setup: - runs-on: macos-15 + runs-on: macos-26 timeout-minutes: 15 steps: - name: Checkout Code @@ -59,7 +59,7 @@ jobs: unit-tests: needs: setup - runs-on: macos-15 + runs-on: macos-26 timeout-minutes: 30 steps: - name: Checkout Code @@ -127,7 +127,7 @@ jobs: release: needs: [setup, unit-tests] - runs-on: macos-15 + runs-on: macos-26 timeout-minutes: 60 if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' steps: From fe89353aea68b41c8c3097a9991a7d5d1c1f7a8a Mon Sep 17 00:00:00 2001 From: Alasdair McCall Date: Tue, 19 May 2026 18:13:43 +0100 Subject: [PATCH 7/7] ALFMOB-203: revert temporary workflow_dispatch on release job Verified end-to-end on workflow_dispatch (run 26111542560): match clones from Mindera/Alfie-match, gym builds against the iOS 26 SDK, upload_to_testflight succeeds. Restore the push-only gate. --- .github/workflows/alfie.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/alfie.yml b/.github/workflows/alfie.yml index af6eaf3b..2a55117f 100644 --- a/.github/workflows/alfie.yml +++ b/.github/workflows/alfie.yml @@ -129,7 +129,7 @@ jobs: needs: [setup, unit-tests] runs-on: macos-26 timeout-minutes: 60 - if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' + if: github.event_name == 'push' steps: - name: Checkout Code uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1