Skip to content

Commit 251cdfb

Browse files
authored
fix the notary issues (#39)
fix the notary issues * more fixes * do the bin version not current since current is a symlink * add a bunch more things now * preserve_xattr in munki-pkg signed package * try and debug things with spctl * change the order of the code signing * paths are still technically wrong but this works already
1 parent 1f9aab0 commit 251cdfb

4 files changed

Lines changed: 64 additions & 50 deletions

File tree

.github/workflows/build_python_3.9.10.yml

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ name: Build and upload recommended package
22

33
env:
44
TYPE: "recommended"
5-
DEV_ID: "Developer ID Installer: Clever DevOps Co. (9GQZ7KUFR6)"
5+
DEV_INSTALLER_ID: "Developer ID Installer: Clever DevOps Co. (9GQZ7KUFR6)"
6+
DEV_APPLICATION_ID: "Developer ID Application: Clever DevOps Co. (9GQZ7KUFR6)"
7+
NOTARY_PASS: ${{ secrets.NOTARY_PASS }}
68
PYTHON_VERSION: "3.9.10"
79

810
on:
@@ -25,17 +27,23 @@ jobs:
2527
- name: Checkout python repo
2628
uses: actions/checkout@v2
2729

28-
- name: Install Apple certificates
29-
if: github.ref == 'refs/heads/main'
30+
- name: Install Apple Developer ID Application certificates
3031
uses: apple-actions/import-codesign-certs@253ddeeac23f2bdad1646faac5c8c2832e800071
3132
with:
33+
keychain-password: ${{ secrets.KEYCHAIN_PASSWORD }}
34+
p12-file-base64: ${{ secrets.DEV_APP_CERTIFICATES_P12 }}
35+
p12-password: ${{ secrets.DEV_APP_CERTIFICATES_P12_PASSWORD }}
36+
37+
- name: Install Apple Developer ID Installer certificates
38+
uses: apple-actions/import-codesign-certs@253ddeeac23f2bdad1646faac5c8c2832e800071
39+
with:
40+
create-keychain: false # do not create a new keychain for this value
41+
keychain-password: ${{ secrets.KEYCHAIN_PASSWORD }}
3242
p12-file-base64: ${{ secrets.CERTIFICATES_P12 }}
3343
p12-password: ${{ secrets.CERTIFICATES_P12_PASSWORD }}
3444

3545
- name: Run build package script
36-
env:
37-
NOTARY_PASS: ${{ secrets.NOTARY_PASS }}
38-
run: ./build_python_framework_pkgs.zsh "$TYPE" "$DEV_ID" "$PYTHON_VERSION" "${BUILD_DATE}"
46+
run: ./build_python_framework_pkgs.zsh "$TYPE" "$DEV_INSTALLER_ID" "$DEV_APPLICATION_ID" "$PYTHON_VERSION" "${BUILD_DATE}" "${NOTARY_PASS}"
3947

4048
- name: Create Release
4149
if: github.ref == 'refs/heads/main'

build_python_framework_pkgs.zsh

Lines changed: 48 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
# Run this with your current directory being the path where this script is located
77

88
# Harcoded versions
9-
RP_SHA="93f3fea5290b761b1c25c15f46f7c76641d94d58"
10-
MP_SHA="71c57fcfdf43692adcd41fa7305be08f66bae3e5"
9+
RP_SHA="06b3052afe49c400aa4196f2aada15c0992e3725"
10+
MP_SHA="0fcd47faf0fb2b4e8a0256a77be315a3cb6ab319"
1111
MACOS_VERSION=11 # use 10.9 for non-universal
1212
PYTHON_PRERELEASE_VERSION=
1313
PYTHON_BASEURL="https://www.python.org/ftp/python/%s/python-%s${PYTHON_PRERELEASE_VERSION}-macos%s.pkg"
@@ -18,7 +18,6 @@ RP_BINDIR="/tmp/relocatable-python"
1818
MP_BINDIR="/tmp/munki-pkg"
1919
CONSOLEUSER=$(/usr/bin/stat -f "%Su" /dev/console)
2020
PIPCACHEDIR="/Users/${CONSOLEUSER}/Library/Caches/pip"
21-
# NOTARY_PASS="" # Store as a repo secret
2221
XCODE_PATH="/Applications/Xcode_13.2.1.app"
2322
XCODE_NOTARY_PATH="$XCODE_PATH/Contents/Developer/usr/bin/notarytool"
2423
XCODE_STAPLER_PATH="$XCODE_PATH/Contents/Developer/usr/bin/stapler"
@@ -49,22 +48,19 @@ else
4948
echo ""
5049
echo " recommended"
5150
echo " A python framework with libraries for commonly used tools like autopkg and munki"
52-
echo ""
53-
echo " opionated"
54-
echo " A python framework with libraries for as many macadmin tools as possible"
5551
exit 1
5652
fi
5753

58-
if [ -n "$3" ]; then
59-
PYTHON_VERSION=$3
54+
if [ -n "$4" ]; then
55+
PYTHON_VERSION=$4
6056
else
61-
PYTHON_VERSION=3.9.5
57+
PYTHON_VERSION=3.9.10
6258
fi
6359
# Set python bin version based on PYTHON_VERSION
6460
PYTHON_BIN_VERSION="${PYTHON_VERSION%.*}"
6561

66-
if [ -n "$4" ]; then
67-
DATE=$4
62+
if [ -n "$5" ]; then
63+
DATE=$5
6864
else
6965
DATE=$(/bin/date -u "+%m%d%Y%H%M%S")
7066
fi
@@ -77,9 +73,6 @@ RP_ZIP="/tmp/relocatable-python.zip"
7773
MP_ZIP="/tmp/munki-pkg.zip"
7874
echo "Creating Python Framework - $TYPE"
7975

80-
# Setup notary item
81-
$XCODE_NOTARY_PATH store-credentials --apple-id "macadmins@cleverdevops.com" --team-id "9GQZ7KUFR6" --password "$NOTARY_PASS" macadminpython
82-
8376
# Create framework path if not present with 777 so sudo is not needed
8477
if [ ! -d "${FRAMEWORKDIR}" ]; then
8578
/usr/bin/sudo /bin/mkdir -m 777 -p "${FRAMEWORKDIR}"
@@ -118,11 +111,11 @@ fi
118111
# remove existing Python package folders and recreate
119112
if [ -d "$TOOLSDIR/$TYPE" ]; then
120113
/bin/rm -rf "$TOOLSDIR/$TYPE"
121-
/bin/mkdir -p "$TOOLSDIR/$TYPE/payload/${FRAMEWORKDIR}"
114+
/bin/mkdir -p "$TOOLSDIR/$TYPE/payload${FRAMEWORKDIR}"
122115
/bin/mkdir -p "$TOOLSDIR/$TYPE/payload/usr/local/bin"
123116
/usr/bin/sudo /usr/sbin/chown -R ${CONSOLEUSER}:wheel "$TOOLSDIR/$TYPE"
124117
else
125-
/bin/mkdir -p "$TOOLSDIR/$TYPE/payload/${FRAMEWORKDIR}"
118+
/bin/mkdir -p "$TOOLSDIR/$TYPE/payload${FRAMEWORKDIR}"
126119
/bin/mkdir -p "$TOOLSDIR/$TYPE/payload/usr/local/bin"
127120
/usr/bin/sudo /usr/sbin/chown -R ${CONSOLEUSER}:wheel "$TOOLSDIR/$TYPE"
128121
fi
@@ -134,6 +127,7 @@ RP_EXTRACT_BINDIR="${RP_BINDIR}/relocatable-python-${RP_SHA}"
134127
--python-version "${PYTHON_VERSION}" \
135128
--os-version "${MACOS_VERSION}" \
136129
--upgrade-pip \
130+
--no-unsign \
137131
--pip-requirements "${TOOLSDIR}/requirements_${TYPE}.txt" \
138132
--destination "${FRAMEWORKDIR}"
139133

@@ -145,19 +139,30 @@ fi
145139

146140
# move the framework to the Python package folder
147141
echo "Moving Python.framework to payload folder"
148-
/bin/mv "${FRAMEWORKDIR}/Python.framework" "$TOOLSDIR/$TYPE/payload/${FRAMEWORKDIR}/Python3.framework"
142+
/bin/mv "${FRAMEWORKDIR}/Python.framework" "$TOOLSDIR/$TYPE/payload${FRAMEWORKDIR}/Python3.framework"
149143

150-
# ad-hoc re-sign the framework so it will run on Apple Silicon
151-
echo "Adding ad-hoc code signing so the framework will run on Apple Silicon..."
152-
/usr/bin/codesign -s - --deep --force --preserve-metadata=identifier,entitlements,flags,runtime "$TOOLSDIR/$TYPE/payload/${FRAMEWORKDIR}/Python3.framework/Versions/${PYTHON_BIN_VERSION}/Resources/Python.app"
153-
/usr/bin/codesign -s - --force --preserve-metadata=identifier,entitlements,flags,runtime "$TOOLSDIR/$TYPE/payload/${FRAMEWORKDIR}/Python3.framework/Versions/Current/Python"
154-
/usr/bin/find "$TOOLSDIR/$TYPE/payload/${FRAMEWORKDIR}/Python3.framework/Versions/Current/bin/" -type f -perm -u=x -exec /usr/bin/codesign -s - --preserve-metadata=identifier,entitlements,flags,runtime -f {} \;
155-
/usr/bin/find "$TOOLSDIR/$TYPE/payload/${FRAMEWORKDIR}/Python3.framework/Versions/Current/lib/" -type f -perm -u=x -exec /usr/bin/codesign -s - --preserve-metadata=identifier,entitlements,flags,runtime -f {} \;
156-
/usr/bin/find "$TOOLSDIR/$TYPE/payload/${FRAMEWORKDIR}/Python3.framework/Versions/Current/lib/" -type f -name "*dylib" -exec /usr/bin/codesign -s - --preserve-metadata=identifier,entitlements,flags,runtime -f {} \;
144+
# re-sign the framework so it will run on Apple Silicon
145+
if [ -n "$3" ]; then
146+
echo "Adding developer id code signing so the framework will run on Apple Silicon..."
147+
/usr/bin/find "$TOOLSDIR/$TYPE/payload${FRAMEWORKDIR}/Python3.framework/Versions/${PYTHON_BIN_VERSION}/bin" -type f -perm -u=x -exec /usr/bin/codesign --sign "$3" --timestamp --preserve-metadata=identifier,entitlements,flags,runtime -f {} \;
148+
/usr/bin/find "$TOOLSDIR/$TYPE/payload${FRAMEWORKDIR}/Python3.framework/Versions/${PYTHON_BIN_VERSION}/lib" -type f -perm -u=x -exec /usr/bin/codesign --sign "$3" --timestamp --preserve-metadata=identifier,entitlements,flags,runtime -f {} \;
149+
/usr/bin/find "$TOOLSDIR/$TYPE/payload${FRAMEWORKDIR}/Python3.framework/Versions/${PYTHON_BIN_VERSION}/lib" -type f -name "*dylib" -exec /usr/bin/codesign --sign "$3" --timestamp --preserve-metadata=identifier,entitlements,flags,runtime -f {} \;
150+
/usr/bin/codesign --sign "$3" --timestamp --deep --force --preserve-metadata=identifier,entitlements,flags,runtime "$TOOLSDIR/$TYPE/payload${FRAMEWORKDIR}/Python3.framework/Versions/${PYTHON_BIN_VERSION}/Resources/Python.app"
151+
/usr/bin/codesign --sign "$3" --timestamp --force --preserve-metadata=identifier,entitlements,flags,runtime "$TOOLSDIR/$TYPE/payload${FRAMEWORKDIR}/Python3.framework/Versions/${PYTHON_BIN_VERSION}/Python"
152+
/usr/bin/codesign --sign "$3" --timestamp --force --preserve-metadata=identifier,entitlements,flags,runtime "$TOOLSDIR/$TYPE/payload${FRAMEWORKDIR}/Python3.framework/Versions/Current/Python"
153+
else
154+
echo "Adding ad-hoc code signing so the framework will run on Apple Silicon..."
155+
/usr/bin/find "$TOOLSDIR/$TYPE/payload${FRAMEWORKDIR}/Python3.framework/Versions/${PYTHON_BIN_VERSION}/bin" -type f -perm -u=x -exec /usr/bin/codesign -s - --preserve-metadata=identifier,entitlements,flags,runtime -f {} \;
156+
/usr/bin/find "$TOOLSDIR/$TYPE/payload${FRAMEWORKDIR}/Python3.framework/Versions/${PYTHON_BIN_VERSION}/lib" -type f -perm -u=x -exec /usr/bin/codesign -s - --preserve-metadata=identifier,entitlements,flags,runtime -f {} \;
157+
/usr/bin/find "$TOOLSDIR/$TYPE/payload${FRAMEWORKDIR}/Python3.framework/Versions/${PYTHON_BIN_VERSION}/lib" -type f -name "*dylib" -exec /usr/bin/codesign -s - --preserve-metadata=identifier,entitlements,flags,runtime -f {} \;
158+
/usr/bin/codesign -s - --deep --force --preserve-metadata=identifier,entitlements,flags,runtime "$TOOLSDIR/$TYPE/payload${FRAMEWORKDIR}/Python3.framework/Versions/${PYTHON_BIN_VERSION}/Resources/Python.app"
159+
/usr/bin/codesign -s - --force --preserve-metadata=identifier,entitlements,flags,runtime "$TOOLSDIR/$TYPE/payload${FRAMEWORKDIR}/Python3.framework/Versions/${PYTHON_BIN_VERSION}/Python"
160+
/usr/bin/codesign -s - --force --preserve-metadata=identifier,entitlements,flags,runtime "$TOOLSDIR/$TYPE/payload${FRAMEWORKDIR}Python3.framework/Versions/Current/Python"
161+
fi
157162

158163
# confirm truly universal
159-
TOTAL_DYLIB=$(/usr/bin/find "$TOOLSDIR/$TYPE/payload/${FRAMEWORKDIR}/Python3.framework/Versions/Current/lib" -name "*.dylib" | /usr/bin/wc -l | /usr/bin/xargs)
160-
UNIVERSAL_DYLIB=$(/usr/bin/find "$TOOLSDIR/$TYPE/payload/${FRAMEWORKDIR}/Python3.framework/Versions/Current/lib" -name "*.dylib" | /usr/bin/xargs file | /usr/bin/grep "2 architectures" | /usr/bin/wc -l | /usr/bin/xargs)
164+
TOTAL_DYLIB=$(/usr/bin/find "$TOOLSDIR/$TYPE/payload${FRAMEWORKDIR}/Python3.framework/Versions/${PYTHON_BIN_VERSION}/lib" -name "*.dylib" | /usr/bin/wc -l | /usr/bin/xargs)
165+
UNIVERSAL_DYLIB=$(/usr/bin/find "$TOOLSDIR/$TYPE/payload${FRAMEWORKDIR}/Python3.framework/Versions/${PYTHON_BIN_VERSION}/lib" -name "*.dylib" | /usr/bin/xargs file | /usr/bin/grep "2 architectures" | /usr/bin/wc -l | /usr/bin/xargs)
161166
if [ "${TOTAL_DYLIB}" != "${UNIVERSAL_DYLIB}" ] ; then
162167
echo "Dynamic Libraries do not match, resulting in a non-universal Python framework."
163168
echo "Total Dynamic Libraries found: ${TOTAL_DYLIB}"
@@ -167,20 +172,24 @@ fi
167172

168173
echo "Dynamic Libraries are confirmed as universal"
169174

170-
TOTAL_SO=$(/usr/bin/find "$TOOLSDIR/$TYPE/payload/${FRAMEWORKDIR}/Python3.framework/Versions/Current/lib" -name "*.so" | /usr/bin/wc -l | /usr/bin/xargs)
171-
UNIVERSAL_SO=$(/usr/bin/find "$TOOLSDIR/$TYPE/payload/${FRAMEWORKDIR}/Python3.framework/Versions/Current/lib" -name "*.so" | /usr/bin/xargs file | /usr/bin/grep "2 architectures" | /usr/bin/wc -l | /usr/bin/xargs)
175+
TOTAL_SO=$(/usr/bin/find "$TOOLSDIR/$TYPE/payload${FRAMEWORKDIR}/Python3.framework/Versions/${PYTHON_BIN_VERSION}/lib" -name "*.so" | /usr/bin/wc -l | /usr/bin/xargs)
176+
UNIVERSAL_SO=$(/usr/bin/find "$TOOLSDIR/$TYPE/payload${FRAMEWORKDIR}/Python3.framework/Versions/${PYTHON_BIN_VERSION}/lib" -name "*.so" | /usr/bin/xargs file | /usr/bin/grep "2 architectures" | /usr/bin/wc -l | /usr/bin/xargs)
172177
if [ "${TOTAL_SO}" != "${UNIVERSAL_SO}" ] ; then
173178
echo "Shared objects do not match, resulting in a non-universal Python framework."
174179
echo "Total shared objects found: ${TOTAL_SO}"
175180
echo "Universal shared objects found: ${UNIVERSAL_SO}"
176-
UNIVERSAL_SO_ARRAY=("${(@f)$(/usr/bin/find "$TOOLSDIR/$TYPE/payload/${FRAMEWORKDIR}/Python3.framework/Versions/Current/lib" -name "*.so" | /usr/bin/xargs file | /usr/bin/grep "2 architectures" | awk '{print $1;}' | sed 's/:*$//g')}")
177-
TOTAL_SO_ARRAY=("${(@f)$(/usr/bin/find "$TOOLSDIR/$TYPE/payload/${FRAMEWORKDIR}/Python3.framework/Versions/Current/lib" -name "*.so" )}")
181+
UNIVERSAL_SO_ARRAY=("${(@f)$(/usr/bin/find "$TOOLSDIR/$TYPE/payload${FRAMEWORKDIR}/Python3.framework/Versions/${PYTHON_BIN_VERSION}/lib" -name "*.so" | /usr/bin/xargs file | /usr/bin/grep "2 architectures" | awk '{print $1;}' | sed 's/:*$//g')}")
182+
TOTAL_SO_ARRAY=("${(@f)$(/usr/bin/find "$TOOLSDIR/$TYPE/payload${FRAMEWORKDIR}/Python3.framework/Versions/${PYTHON_BIN_VERSION}/lib" -name "*.so" )}")
178183
echo ${TOTAL_SO_ARRAY[@]} ${UNIVERSAL_SO_ARRAY[@]} | tr ' ' '\n' | sort | uniq -u
179184
exit 1
180185
fi
181186

182187
echo "Shared objects are confirmed as universal"
183188

189+
# Print out some information about the signatures
190+
/usr/sbin/spctl -a -vvvv "$TOOLSDIR/$TYPE/payload${FRAMEWORKDIR}/Python3.framework/Versions/${PYTHON_BIN_VERSION}/Python"
191+
/usr/sbin/spctl -a -vvvv "$TOOLSDIR/$TYPE/payload${FRAMEWORKDIR}/Python3.framework/Versions/${PYTHON_BIN_VERSION}/lib/libssl.1.1.dylib"
192+
184193
# make a symbolic link to help with interactive use
185194
/bin/ln -s "$PYTHON_BIN" "$TOOLSDIR/$TYPE/payload/usr/local/bin/managed_python3"
186195

@@ -237,6 +246,7 @@ if [ -n "$2" ]; then
237246
"version": "$PYTHON_VERSION.$DATE",
238247
"name": "python_${TYPE}_signed-$PYTHON_VERSION.$DATE.pkg",
239248
"install_location": "/",
249+
"preserve_xattr": true,
240250
"signing_info": {
241251
"identity": "$2",
242252
"timestamp": true
@@ -249,10 +259,13 @@ SIGNED_JSONFILE
249259
if [ "${PKG_RESULT}" != "0" ]; then
250260
echo "Could not sign package: ${PKG_RESULT}" 1>&2
251261
else
252-
# Notarize and staple the package
253-
# If these fail, it will bail on the entire process
254-
$XCODE_NOTARY_PATH submit "$TOOLSDIR/$TYPE/build/python_${TYPE}_signed-$PYTHON_VERSION.$DATE.pkg" --keychain-profile "macadminpython" --wait
255-
$XCODE_STAPLER_PATH staple "$TOOLSDIR/$TYPE/build/python_${TYPE}_signed-$PYTHON_VERSION.$DATE.pkg"
262+
if [ -n "$6" ]; then
263+
# Notarize and staple the package
264+
$XCODE_NOTARY_PATH store-credentials --apple-id "macadmins@cleverdevops.com" --team-id "9GQZ7KUFR6" --password "$NOTARY_PASS" macadminpython
265+
# If these fail, it will bail on the entire process
266+
$XCODE_NOTARY_PATH submit "$TOOLSDIR/$TYPE/build/python_${TYPE}_signed-$PYTHON_VERSION.$DATE.pkg" --keychain-profile "macadminpython" --wait
267+
$XCODE_STAPLER_PATH staple "$TOOLSDIR/$TYPE/build/python_${TYPE}_signed-$PYTHON_VERSION.$DATE.pkg"
268+
fi
256269
# Move the signed + notarized pkg
257270
/bin/mv "$TOOLSDIR/$TYPE/build/python_${TYPE}_signed-$PYTHON_VERSION.$DATE.pkg" "$OUTPUTSDIR"
258271
fi
@@ -262,7 +275,7 @@ fi
262275

263276
# Zip and move the framework
264277
ZIPFILE="Python3.framework_$TYPE-$PYTHON_VERSION.$DATE.zip"
265-
/usr/bin/ditto -c -k --sequesterRsrc "$TOOLSDIR/$TYPE/payload/${FRAMEWORKDIR}/" ${ZIPFILE}
278+
/usr/bin/ditto -c -k --sequesterRsrc "$TOOLSDIR/$TYPE/payload${FRAMEWORKDIR}/" ${ZIPFILE}
266279
/bin/mv ${ZIPFILE} "$OUTPUTSDIR"
267280

268281
# Ensure outputs directory is owned by the current user

requirements_minimal.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1+
--no-binary :all:
12
cffi==1.15.0
2-
--no-binary cffi
33
pycparser==2.21
44
pyobjc==7.3
55
xattr==0.9.9
6-
--no-binary xattr

requirements_recommended.txt

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1+
--no-binary :all:
12
appdirs==1.4.4
23
asn1crypto==1.4.0
3-
--no-binary asn1crypto
44
attrs==21.4.0
55
black==22.1.0
6-
--no-binary black
76
certifi==2021.10.8
87
cffi==1.15.0
9-
--no-binary cffi
108
cfgv==3.3.1
119
chardet==4.0.0
1210
click==8.0.3
@@ -31,17 +29,13 @@ pyflakes==2.4.0
3129
pyobjc==8.2
3230
pyparsing==3.0.7
3331
PyYAML==6.0
34-
--no-binary PyYAML
3532
regex==2022.1.18
36-
--no-binary regex
3733
requests==2.27.1
3834
six==1.16.0
3935
tokenize-rt==4.2.1
4036
toml==0.10.2
4137
typed-ast==1.5.2
42-
--no-binary typed-ast
4338
urllib3==1.26.8
4439
virtualenv==20.13.0
4540
xattr==0.9.9
46-
--no-binary xattr
4741
zipp==3.7.0

0 commit comments

Comments
 (0)