[d16-3] Implement notarization. (#6927)

* Add a dummy x86_64 slice to all our native libraries that don't have one. (#6848)

Apple's notarization tool has a bug where they incorrectly flag Mach-O
binaries without an x86_64 slice, so make sure all our libraries have one.

* Jenkinsfile notarization (#6869)

* Add in notarization script for xamarin.mac/xamarin.iOS

* Flatten the list to get rid of the braces

* Add in keychain password

* Add login.keychain back in to access codesigning certificates

* Always sign pkgs, upload notarized copies

* Enable ios notarization and make notarized pkgs public

* Make notarization non-fatal

* Publish GH statuses for notarized PKGs

* Don't forget to declare URI variables for notarized pkgs

* report proper package links

* [jenkins] Improve package reporting.

* Use dummy function name which our tests won't complain about.
This commit is contained in:
Rolf Bjarne Kvinge 2019-09-06 05:35:12 -07:00 коммит произвёл GitHub
Родитель 377403c9a6
Коммит 08809f5bf7
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
9 изменённых файлов: 139 добавлений и 32 удалений

2
builds/.gitignore поставляемый
Просмотреть файл

@ -23,3 +23,5 @@ targettv
targetwatch
watchbcl
mono-ios-sdk-destdir
*.dylib
*.o

Просмотреть файл

@ -55,6 +55,10 @@ downloads/%: downloads/%.7z
clean-local::
$(Q) rm -Rf downloads .stamp-download-mono
X86_64_SLICE=$(abspath $(CURDIR)/x86-64-slice.dylib)
$(X86_64_SLICE): Makefile
echo "void xamarin_x86_64_function_for_notarization_workaround () {}" | $(MAC_CC) -shared -x c -o$@ -
all-local:: .stamp-download-mono .stamp-mono-ios-sdk-destdir
else
@ -840,13 +844,18 @@ IPHONEOS_TARGETS = \
$(IOS_DESTDIR)$(XAMARIN_IPHONEOS_SDK)/usr/lib/libmono-profiler-log.dylib \
$(IOS_DESTDIR)$(XAMARIN_IPHONEOS_SDK)/Frameworks/Mono.framework/Mono \
$(IOS_DESTDIR)$(XAMARIN_IPHONEOS_SDK)/usr/lib/%: .stamp-$(MONO_BUILD_MODE) | $(IOS_DESTDIR)$(XAMARIN_IPHONEOS_SDK)/usr/lib
$(Q) $(CP) $(MONO_IOS_SDK_DESTDIR)/ios-libs/ios/$(notdir $@) $@
$(IOS_DESTDIR)$(XAMARIN_IPHONEOS_SDK)/usr/lib/%: .stamp-$(MONO_BUILD_MODE) $(X86_64_SLICE) | $(IOS_DESTDIR)$(XAMARIN_IPHONEOS_SDK)/usr/lib
@#$(Q) $(CP) $(MONO_IOS_SDK_DESTDIR)/ios-libs/ios/$(notdir $@) $@
$(Q_LIPO) lipo $(MONO_IOS_SDK_DESTDIR)/ios-libs/ios/$(notdir $@) $(X86_64_SLICE) -create -output $@
$(Q) if test -d $(MONO_IOS_SDK_DESTDIR)/ios-libs/ios/$(notdir $@).dSYM; then $(CP) -R $(MONO_IOS_SDK_DESTDIR)/ios-libs/ios/$(notdir $@).dSYM $(dir $@); fi
$(IOS_DESTDIR)$(XAMARIN_IPHONEOS_SDK)/Frameworks/Mono.framework/Mono: .stamp-$(MONO_BUILD_MODE) | $(IOS_DESTDIR)$(XAMARIN_IPHONEOS_SDK)/Frameworks
$(Q) $(CP) -R $(MONO_IOS_SDK_DESTDIR)/ios-frameworks/ios/Mono.framework $(IOS_DESTDIR)$(XAMARIN_IPHONEOS_SDK)/Frameworks
$(Q) $(CP) -R $(MONO_IOS_SDK_DESTDIR)/ios-frameworks/ios/Mono.framework.dSYM $(IOS_DESTDIR)$(XAMARIN_IPHONEOS_SDK)/Frameworks
@# inject x86-64 slice
$(Q) mv $@ $@.tmp
$(Q_LIPO) lipo $@.tmp $(X86_64_SLICE) -create -output $@
$(Q) rm $@.tmp
$(IPHONEOS_DIRECTORIES):
$(Q) mkdir -p $@
@ -877,13 +886,18 @@ WATCHOS_TARGETS = \
$(IOS_DESTDIR)$(XAMARIN_WATCHOS_SDK)/usr/lib/libmono-profiler-log.dylib \
$(IOS_DESTDIR)$(XAMARIN_WATCHOS_SDK)/Frameworks/Mono.framework/Mono \
$(IOS_DESTDIR)$(XAMARIN_WATCHOS_SDK)/usr/lib/%: .stamp-$(MONO_BUILD_MODE) | $(IOS_DESTDIR)$(XAMARIN_WATCHOS_SDK)/usr/lib
$(Q) $(CP) $(MONO_IOS_SDK_DESTDIR)/ios-libs/watchos/$(notdir $@) $@
$(IOS_DESTDIR)$(XAMARIN_WATCHOS_SDK)/usr/lib/%: .stamp-$(MONO_BUILD_MODE) $(X86_64_SLICE) | $(IOS_DESTDIR)$(XAMARIN_WATCHOS_SDK)/usr/lib
@#$(Q) $(CP) $(MONO_IOS_SDK_DESTDIR)/ios-libs/watchos/$(notdir $@) $@
$(Q_LIPO) lipo $(MONO_IOS_SDK_DESTDIR)/ios-libs/watchos/$(notdir $@) $(X86_64_SLICE) -create -output $@
$(Q) if test -d $(MONO_IOS_SDK_DESTDIR)/ios-libs/watchos/$(notdir $@).dSYM; then $(CP) -R $(MONO_IOS_SDK_DESTDIR)/ios-libs/watchos/$(notdir $@).dSYM $(dir $@); fi
$(IOS_DESTDIR)$(XAMARIN_WATCHOS_SDK)/Frameworks/Mono.framework/Mono: .stamp-$(MONO_BUILD_MODE) | $(IOS_DESTDIR)$(XAMARIN_WATCHOS_SDK)/Frameworks
$(IOS_DESTDIR)$(XAMARIN_WATCHOS_SDK)/Frameworks/Mono.framework/Mono: .stamp-$(MONO_BUILD_MODE) $(X86_64_SLICE) | $(IOS_DESTDIR)$(XAMARIN_WATCHOS_SDK)/Frameworks
$(Q) $(CP) -R $(MONO_IOS_SDK_DESTDIR)/ios-frameworks/watchos/Mono.framework $(IOS_DESTDIR)$(XAMARIN_WATCHOS_SDK)/Frameworks
$(Q) $(CP) -R $(MONO_IOS_SDK_DESTDIR)/ios-frameworks/watchos/Mono.framework.dSYM $(IOS_DESTDIR)$(XAMARIN_WATCHOS_SDK)/Frameworks
@# inject x86-64 slice
$(Q) mv $@ $@.tmp
$(Q_LIPO) lipo $@.tmp $(X86_64_SLICE) -create -output $@
$(Q) rm $@.tmp
$(WATCHOS_DIRECTORIES):
$(Q) mkdir -p $@
@ -914,13 +928,18 @@ TVOS_TARGETS = \
$(IOS_DESTDIR)$(XAMARIN_TVOS_SDK)/usr/lib/libmono-profiler-log.dylib \
$(IOS_DESTDIR)$(XAMARIN_TVOS_SDK)/Frameworks/Mono.framework/Mono \
$(IOS_DESTDIR)$(XAMARIN_TVOS_SDK)/usr/lib/%: .stamp-$(MONO_BUILD_MODE) | $(IOS_DESTDIR)$(XAMARIN_TVOS_SDK)/usr/lib
$(Q) $(CP) $(MONO_IOS_SDK_DESTDIR)/ios-libs/tvos/$(notdir $@) $@
$(IOS_DESTDIR)$(XAMARIN_TVOS_SDK)/usr/lib/%: .stamp-$(MONO_BUILD_MODE) $(X86_64_SLICE) | $(IOS_DESTDIR)$(XAMARIN_TVOS_SDK)/usr/lib
@#$(Q) $(CP) $(MONO_IOS_SDK_DESTDIR)/ios-libs/tvos/$(notdir $@) $@
$(Q_LIPO) lipo $(MONO_IOS_SDK_DESTDIR)/ios-libs/tvos/$(notdir $@) $(X86_64_SLICE) -create -output $@
$(Q) if test -d $(MONO_IOS_SDK_DESTDIR)/ios-libs/tvos/$(notdir $@).dSYM; then $(CP) -R $(MONO_IOS_SDK_DESTDIR)/ios-libs/tvos/$(notdir $@).dSYM $(dir $@); fi
$(IOS_DESTDIR)$(XAMARIN_TVOS_SDK)/Frameworks/Mono.framework/Mono: .stamp-$(MONO_BUILD_MODE) | $(IOS_DESTDIR)$(XAMARIN_TVOS_SDK)/Frameworks
$(IOS_DESTDIR)$(XAMARIN_TVOS_SDK)/Frameworks/Mono.framework/Mono: .stamp-$(MONO_BUILD_MODE) $(X86_64_SLICE) | $(IOS_DESTDIR)$(XAMARIN_TVOS_SDK)/Frameworks
$(Q) $(CP) -R $(MONO_IOS_SDK_DESTDIR)/ios-frameworks/tvos/Mono.framework $(IOS_DESTDIR)$(XAMARIN_TVOS_SDK)/Frameworks
$(Q) $(CP) -R $(MONO_IOS_SDK_DESTDIR)/ios-frameworks/tvos/Mono.framework.dSYM $(IOS_DESTDIR)$(XAMARIN_TVOS_SDK)/Frameworks
@# inject x86-64 slice
$(Q) mv $@ $@.tmp
$(Q_LIPO) lipo $@.tmp $(X86_64_SLICE) -create -output $@
$(Q) rm $@.tmp
$(TVOS_DIRECTORIES):
$(Q) mkdir -p $@

67
jenkins/Jenkinsfile поставляемый
Просмотреть файл

@ -10,6 +10,8 @@ packagePrefix = null
virtualPath = null
xiPackageUrl = null
xmPackageUrl = null
xiNotarizedPackageUrl = null
xmNotarizedPackageUrl = null
utils = null
errorMessage = null
currentStage = null
@ -19,6 +21,8 @@ manualException = false
xiPackageFilename = null
xmPackageFilename = null
xiNotarizedPkgFilename = null
xmNotarizedPkgFilename = null
msbuildZipFilename = null
bundleZipFilename = null
manifestFilename = null
@ -476,6 +480,9 @@ timestamps {
}
stage ('Signing') {
def notarize_mac = true
def notarize_ios = true
def entitlements = "${workspace}/xamarin-macios/mac-entitlements.plist"
currentStage = "${STAGE_NAME}"
echo ("Building on ${env.NODE_NAME}")
def xiPackages = findFiles (glob: "package/xamarin.ios-*.pkg")
@ -494,8 +501,49 @@ timestamps {
def bundleZip = findFiles (glob: "package/bundle.zip")
if (bundleZip.length > 0)
bundleZipFilename = bundleZip [0].name
withCredentials ([string (credentialsId: 'codesign_keychain_pw', variable: 'PRODUCTSIGN_KEYCHAIN_PASSWORD')]) {
sh ("${workspace}/xamarin-macios/jenkins/productsign.sh")
sh ("${workspace}/xamarin-macios/jenkins/productsign.sh")
}
if (notarize_mac || notarize_ios) {
try {
pkgs = []
if (fileExists('release-scripts')) {
dir('release-scripts') {
sh ('git checkout sign-and-notarized && git pull')
}
} else {
sh ('git clone git@github.com:xamarin/release-scripts -b sign-and-notarized')
}
if (notarize_mac)
pkgs = pkgs + xmPackages
if (notarize_ios)
pkgs = pkgs + xiPackages
withCredentials([string(credentialsId: 'codesign_keychain_pw', variable: 'KEYCHAIN_PASS'), string(credentialsId: 'team_id', variable: 'TEAM_ID'), string(credentialsId: 'application_id', variable: 'APP_ID'), string(credentialsId: 'installer_id', variable: 'INSTALL_ID'), usernamePassword(credentialsId: 'apple_account', passwordVariable: 'APPLE_PASS', usernameVariable: 'APPLE_ACCOUNT')]) {
sh (returnStatus: true, script: "security create-keychain -p ${env.KEYCHAIN_PASS} login.keychain") // needed to repopulate the keychain
sh ("security unlock-keychain -p ${env.KEYCHAIN_PASS} login.keychain")
sh ("python release-scripts/sign_and_notarize.py -a ${env.APP_ID} -i ${env.INSTALL_ID} -u ${env.APPLE_ACCOUNT} -p ${env.APPLE_PASS} -t ${env.TEAM_ID} -d package/notarized -e ${entitlements} -k login.keychain " + pkgs.flatten().join(" "))
}
def xiNotarizedPackages = findFiles (glob: "package/notarized/xamarin.ios-*.pkg")
if (xiNotarizedPackages.length > 0) {
xiNotarizedPkgFilename = xiNotarizedPackages [0].name
echo ("Created notarized Xamarin.iOS package: ${xiNotarizedPkgFilename}")
}
def xmNotarizedPackages = findFiles (glob: "package/notarized/xamarin.mac-*.pkg")
if (xmNotarizedPackages.length > 0) {
xmNotarizedPkgFilename = xmNotarizedPackages [0].name
echo ("Created notarized Xamarin.Mac package: ${xmNotarizedPkgFilename}")
}
} catch (ex) {
echo "Notarization failed:\n${ex.getMessage()}"
for (def stack : ex.getStackTrace()) {
echo "\t${stack}"
}
manager.addWarningBadge("PKGs are not notarized")
}
}
}
@ -530,6 +578,7 @@ timestamps {
sh ("ls -la package")
uploadFiles ("package/*", "wrench", virtualPath)
uploadFiles ("package/notarized/*", "wrench", virtualPath)
uploadFiles ("package-internal/*", "jenkins-internal", virtualPath)
// Also upload manifest to a predictable url (without the build number)
@ -557,12 +606,22 @@ timestamps {
if (xiPackageFilename != null) {
xiPackageUrl = "${packagePrefix}/${xiPackageFilename}"
utils.reportGitHubStatus (gitHash, 'PKG-Xamarin.iOS', "${xiPackageUrl}", 'SUCCESS', "${xiPackageFilename}")
packagesMessage += "[${xiPackageFilename}](${xiPackageUrl}) "
packagesMessage += "* [${xiPackageFilename} (Not notarized)](${xiPackageUrl})\n"
}
if (xmPackageFilename != null) {
xmPackageUrl = "${packagePrefix}/${xmPackageFilename}"
utils.reportGitHubStatus (gitHash, 'PKG-Xamarin.Mac', "${xmPackageUrl}", 'SUCCESS', "${xmPackageFilename}")
packagesMessage += "[${xmPackageFilename}](${xmPackageUrl})"
packagesMessage += "* [${xmPackageFilename} (Not notarized)](${xmPackageUrl})\n"
}
if (xiNotarizedPkgFilename != null) {
xiNotarizedPackageUrl = "${packagePrefix}/notarized/${xiNotarizedPkgFilename}"
utils.reportGitHubStatus (gitHash, 'PKG-Xamarin.iOS-notarized', "${xiNotarizedPackageUrl}", 'SUCCESS', "${xiNotarizedPkgFilename}")
packagesMessage += "* [${xiNotarizedPkgFilename} (Notarized)](${xiNotarizedPackageUrl})\n"
}
if (xmNotarizedPkgFilename != null) {
xmNotarizedPackageUrl = "${packagePrefix}/notarized/${xmNotarizedPkgFilename}"
utils.reportGitHubStatus (gitHash, 'PKG-Xamarin.Mac-notarized', "${xmNotarizedPackageUrl}", 'SUCCESS', "${xmNotarizedPkgFilename}")
packagesMessage += "* [${xmNotarizedPkgFilename} (Notarized)](${xmNotarizedPackageUrl})\n"
}
if (manifestFilename != null) {
def manifestUrl = "${packagePrefix}/${manifestFilename}"
@ -582,7 +641,7 @@ timestamps {
}
if (packagesMessage != "")
appendFileComment ("✅ Packages: ${packagesMessage}\n")
appendFileComment ("✅ Packages: \n${packagesMessage}\n")
}
dir ('xamarin-macios') {

14
mac-entitlements.plist Normal file
Просмотреть файл

@ -0,0 +1,14 @@
<?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.allow-dyld-environment-variables</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
</dict>
</plist>

2
runtime/.gitignore поставляемый
Просмотреть файл

@ -9,3 +9,5 @@ app-main.m
watchextension-main.m
tvextension-main.m
bindings-generated.m
*.dylib
*.o

Просмотреть файл

@ -30,6 +30,10 @@ SHARED_FILES = $(SHARED_SOURCES) $(SHARED_HEADERS) $(SHARED_I386_SOURCES) $(SHAR
EXTRA_DEPENDENCIES = $(SHARED_HEADERS) $(TOP)/Make.config $(TOP)/mk/mono.mk
X86_64_SLICE=$(abspath $(CURDIR)/x86-64-slice.dylib)
$(X86_64_SLICE): Makefile
echo "void xamarin_x86_64_function_for_notarization_workaround_v2 () {}" | $(MAC_CC) -shared -x c -o$@ -
xamarin/mono-runtime.h: mono-runtime.h.t4 exports.t4
$(Q_GEN) $(TT) $< -o $@
@ -261,41 +265,41 @@ $$(foreach arch,$$($(2)_ARCHITECTURES),.libs/$(1)/tvextension-main.$$(arch).o):
$(Q) install_name_tool -id @rpath/libxamarin-debug.dylib $$@
$(Q) install_name_tool -change @rpath/ @rpath/libmonosgen-2.0.dylib $$@
.libs/$(1)/libxamarin-dev.dylib: $$(foreach arch,$$($(2)_DEVICE_ARCHITECTURES),.libs/$(1)/libxamarin.$$(arch).dylib)
.libs/$(1)/libxamarin-dev.dylib: $$(foreach arch,$$($(2)_DEVICE_ARCHITECTURES),.libs/$(1)/libxamarin.$$(arch).dylib) $(X86_64_SLICE)
$(Q) rm -f $$@
ifeq (1,$$(words $$($(2)_DEVICE_ARCHITECTURES)))
$(Q) $(CP) $$^ $$@
else
#ifeq (1,$$(words $$($(2)_DEVICE_ARCHITECTURES)))
# $(Q) $(CP) $$^ $$@
#else
$$(call Q_2,LIPO, [$1]) $(DEVICE_BIN_PATH)/lipo $$^ -create -output $$@
endif
#endif
$(Q) install_name_tool -id @rpath/libxamarin.dylib $$@
$(Q) install_name_tool -change @rpath/ @rpath/libmonosgen-2.0.dylib $$@
.libs/$(1)/libxamarin-debug-dev.dylib: $$(foreach arch,$$($(2)_DEVICE_ARCHITECTURES),.libs/$(1)/libxamarin-debug.$$(arch).dylib)
.libs/$(1)/libxamarin-debug-dev.dylib: $$(foreach arch,$$($(2)_DEVICE_ARCHITECTURES),.libs/$(1)/libxamarin-debug.$$(arch).dylib) $(X86_64_SLICE)
$(Q) rm -f $$@
ifeq (1,$$(words $$($(2)_DEVICE_ARCHITECTURES)))
$(Q) $(CP) $$^ $$@
else
#ifeq (1,$$(words $$($(2)_DEVICE_ARCHITECTURES)))
# $(Q) $(CP) $$^ $$@
#else
$$(call Q_2,LIPO, [$1]) $(DEVICE_BIN_PATH)/lipo $$^ -create -output $$@
endif
#endif
$(Q) install_name_tool -id @rpath/libxamarin-debug.dylib $$@
$(Q) install_name_tool -change @rpath/ @rpath/libmonosgen-2.0.dylib $$@
.libs/$(1)/Xamarin-dev.framework: $$(foreach arch,$$($(2)_DEVICE_ARCHITECTURES),.libs/$(1)/Xamarin.$$(arch).framework)
.libs/$(1)/Xamarin-dev.framework: $$(foreach arch,$$($(2)_DEVICE_ARCHITECTURES),.libs/$(1)/Xamarin.$$(arch).framework) $(X86_64_SLICE)
$(Q) rm -f $$@
ifeq (1,$$(words $$($(2)_DEVICE_ARCHITECTURES)))
$(Q) $(CP) $$^ $$@
else
#ifeq (1,$$(words $$($(2)_DEVICE_ARCHITECTURES)))
# $(Q) $(CP) $$^ $$@
#else
$$(call Q_2,LIPO, [$1]) $(DEVICE_BIN_PATH)/lipo $$^ -create -output $$@
endif
#endif
.libs/$(1)/Xamarin-debug-dev.framework: $$(foreach arch,$$($(2)_DEVICE_ARCHITECTURES),.libs/$(1)/Xamarin-debug.$$(arch).framework)
.libs/$(1)/Xamarin-debug-dev.framework: $$(foreach arch,$$($(2)_DEVICE_ARCHITECTURES),.libs/$(1)/Xamarin-debug.$$(arch).framework) $(X86_64_SLICE)
$(Q) rm -f $$@
ifeq (1,$$(words $$($(2)_DEVICE_ARCHITECTURES)))
$(Q) $(CP) $$^ $$@
else
#ifeq (1,$$(words $$($(2)_DEVICE_ARCHITECTURES)))
# $(Q) $(CP) $$^ $$@
#else
$$(call Q_2,LIPO, [$1]) $(DEVICE_BIN_PATH)/lipo $$^ -create -output $$@
endif
#endif
.libs/$(1)/Xamarin-sim.framework: $$(foreach arch,$$($(2)_SIM_ARCHITECTURES),.libs/$(1)/Xamarin.$$(arch).framework)
$(Q) rm -f $$@

Просмотреть файл

@ -70,6 +70,8 @@ namespace Xamarin.Tests
foreach (var machoFile in machoFiles) {
var fatfile = MachO.Read (machoFile);
foreach (var slice in fatfile) {
if (slice.IsDynamicLibrary && slice.Architecture == MachO.Architectures.x86_64 && slice.Parent.size < 10240 /* this is the dummy x86_64 slice to appease Apple's notarization tooling */)
continue;
var any_load_command = false;
foreach (var lc in slice.load_commands) {

Просмотреть файл

@ -585,6 +585,7 @@ namespace Xamarin
public List<LoadCommand> load_commands;
public string Filename { get { return filename; } }
public FatEntry Parent { get { return fat_parent; } }
public MachOFile (FatEntry parent)
{

Просмотреть файл

@ -1776,6 +1776,10 @@ namespace Xamarin.Bundler {
}
if (LibMonoLinkMode == AssemblyBuildTarget.Framework)
Driver.XcodeRun ("install_name_tool", "-change @rpath/libmonosgen-2.0.dylib @rpath/Mono.framework/Mono " + StringUtils.Quote (targetPath));
// Remove architectures we don't care about.
if (IsDeviceBuild)
MachO.SelectArchitectures (targetPath, AllArchitectures);
} else {
Driver.Log (3, "Target '{0}' is up-to-date.", targetPath);
}