From 8d79fe558113797bc04d1cec70670f705f2590f6 Mon Sep 17 00:00:00 2001 From: Hannes Achleitner Date: Thu, 1 Oct 2026 10:38:31 +0200 Subject: [PATCH 1/5] Run tests in CI --- .github/workflows/BuildPR.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/BuildPR.yml b/.github/workflows/BuildPR.yml index 95ed550f..d6689a2f 100644 --- a/.github/workflows/BuildPR.yml +++ b/.github/workflows/BuildPR.yml @@ -57,7 +57,7 @@ jobs: - name: Unlink openssl 3 run: | brew unlink openssl@3 -# - name: Test project -# run: make test ARCH=${{ matrix.abi }} + - name: Test project + run: make test ARCH=${{ matrix.abi }} - name: Archive project run: make archive ARCH=${{ matrix.abi }} From 4fca2a529838459dc48d2f48cbf44284e1255ea0 Mon Sep 17 00:00:00 2001 From: Hannes Achleitner Date: Mon, 28 Sep 2026 07:30:14 +0200 Subject: [PATCH 2/5] Stop signing Debug builds with SHA-1 The vendored Carthage/Checkouts/xcconfigs Base/Configurations/Debug.xcconfig hardcodes OTHER_CODE_SIGN_FLAGS = --digest-algorithm=sha1 --timestamp=none for every Debug build. Current codesign refuses SHA-1 outright: error: signing with only SHA1 not allowed. Please remove `sha1` from the `--digest-algorithm` code signing flag. which was breaking ObjectiveGit-MacTests' CodeSign build phase (and would break the ObjectiveGit-Mac framework and ObjectiveGit-iOS target the same way, since they share the same project-level Debug config). Since Base/Configurations/Debug.xcconfig lives in a separate vendored git submodule (jspahrsummers/xcconfigs) fetched fresh by script/bootstrap on every CI run, patching it directly wouldn't survive a bootstrap. Instead, override OTHER_CODE_SIGN_FLAGS directly in the project's own Debug build configuration, which takes precedence over the same key supplied by baseConfigurationReference. Keeps --timestamp=none (skips the network-dependent Developer ID timestamp server, still fine for local/CI ad-hoc signing) and just drops the now-rejected --digest-algorithm=sha1. --- ObjectiveGitFramework.xcodeproj/project.pbxproj | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ObjectiveGitFramework.xcodeproj/project.pbxproj b/ObjectiveGitFramework.xcodeproj/project.pbxproj index 22f60cad..61072f74 100644 --- a/ObjectiveGitFramework.xcodeproj/project.pbxproj +++ b/ObjectiveGitFramework.xcodeproj/project.pbxproj @@ -1763,6 +1763,12 @@ "$(inherited)", "-DGIT_SSH", ); + // Override the vendored Carthage/Checkouts/xcconfigs Debug.xcconfig, + // which hardcodes "--digest-algorithm=sha1". Current codesign + // rejects SHA-1 outright ("signing with only SHA1 not allowed"), + // so drop it here and keep only the network-independent timestamp + // opt-out. + OTHER_CODE_SIGN_FLAGS = "--timestamp=none"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; WARNING_CFLAGS = ( From 06513cc2938a8a017e686922126257bcb7d4303a Mon Sep 17 00:00:00 2001 From: Hannes Achleitner Date: Wed, 30 Sep 2026 07:15:40 +0200 Subject: [PATCH 3/5] Upload xcresult when unit tests fail --- .github/workflows/BuildPR.yml | 13 ++++++++++++- Makefile | 7 ++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/.github/workflows/BuildPR.yml b/.github/workflows/BuildPR.yml index d6689a2f..a7902841 100644 --- a/.github/workflows/BuildPR.yml +++ b/.github/workflows/BuildPR.yml @@ -58,6 +58,17 @@ jobs: run: | brew unlink openssl@3 - name: Test project - run: make test ARCH=${{ matrix.abi }} + id: run-unit-tests + run: | + make test \ + ARCH=${{ matrix.abi }} \ + RESULT_BUNDLE=UnitTestResults-${{ matrix.abi }}.xcresult + - name: Upload unit test results + if: ${{ failure() && steps.run-unit-tests.outcome == 'failure' }} + uses: actions/upload-artifact@v7 + with: + name: UnitTestResults-${{ matrix.abi }}.xcresult + path: UnitTestResults-${{ matrix.abi }}.xcresult + retention-days: ${{ github.event_name == 'pull_request' && 7 || 90 }} - name: Archive project run: make archive ARCH=${{ matrix.abi }} diff --git a/Makefile b/Makefile index 15710da9..aa6886b7 100644 --- a/Makefile +++ b/Makefile @@ -20,6 +20,11 @@ DESTINATION := platform=macOS,arch=$(ARCH) LIBGIT2_ARCHIVE := External/libgit2.a LIBGIT2_BUILD_DIR := External/libgit2/build +# Set to a path to have xcodebuild write an .xcresult bundle, which is where CI +# reads failed unit test results back out of a test run. +RESULT_BUNDLE ?= +RESULT_BUNDLE_ARG := $(if $(RESULT_BUNDLE),-resultBundlePath $(RESULT_BUNDLE)) + XCODEBUILD := xcodebuild -workspace $(WORKSPACE) -scheme "$(SCHEME)" ARCHS="$(ARCH)" MAKEFILE := $(firstword $(MAKEFILE_LIST)) @@ -101,7 +106,7 @@ build: git-submodule-check ## Build the macOS framework $(XCODEBUILD) -destination "$(DESTINATION)" build test: git-submodule-check ## Run the macOS framework specs - $(XCODEBUILD) -destination "$(DESTINATION)" test + $(XCODEBUILD) -destination "$(DESTINATION)" $(RESULT_BUNDLE_ARG) test archive: git-submodule-check ## Build a release archive of the macOS framework $(XCODEBUILD) archive From 63e6f941675820d1a11b0c3ab5adb5bbb3fa803d Mon Sep 17 00:00:00 2001 From: Hannes Achleitner Date: Thu, 1 Oct 2026 11:11:51 +0200 Subject: [PATCH 4/5] Fix flaky GTSubmoduleSpec expectation for git_submodule_sync The fixture repository has no 'origin' remote configured, so when git_submodule_sync resolves the submodule's relative URL ('../Test_App'), libgit2 falls back to resolving it against the parent repository's working directory (get_url_base in submodule.c) rather than a remote URL. That correctly produces an absolute path to the sibling Test_App fixture, not the untouched relative string the test previously expected. This is a legitimate libgit2 behavior (matches 'git submodule sync' resolving relative URLs to absolute ones before writing to .git/config), not a regression, so update the expectation to compute the resolved absolute path dynamically instead of hardcoding the relative URL. --- ObjectiveGitTests/GTSubmoduleSpec.m | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/ObjectiveGitTests/GTSubmoduleSpec.m b/ObjectiveGitTests/GTSubmoduleSpec.m index 5575c120..809c0f6e 100644 --- a/ObjectiveGitTests/GTSubmoduleSpec.m +++ b/ObjectiveGitTests/GTSubmoduleSpec.m @@ -246,7 +246,15 @@ __block NSError *error = nil; expect(@([submodule sync:&error])).to(beTruthy()); - expect([config stringForKey:configKey]).to(equal(@"../Test_App")); + + // The fixture repository has no "origin" remote configured, so + // libgit2 resolves the submodule's relative URL ("../Test_App") + // against the parent repository's working directory instead of a + // remote URL, producing an absolute path to the sibling Test_App + // fixture rather than leaving the URL as the relative string. + NSString *expectedURL = [repo.fileURL URLByDeletingLastPathComponent].path; + expectedURL = [expectedURL stringByAppendingPathComponent:@"Test_App"]; + expect([config stringForKey:configKey]).to(equal(expectedURL)); }); }); From 0c419abfed2b0a177331139e9c6c2966d82efa49 Mon Sep 17 00:00:00 2001 From: Hannes Achleitner Date: Thu, 1 Oct 2026 11:19:28 +0200 Subject: [PATCH 5/5] Build libgit2 with SSH support via libssh2 GTLibgit2FeaturesSpec expected GIT_FEATURE_SSH to be set, but libgit2's USE_SSH cmake option defaults to off/empty, and script/update_libgit2 never set it. bootstrap already fetches libssh2 and makes its headers/library discoverable (including a pkgconfig entry within PKG_CONFIG_PATH), so just pass -DUSE_SSH=libssh2 to opt in. Verified locally: rebuilt libgit2.a and all 4 Libgit2FeaturesSpec tests (including SSH) now pass. --- script/update_libgit2 | 1 + 1 file changed, 1 insertion(+) diff --git a/script/update_libgit2 b/script/update_libgit2 index 0495f0e2..faf306e3 100755 --- a/script/update_libgit2 +++ b/script/update_libgit2 @@ -68,6 +68,7 @@ cmake --version cmake -DBUILD_SHARED_LIBS:BOOL=OFF \ -DBUILD_TESTS:BOOL=OFF \ -DTHREADSAFE:BOOL=ON \ + -DUSE_SSH=libssh2 \ -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \ .. cmake --build .