Skip to content

Commit

Permalink
macos wip
Browse files Browse the repository at this point in the history
  • Loading branch information
ldennington committed Oct 13, 2023
1 parent 665fcd5 commit 72c75d0
Show file tree
Hide file tree
Showing 5 changed files with 315 additions and 3 deletions.
30 changes: 27 additions & 3 deletions .github/macos-installer/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,16 @@ GIT_PREFIX := $(PREFIX)/git
BUILD_CODE := intel-$(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 @@ -102,7 +107,11 @@ disk-image/VERSION-$(VERSION)-$(ARCH_CODE):
touch "$@"

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
pkgbuild --identifier com.git.pkg --version $(VERSION) \
--root $(ARTIFACTDIR)$(PREFIX) --scripts assets/scripts \
--install-location $(PREFIX) --component-plist \
${APPLE_INSTALLER_IDENTITY:+"--sign"} ${APPLE_INSTALLER_IDENTITY:+"$APPLE_INSTALLER_IDENTITY"} \
./assets/git-components.plist disk-image/git-$(VERSION)-$(BUILD_CODE).pkg

git-%-$(BUILD_CODE).dmg:
hdiutil create git-$(VERSION)-$(BUILD_CODE).uncompressed.dmg -fs HFS+ -srcfolder disk-image -volname "Git $(VERSION) Intel $(ARCH)" -ov
Expand All @@ -114,3 +123,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"
176 changes: 176 additions & 0 deletions .github/workflows/macos-updates.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
name: macos-test

on:
push:
tags:
- 'v[0-9]*vfs*' # matches "v<number><any characters>vfs<any characters>"

jobs:
# Check prerequisites for the workflow
prereqs:
runs-on: ubuntu-latest
environment: release
env:
AZ_SUB: ${{ secrets.AZURE_SUBSCRIPTION }}
AZ_CREDS: ${{ secrets.AZURE_CREDENTIALS }}
outputs:
tag_name: ${{ steps.tag.outputs.name }} # The full name of the tag, e.g. v2.32.0.vfs.0.0
tag_version: ${{ steps.tag.outputs.version }} # The version number (without preceding "v"), e.g. 2.32.0.vfs.0.0
deb_signable: ${{ steps.deb.outputs.signable }} # Whether the credentials needed to sign the .deb package are available
steps:
- name: Validate tag
run: |
echo "$GITHUB_REF" |
grep '^refs/tags/v2\.\(0\|[1-9][0-9]*\)\.\(0\|[1-9][0-9]*\)\.vfs\.0\.\(0\|[1-9][0-9]*\)$' || {
echo "::error::${GITHUB_REF#refs/tags/} is not of the form v2.<X>.<Y>.vfs.0.<W>" >&2
exit 1
}
- name: Determine tag to build
run: |
echo "name=${GITHUB_REF#refs/tags/}" >>$GITHUB_OUTPUT
echo "version=${GITHUB_REF#refs/tags/v}" >>$GITHUB_OUTPUT
id: tag
- name: Determine whether signing certificates are present
run: echo "signable=$([[ $AZ_SUB != '' && $AZ_CREDS != '' ]] && echo 'true' || echo 'false')" >>$GITHUB_OUTPUT
id: deb
- name: Clone git
uses: actions/checkout@v3
- name: Validate the tag identified with trigger
run: |
die () {
echo "::error::$*" >&2
exit 1
}
# `actions/checkout` only downloads the peeled tag (i.e. the commit)
git fetch origin +$GITHUB_REF:$GITHUB_REF
# Verify that the tag is annotated
test $(git cat-file -t "$GITHUB_REF") == "tag" || die "Tag ${{ steps.tag.outputs.name }} is not annotated"
# Verify tag follows rules in GIT-VERSION-GEN (i.e., matches the specified "DEF_VER" in
# GIT-VERSION-FILE) and matches tag determined from trigger
make GIT-VERSION-FILE
test "${{ steps.tag.outputs.version }}" == "$(sed -n 's/^GIT_VERSION = //p'< GIT-VERSION-FILE)" || die "GIT-VERSION-FILE tag does not match ${{ steps.tag.outputs.name }}"
# End check prerequisites for the workflow

# Build and sign Mac OSX installers & upload artifacts
osx_build:
runs-on: macos-latest
needs: prereqs
env:
# `gettext` is keg-only
LDFLAGS: -L/usr/local/opt/gettext/lib
CFLAGS: -I/usr/local/opt/gettext/include
# To make use of the catalogs...
XML_CATALOG_FILES: /usr/local/etc/xml/catalog
VERSION: "${{ needs.prereqs.outputs.tag_version }}"
environment: release
steps:
- name: Check out repository
uses: actions/checkout@v3
with:
path: 'git'

- name: Install Git dependencies
run: |
set -x
brew install automake asciidoc xmlto docbook
brew link --force gettext
- 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
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/productbuild
security set-key-partition-list \
-S apple-tool:,apple:,productbuild: \
-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: |
# Configure the environment
set -x
PATH=/usr/local/bin:$PATH
export CURL_LDFLAGS=$(curl-config --libs)
# Write to "version" file to force match with trigger payload version
echo "${{ needs.prereqs.outputs.tag_version }}" >>git/version
make -C git -j$(sysctl -n hw.physicalcpu) GIT-VERSION-FILE dist dist-doc
export GIT_BUILT_FROM_COMMIT=$(gunzip -c git/git-$VERSION.tar.gz | git get-tar-commit-id) ||
die "Could not determine commit for build"
# 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
make -C git/.github/macos-installer V=1 payload
# Codesign payload
cp -R stage/git-intel-x86_64-$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"
# Move disk-image into the same directory as Makefile
mv disk-image git/.github/macos-installer/
# Create DMG
make -C git/.github/macos-installer V=1 image || die "Creating DMG failed"
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
name: osx-dmg
path: git/.github/macos-installer/*.dmg
# End build and sign Mac OSX installers

0 comments on commit 72c75d0

Please sign in to comment.