diff --git a/.github/macos-installer/Makefile b/.github/macos-installer/Makefile new file mode 100644 index 00000000000000..3e1d60dcbeb2ef --- /dev/null +++ b/.github/macos-installer/Makefile @@ -0,0 +1,157 @@ +SHELL := /bin/bash +SUDO := sudo +C_INCLUDE_PATH := /usr/include +CPLUS_INCLUDE_PATH := /usr/include +LD_LIBRARY_PATH := /usr/lib + +OSX_VERSION := $(shell sw_vers -productVersion) +TARGET_FLAGS := -mmacosx-version-min=$(OSX_VERSION) -DMACOSX_DEPLOYMENT_TARGET=$(OSX_VERSION) + +uname_M := $(shell sh -c 'uname -m 2>/dev/null || echo not') + +ARCH_UNIV := universal +ARCH_FLAGS := -arch x86_64 -arch arm64 + +CFLAGS := $(TARGET_FLAGS) $(ARCH_FLAGS) +LDFLAGS := $(TARGET_FLAGS) $(ARCH_FLAGS) + +PREFIX := /usr/local +GIT_PREFIX := $(PREFIX)/git + +BUILD_DIR := $(GITHUB_WORKSPACE)/payload +DESTDIR := $(PWD)/stage/git-$(ARCH_UNIV)-$(VERSION) +ARTIFACTDIR := build-artifacts +SUBMAKE := $(MAKE) C_INCLUDE_PATH="$(C_INCLUDE_PATH)" CPLUS_INCLUDE_PATH="$(CPLUS_INCLUDE_PATH)" LD_LIBRARY_PATH="$(LD_LIBRARY_PATH)" TARGET_FLAGS="$(TARGET_FLAGS)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" NO_GETTEXT=1 NO_DARWIN_PORTS=1 prefix=$(GIT_PREFIX) DESTDIR=$(DESTDIR) +CORES := $(shell bash -c "sysctl hw.ncpu | awk '{print \$$2}'") + +# Guard against environment variables +APPLE_APP_IDENTITY = +APPLE_INSTALLER_IDENTITY = +APPLE_KEYCHAIN_PROFILE = + +.PHONY: image pkg payload codesign notarize + +.SECONDARY: + +$(DESTDIR)$(GIT_PREFIX)/VERSION-$(VERSION)-$(ARCH_UNIV): + rm -f $(BUILD_DIR)/git-$(VERSION)/osx-installed* + mkdir -p $(DESTDIR)$(GIT_PREFIX) + touch $@ + +$(BUILD_DIR)/git-$(VERSION)/osx-built-keychain: + cd $(BUILD_DIR)/git-$(VERSION)/contrib/credential/osxkeychain; $(SUBMAKE) CFLAGS="$(CFLAGS) -g -O2 -Wall" + touch $@ + +$(BUILD_DIR)/git-$(VERSION)/osx-built: + [ -d $(DESTDIR)$(GIT_PREFIX) ] && $(SUDO) rm -rf $(DESTDIR) || echo ok + cd $(BUILD_DIR)/git-$(VERSION); $(SUBMAKE) -j $(CORES) all strip + echo "================" + echo "Dumping Linkage" + cd $(BUILD_DIR)/git-$(VERSION); ./git version + echo "====" + cd $(BUILD_DIR)/git-$(VERSION); /usr/bin/otool -L ./git + echo "====" + cd $(BUILD_DIR)/git-$(VERSION); /usr/bin/otool -L ./git-http-fetch + echo "====" + cd $(BUILD_DIR)/git-$(VERSION); /usr/bin/otool -L ./git-http-push + echo "====" + cd $(BUILD_DIR)/git-$(VERSION); /usr/bin/otool -L ./git-remote-http + echo "====" + cd $(BUILD_DIR)/git-$(VERSION); /usr/bin/otool -L ./git-gvfs-helper + echo "================" + touch $@ + +$(BUILD_DIR)/git-$(VERSION)/osx-installed-bin: $(BUILD_DIR)/git-$(VERSION)/osx-built $(BUILD_DIR)/git-$(VERSION)/osx-built-keychain + cd $(BUILD_DIR)/git-$(VERSION); $(SUBMAKE) install + cp $(BUILD_DIR)/git-$(VERSION)/contrib/credential/osxkeychain/git-credential-osxkeychain $(DESTDIR)$(GIT_PREFIX)/bin/git-credential-osxkeychain + mkdir -p $(DESTDIR)$(GIT_PREFIX)/contrib/completion + cp $(BUILD_DIR)/git-$(VERSION)/contrib/completion/git-completion.bash $(DESTDIR)$(GIT_PREFIX)/contrib/completion/ + cp $(BUILD_DIR)/git-$(VERSION)/contrib/completion/git-completion.zsh $(DESTDIR)$(GIT_PREFIX)/contrib/completion/ + cp $(BUILD_DIR)/git-$(VERSION)/contrib/completion/git-prompt.sh $(DESTDIR)$(GIT_PREFIX)/contrib/completion/ + # This is needed for Git-Gui, GitK + mkdir -p $(DESTDIR)$(GIT_PREFIX)/lib/perl5/site_perl + [ ! -f $(DESTDIR)$(GIT_PREFIX)/lib/perl5/site_perl/Error.pm ] && cp $(BUILD_DIR)/git-$(VERSION)/perl/private-Error.pm $(DESTDIR)$(GIT_PREFIX)/lib/perl5/site_perl/Error.pm || echo done + touch $@ + +$(BUILD_DIR)/git-$(VERSION)/osx-installed-man: $(BUILD_DIR)/git-$(VERSION)/osx-installed-bin + mkdir -p $(DESTDIR)$(GIT_PREFIX)/share/man + cp -R $(GITHUB_WORKSPACE)/manpages/ $(DESTDIR)$(GIT_PREFIX)/share/man + touch $@ + +$(BUILD_DIR)/git-$(VERSION)/osx-built-subtree: + cd $(BUILD_DIR)/git-$(VERSION)/contrib/subtree; $(SUBMAKE) XML_CATALOG_FILES="$(XML_CATALOG_FILES)" all git-subtree.1 + touch $@ + +$(BUILD_DIR)/git-$(VERSION)/osx-installed-subtree: $(BUILD_DIR)/git-$(VERSION)/osx-built-subtree + mkdir -p $(DESTDIR) + cd $(BUILD_DIR)/git-$(VERSION)/contrib/subtree; $(SUBMAKE) XML_CATALOG_FILES="$(XML_CATALOG_FILES)" install install-man + touch $@ + +$(BUILD_DIR)/git-$(VERSION)/osx-installed-assets: $(BUILD_DIR)/git-$(VERSION)/osx-installed-bin + mkdir -p $(DESTDIR)$(GIT_PREFIX)/etc + cat assets/etc/gitconfig.osxkeychain >> $(DESTDIR)$(GIT_PREFIX)/etc/gitconfig + cp assets/uninstall.sh $(DESTDIR)$(GIT_PREFIX)/uninstall.sh + sh -c "echo .DS_Store >> $(DESTDIR)$(GIT_PREFIX)/share/git-core/templates/info/exclude" + +symlinks: + mkdir -p $(ARTIFACTDIR)$(PREFIX)/bin + cd $(ARTIFACTDIR)$(PREFIX)/bin; find ../git/bin -type f -exec ln -sf {} \; + for man in man1 man3 man5 man7; do mkdir -p $(ARTIFACTDIR)$(PREFIX)/share/man/$$man; (cd $(ARTIFACTDIR)$(PREFIX)/share/man/$$man; ln -sf ../../../git/share/man/$$man/* ./); done + ruby ../scripts/symlink-git-hardlinks.rb $(ARTIFACTDIR) + touch $@ + +$(BUILD_DIR)/git-$(VERSION)/osx-installed: $(DESTDIR)$(GIT_PREFIX)/VERSION-$(VERSION)-$(ARCH_UNIV) $(BUILD_DIR)/git-$(VERSION)/osx-installed-man $(BUILD_DIR)/git-$(VERSION)/osx-installed-assets $(BUILD_DIR)/git-$(VERSION)/osx-installed-subtree + find $(DESTDIR)$(GIT_PREFIX) -type d -exec chmod ugo+rx {} \; + find $(DESTDIR)$(GIT_PREFIX) -type f -exec chmod ugo+r {} \; + touch $@ + +$(BUILD_DIR)/git-$(VERSION)/osx-built-assert-$(ARCH_UNIV): $(BUILD_DIR)/git-$(VERSION)/osx-built + File $(BUILD_DIR)/git-$(VERSION)/git + File $(BUILD_DIR)/git-$(VERSION)/contrib/credential/osxkeychain/git-credential-osxkeychain + touch $@ + +disk-image/VERSION-$(VERSION)-$(ARCH_UNIV): + rm -f disk-image/*.pkg disk-image/VERSION-* disk-image/.DS_Store + mkdir disk-image + touch "$@" + +pkg_cmd := pkgbuild --identifier com.git.pkg --version $(VERSION) \ + --root $(ARTIFACTDIR)$(PREFIX) --scripts assets/scripts \ + --install-location $(PREFIX) --component-plist ./assets/git-components.plist + +ifdef APPLE_INSTALLER_IDENTITY + pkg_cmd += --sign "$(APPLE_INSTALLER_IDENTITY)" +endif + +pkg_cmd += disk-image/git-$(VERSION)-$(ARCH_UNIV).pkg +disk-image/git-$(VERSION)-$(ARCH_UNIV).pkg: disk-image/VERSION-$(VERSION)-$(ARCH_UNIV) symlinks + $(pkg_cmd) + +git-%-$(ARCH_UNIV).dmg: + hdiutil create git-$(VERSION)-$(ARCH_UNIV).uncompressed.dmg -fs HFS+ -srcfolder disk-image -volname "Git $(VERSION) $(ARCH_UNIV)" -ov 2>&1 | tee err || { \ + grep "Resource busy" err && \ + sleep 5 && \ + hdiutil create git-$(VERSION)-$(ARCH_UNIV).uncompressed.dmg -fs HFS+ -srcfolder disk-image -volname "Git $(VERSION) $(ARCH_UNIV)" -ov; } + hdiutil convert -format UDZO -o $@ git-$(VERSION)-$(ARCH_UNIV).uncompressed.dmg + rm -f git-$(VERSION)-$(ARCH_UNIV).uncompressed.dmg + +payload: $(BUILD_DIR)/git-$(VERSION)/osx-installed $(BUILD_DIR)/git-$(VERSION)/osx-built-assert-$(ARCH_UNIV) + +pkg: disk-image/git-$(VERSION)-$(ARCH_UNIV).pkg + +image: git-$(VERSION)-$(ARCH_UNIV).dmg + +ifdef APPLE_APP_IDENTITY +codesign: + @$(CURDIR)/../scripts/codesign.sh --payload="build-artifacts/usr/local/git" \ + --identity="$(APPLE_APP_IDENTITY)" \ + --entitlements="$(CURDIR)/entitlements.xml" +endif + +# Notarization can only happen if the package is fully signed +ifdef APPLE_KEYCHAIN_PROFILE +notarize: + @$(CURDIR)/../scripts/notarize.sh \ + --package="disk-image/git-$(VERSION)-$(ARCH_UNIV).pkg" \ + --keychain-profile="$(APPLE_KEYCHAIN_PROFILE)" +endif diff --git a/.github/macos-installer/assets/etc/gitconfig.osxkeychain b/.github/macos-installer/assets/etc/gitconfig.osxkeychain new file mode 100644 index 00000000000000..788266b3a40a9d --- /dev/null +++ b/.github/macos-installer/assets/etc/gitconfig.osxkeychain @@ -0,0 +1,2 @@ +[credential] + helper = osxkeychain diff --git a/.github/macos-installer/assets/git-components.plist b/.github/macos-installer/assets/git-components.plist new file mode 100644 index 00000000000000..78db36777df3ed --- /dev/null +++ b/.github/macos-installer/assets/git-components.plist @@ -0,0 +1,18 @@ + + + + + + BundleHasStrictIdentifier + + BundleIsRelocatable + + BundleIsVersionChecked + + BundleOverwriteAction + upgrade + RootRelativeBundlePath + git/share/git-gui/lib/Git Gui.app + + + diff --git a/.github/macos-installer/assets/scripts/postinstall b/.github/macos-installer/assets/scripts/postinstall new file mode 100755 index 00000000000000..94056db9b7b864 --- /dev/null +++ b/.github/macos-installer/assets/scripts/postinstall @@ -0,0 +1,62 @@ +#!/bin/bash +INSTALL_DST="$2" +SCALAR_C_CMD="$INSTALL_DST/git/bin/scalar" +SCALAR_DOTNET_CMD="/usr/local/scalar/scalar" +SCALAR_UNINSTALL_SCRIPT="/usr/local/scalar/uninstall_scalar.sh" + +function cleanupScalar() +{ + echo "checking whether Scalar was installed" + if [ ! -f "$SCALAR_C_CMD" ]; then + echo "Scalar not installed; exiting..." + return 0 + fi + echo "Scalar is installed!" + + echo "looking for Scalar.NET" + if [ ! -f "$SCALAR_DOTNET_CMD" ]; then + echo "Scalar.NET not found; exiting..." + return 0 + fi + echo "Scalar.NET found!" + + currentUser=$(echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ { print $3 }') + + # Re-register Scalar.NET repositories with the newly-installed Scalar + for repo in $($SCALAR_DOTNET_CMD list); do + ( + PATH="$INSTALL_DST/git/bin:$PATH" + sudo -u "$currentUser" scalar register $repo || \ + echo "warning: skipping re-registration of $repo" + ) + done + + # Uninstall Scalar.NET + echo "removing Scalar.NET" + + # Add /usr/local/bin to path - default install location of Homebrew + PATH="/usr/local/bin:$PATH" + if (sudo -u "$currentUser" brew list --cask scalar); then + # Remove from Homebrew + sudo -u "$currentUser" brew remove --cask scalar || echo "warning: Scalar.NET uninstall via Homebrew completed with code $?" + echo "Scalar.NET uninstalled via Homebrew!" + elif (sudo -u "$currentUser" brew list --cask scalar-azrepos); then + sudo -u "$currentUser" brew remove --cask scalar-azrepos || echo "warning: Scalar.NET with GVFS uninstall via Homebrew completed with code $?" + echo "Scalar.NET with GVFS uninstalled via Homebrew!" + elif [ -f $SCALAR_UNINSTALL_SCRIPT ]; then + # If not installed with Homebrew, manually remove package + sudo -S sh $SCALAR_UNINSTALL_SCRIPT || echo "warning: Scalar.NET uninstall completed with code $?" + echo "Scalar.NET uninstalled!" + else + echo "warning: Scalar.NET uninstall script not found" + fi + + # Re-create the Scalar symlink, in case it was removed by the Scalar.NET uninstall operation + mkdir -p $INSTALL_DST/bin + /bin/ln -Fs "$SCALAR_C_CMD" "$INSTALL_DST/bin/scalar" +} + +# Run Scalar cleanup (will exit if not applicable) +cleanupScalar + +exit 0 \ No newline at end of file diff --git a/.github/macos-installer/assets/uninstall.sh b/.github/macos-installer/assets/uninstall.sh new file mode 100755 index 00000000000000..4fc79fbaa2e652 --- /dev/null +++ b/.github/macos-installer/assets/uninstall.sh @@ -0,0 +1,34 @@ +#!/bin/bash -e +if [ ! -r "/usr/local/git" ]; then + echo "Git doesn't appear to be installed via this installer. Aborting" + exit 1 +fi + +if [ "$1" != "--yes" ]; then + echo "This will uninstall git by removing /usr/local/git/, and symlinks" + printf "Type 'yes' if you are sure you wish to continue: " + read response +else + response="yes" +fi + +if [ "$response" == "yes" ]; then + # remove all of the symlinks we've created + pkgutil --files com.git.pkg | grep bin | while read f; do + if [ -L /usr/local/$f ]; then + sudo rm /usr/local/$f + fi + done + + # forget receipts. + pkgutil --packages | grep com.git.pkg | xargs -I {} sudo pkgutil --forget {} + echo "Uninstalled" + + # The guts all go here. + sudo rm -rf /usr/local/git/ +else + echo "Aborted" + exit 1 +fi + +exit 0 diff --git a/.github/macos-installer/entitlements.xml b/.github/macos-installer/entitlements.xml new file mode 100644 index 00000000000000..46f675661149b6 --- /dev/null +++ b/.github/macos-installer/entitlements.xml @@ -0,0 +1,12 @@ + + + + + com.apple.security.cs.allow-jit + + com.apple.security.cs.allow-unsigned-executable-memory + + com.apple.security.cs.disable-library-validation + + + diff --git a/.github/scripts/codesign.sh b/.github/scripts/codesign.sh new file mode 100755 index 00000000000000..076b29f93be45e --- /dev/null +++ b/.github/scripts/codesign.sh @@ -0,0 +1,65 @@ +#!/bin/bash + +sign_directory () { + ( + cd "$1" + for f in * + do + macho=$(file --mime $f | grep mach) + # Runtime sign dylibs and Mach-O binaries + if [[ $f == *.dylib ]] || [ ! -z "$macho" ]; + then + echo "Runtime Signing $f" + codesign -s "$IDENTITY" $f --timestamp --force --options=runtime --entitlements $ENTITLEMENTS_FILE + elif [ -d "$f" ]; + then + echo "Signing files in subdirectory $f" + sign_directory "$f" + + else + echo "Signing $f" + codesign -s "$IDENTITY" $f --timestamp --force + fi + done + ) +} + +for i in "$@" +do +case "$i" in + --payload=*) + SIGN_DIR="${i#*=}" + shift # past argument=value + ;; + --identity=*) + IDENTITY="${i#*=}" + shift # past argument=value + ;; + --entitlements=*) + ENTITLEMENTS_FILE="${i#*=}" + shift # past argument=value + ;; + *) + die "unknown option '$i'" + ;; +esac +done + +if [ -z "$SIGN_DIR" ]; then + echo "error: missing directory argument" + exit 1 +elif [ -z "$IDENTITY" ]; then + echo "error: missing signing identity argument" + exit 1 +elif [ -z "$ENTITLEMENTS_FILE" ]; then + echo "error: missing entitlements file argument" + exit 1 +fi + +echo "======== INPUTS ========" +echo "Directory: $SIGN_DIR" +echo "Signing identity: $IDENTITY" +echo "Entitlements: $ENTITLEMENTS_FILE" +echo "======== END INPUTS ========" + +sign_directory "$SIGN_DIR" diff --git a/.github/scripts/notarize.sh b/.github/scripts/notarize.sh new file mode 100755 index 00000000000000..9315d688afbd49 --- /dev/null +++ b/.github/scripts/notarize.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +for i in "$@" +do +case "$i" in + --package=*) + PACKAGE="${i#*=}" + shift # past argument=value + ;; + --keychain-profile=*) + KEYCHAIN_PROFILE="${i#*=}" + shift # past argument=value + ;; + *) + die "unknown option '$i'" + ;; +esac +done + +if [ -z "$PACKAGE" ]; then + echo "error: missing package argument" + exit 1 +elif [ -z "$KEYCHAIN_PROFILE" ]; then + echo "error: missing keychain profile argument" + exit 1 +fi + +# Exit as soon as any line fails +set -e + +# Send the notarization request +xcrun notarytool submit -v "$PACKAGE" -p "$KEYCHAIN_PROFILE" --wait + +# Staple the notarization ticket (to allow offline installation) +xcrun stapler staple -v "$PACKAGE" diff --git a/.github/scripts/symlink-git-hardlinks.rb b/.github/scripts/symlink-git-hardlinks.rb new file mode 100644 index 00000000000000..174802ccc85d93 --- /dev/null +++ b/.github/scripts/symlink-git-hardlinks.rb @@ -0,0 +1,19 @@ +#!/usr/bin/env ruby + +install_prefix = ARGV[0] +puts install_prefix +git_binary = File.join(install_prefix, '/usr/local/git/bin/git') + +[ + ['git' , File.join(install_prefix, '/usr/local/git/bin')], + ['../../bin/git', File.join(install_prefix, '/usr/local/git/libexec/git-core')] +].each do |link, path| + Dir.glob(File.join(path, '*')).each do |file| + next if file == git_binary + puts "#{file} #{File.size(file)} == #{File.size(git_binary)}" + next unless File.size(file) == File.size(git_binary) + puts "Symlinking #{file}" + puts `ln -sf #{link} #{file}` + exit $?.exitstatus if $?.exitstatus != 0 + end +end \ No newline at end of file diff --git a/.github/workflows/build-git-installers.yml b/.github/workflows/build-git-installers.yml index 13496b451bf2f1..8dec1303019da4 100644 --- a/.github/workflows/build-git-installers.yml +++ b/.github/workflows/build-git-installers.yml @@ -291,3 +291,169 @@ jobs: name: win-${{matrix.artifact.name}}-x86_64 path: artifacts # End build Windows installers + + # Build and sign Mac OSX installers & upload artifacts + create-macos-artifacts: + strategy: + matrix: + arch: + - name: arm64 + runner: macos-latest-xl-arm64 + runs-on: ${{ matrix.arch.runner }} + needs: prereqs + env: + VERSION: "${{ needs.prereqs.outputs.tag_version }}" + environment: release + steps: + - name: Check out repository + uses: actions/checkout@v4 + with: + path: 'git' + + - name: Install Git dependencies + run: | + set -ex + + # Install x86_64 packages + arch -x86_64 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" + arch -x86_64 /usr/local/bin/brew install gettext + + # Install arm64 packages + brew install automake asciidoc xmlto docbook + brew link --force gettext + + # Make universal gettext library + lipo -create -output libintl.a /usr/local/opt/gettext/lib/libintl.a /opt/homebrew/opt/gettext/lib/libintl.a + + - name: Set up signing/notarization infrastructure + env: + A1: ${{ secrets.APPLICATION_CERTIFICATE_BASE64 }} + A2: ${{ secrets.APPLICATION_CERTIFICATE_PASSWORD }} + I1: ${{ secrets.INSTALLER_CERTIFICATE_BASE64 }} + I2: ${{ secrets.INSTALLER_CERTIFICATE_PASSWORD }} + N1: ${{ secrets.APPLE_TEAM_ID }} + N2: ${{ secrets.APPLE_DEVELOPER_ID }} + N3: ${{ secrets.APPLE_DEVELOPER_PASSWORD }} + N4: ${{ secrets.APPLE_KEYCHAIN_PROFILE }} + run: | + echo "Setting up signing certificates" + security create-keychain -p pwd $RUNNER_TEMP/buildagent.keychain + security default-keychain -s $RUNNER_TEMP/buildagent.keychain + security unlock-keychain -p pwd $RUNNER_TEMP/buildagent.keychain + # Prevent re-locking + security set-keychain-settings $RUNNER_TEMP/buildagent.keychain + + echo "$A1" | base64 -D > $RUNNER_TEMP/cert.p12 + security import $RUNNER_TEMP/cert.p12 \ + -k $RUNNER_TEMP/buildagent.keychain \ + -P "$A2" \ + -T /usr/bin/codesign + security set-key-partition-list \ + -S apple-tool:,apple:,codesign: \ + -s -k pwd \ + $RUNNER_TEMP/buildagent.keychain + + echo "$I1" | base64 -D > $RUNNER_TEMP/cert.p12 + security import $RUNNER_TEMP/cert.p12 \ + -k $RUNNER_TEMP/buildagent.keychain \ + -P "$I2" \ + -T /usr/bin/pkgbuild + security set-key-partition-list \ + -S apple-tool:,apple:,pkgbuild: \ + -s -k pwd \ + $RUNNER_TEMP/buildagent.keychain + + echo "Setting up notarytool" + xcrun notarytool store-credentials \ + --team-id "$N1" \ + --apple-id "$N2" \ + --password "$N3" \ + "$N4" + + - name: Build, sign, and notarize artifacts + env: + A3: ${{ secrets.APPLE_APPLICATION_SIGNING_IDENTITY }} + I3: ${{ secrets.APPLE_INSTALLER_SIGNING_IDENTITY }} + N4: ${{ secrets.APPLE_KEYCHAIN_PROFILE }} + run: | + die () { + echo "$*" >&2 + exit 1 + } + + # Trace execution, stop on error + set -ex + + # Write to "version" file to force match with trigger payload version + echo "${{ needs.prereqs.outputs.tag_version }}" >>git/version + + # Configure universal build + cat >git/config.mak <>git/config.mak <>git/config.mak <>git/config.mak + + # To make use of the catalogs... + export XML_CATALOG_FILES=$homebrew_prefix/etc/xml/catalog + + make -C git -j$(sysctl -n hw.physicalcpu) GIT-VERSION-FILE dist dist-doc + + # Extract tarballs + mkdir payload manpages + tar -xvf git/git-$VERSION.tar.gz -C payload + tar -xvf git/git-manpages-$VERSION.tar.gz -C manpages + + # Lay out payload + cp git/config.mak payload/git-$VERSION/config.mak + make -C git/.github/macos-installer V=1 payload + + # Codesign payload + cp -R stage/git-universal-$VERSION/ \ + git/.github/macos-installer/build-artifacts + make -C git/.github/macos-installer V=1 codesign \ + APPLE_APP_IDENTITY="$A3" || die "Creating signed payload failed" + + # Build and sign pkg + make -C git/.github/macos-installer V=1 pkg \ + APPLE_INSTALLER_IDENTITY="$I3" \ + || die "Creating signed pkg failed" + + # Notarize pkg + make -C git/.github/macos-installer V=1 notarize \ + APPLE_INSTALLER_IDENTITY="$I3" APPLE_KEYCHAIN_PROFILE="$N4" \ + || die "Creating signed and notarized pkg failed" + + # Create DMG + make -C git/.github/macos-installer V=1 image || die "Creating DMG failed" + + # Move all artifacts into top-level directory + mv git/.github/macos-installer/disk-image/*.pkg git/.github/macos-installer/ + + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: macos-artifacts + path: | + git/.github/macos-installer/*.dmg + git/.github/macos-installer/*.pkg + # End build and sign Mac OSX installers