Skip to content

Commit

Permalink
build-git-installers: migrate macOS and Linux off ESRP (#614)
Browse files Browse the repository at this point in the history
This PR migrates `microsoft/git`'s signing workflows off the ESRP
service. This means:

1. Updating the Linux components to sign with a GPG key.
2. Updating macOS components to sign/notarize using Application and
Installer certificates (see [this
series](https://developer.apple.com/forums/thread/701514) for more
details).

An example run of release workflow with these changes can be found at
[1].

1: https://github.com/microsoft/git/actions/runs/6635788798
  • Loading branch information
ldennington authored Oct 30, 2023
2 parents f8d3c9d + 7a89262 commit b7dec5a
Show file tree
Hide file tree
Showing 8 changed files with 350 additions and 504 deletions.
35 changes: 32 additions & 3 deletions .github/macos-installer/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,16 @@ GIT_PREFIX := $(PREFIX)/git
BUILD_CODE := $(ARCH_CODE)
BUILD_DIR := $(GITHUB_WORKSPACE)/payload
DESTDIR := $(PWD)/stage/git-$(BUILD_CODE)-$(VERSION)
ARTIFACTDIR := build_artifacts
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) GIT_BUILT_FROM_COMMIT="$(GIT_BUILT_FROM_COMMIT)" DESTDIR=$(DESTDIR)
CORES := $(shell bash -c "sysctl hw.ncpu | awk '{print \$$2}'")

.PHONY: image pkg payload
# Guard against environment variables
APPLE_APP_IDENTITY =
APPLE_INSTALLER_IDENTITY =
APPLE_KEYCHAIN_PROFILE =

.PHONY: image pkg payload codesign notarize

.SECONDARY:

Expand Down Expand Up @@ -112,8 +117,17 @@ disk-image/VERSION-$(VERSION)-$(ARCH_CODE):
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)-$(BUILD_CODE).pkg
disk-image/git-$(VERSION)-$(BUILD_CODE).pkg: disk-image/VERSION-$(VERSION)-$(ARCH_CODE) symlinks
pkgbuild --identifier com.git.pkg --version $(VERSION) --root $(ARTIFACTDIR)$(PREFIX) --scripts assets/scripts --install-location $(PREFIX) --component-plist ./assets/git-components.plist disk-image/git-$(VERSION)-$(BUILD_CODE).pkg
$(pkg_cmd)

git-%-$(BUILD_CODE).dmg:
hdiutil create git-$(VERSION)-$(BUILD_CODE).uncompressed.dmg -fs HFS+ -srcfolder disk-image -volname "Git $(VERSION) $(CPU_VENDOR) $(ARCH)" -ov
Expand All @@ -125,3 +139,18 @@ payload: $(BUILD_DIR)/git-$(VERSION)/osx-installed $(BUILD_DIR)/git-$(VERSION)/o
pkg: disk-image/git-$(VERSION)-$(BUILD_CODE).pkg

image: git-$(VERSION)-$(BUILD_CODE).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)-$(BUILD_CODE).pkg" \
--keychain-profile="$(APPLE_KEYCHAIN_PROFILE)"
endif
12 changes: 12 additions & 0 deletions .github/macos-installer/entitlements.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
</dict>
</plist>
65 changes: 65 additions & 0 deletions .github/scripts/codesign.sh
Original file line number Diff line number Diff line change
@@ -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"
35 changes: 35 additions & 0 deletions .github/scripts/notarize.sh
Original file line number Diff line number Diff line change
@@ -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"
135 changes: 0 additions & 135 deletions .github/scripts/run-esrp-signing.py

This file was deleted.

12 changes: 0 additions & 12 deletions .github/scripts/set-up-esrp.ps1

This file was deleted.

Loading

0 comments on commit b7dec5a

Please sign in to comment.