mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-29 12:19:03 +03:00
Merge pull request #7103 from nextcloud/bugfix/mac-crafter-codesign-notarisation
Code-sign client via mac-crafter so it may pass notarisation
This commit is contained in:
commit
9ffd0d455f
2 changed files with 91 additions and 16 deletions
|
@ -33,7 +33,7 @@ func isAppExtension(_ path: String) -> Bool {
|
||||||
func codesign(
|
func codesign(
|
||||||
identity: String,
|
identity: String,
|
||||||
path: String,
|
path: String,
|
||||||
options: String = "--timestamp --force --preserve-metadata=entitlements --verbose=4 --options runtime"
|
options: String = "--timestamp --force --preserve-metadata=entitlements --verbose=4 --options runtime --deep"
|
||||||
) throws {
|
) throws {
|
||||||
print("Code-signing \(path)...")
|
print("Code-signing \(path)...")
|
||||||
let command = "codesign -s \"\(identity)\" \(options) \(path)"
|
let command = "codesign -s \"\(identity)\" \(options) \(path)"
|
||||||
|
@ -56,17 +56,70 @@ func recursivelyCodesign(path: String, identity: String) throws {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func saveCodesignEntitlements(target: String, path: String) throws {
|
||||||
|
let command = "codesign -d --entitlements \(path) --xml \(target)"
|
||||||
|
guard shell(command) == 0 else {
|
||||||
|
throw CodeSigningError.failedToCodeSign("Failed to save entitlements for \(target).")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func codesignClientAppBundle(
|
func codesignClientAppBundle(
|
||||||
at clientAppDir: String, withCodeSignIdentity codeSignIdentity: String
|
at clientAppDir: String, withCodeSignIdentity codeSignIdentity: String
|
||||||
) throws {
|
) throws {
|
||||||
print("Code-signing Nextcloud Desktop Client libraries, frameworks and plugins...")
|
print("Code-signing Nextcloud Desktop Client libraries, frameworks and plugins...")
|
||||||
|
|
||||||
let clientContentsDir = "\(clientAppDir)/Contents"
|
let clientContentsDir = "\(clientAppDir)/Contents"
|
||||||
|
let frameworksPath = "\(clientContentsDir)/Frameworks"
|
||||||
|
let pluginsPath = "\(clientContentsDir)/PlugIns"
|
||||||
|
|
||||||
try recursivelyCodesign(path: "\(clientContentsDir)/Frameworks", identity: codeSignIdentity)
|
try recursivelyCodesign(path: frameworksPath, identity: codeSignIdentity)
|
||||||
try recursivelyCodesign(path: "\(clientContentsDir)/PlugIns", identity: codeSignIdentity)
|
try recursivelyCodesign(path: pluginsPath, identity: codeSignIdentity)
|
||||||
try recursivelyCodesign(path: "\(clientContentsDir)/Resources", identity: codeSignIdentity)
|
try recursivelyCodesign(path: "\(clientContentsDir)/Resources", identity: codeSignIdentity)
|
||||||
|
|
||||||
print("Code-signing Nextcloud Desktop Client app bundle...")
|
print("Code-signing QtWebEngineProcess...")
|
||||||
try codesign(identity: codeSignIdentity, path: clientAppDir)
|
let qtWebEngineProcessPath =
|
||||||
|
"\(frameworksPath)/QtWebEngineCore.framework/Versions/A/Helpers/QtWebEngineProcess.app"
|
||||||
|
try codesign(identity: codeSignIdentity, path: qtWebEngineProcessPath)
|
||||||
|
|
||||||
|
print("Code-signing QtWebEngine...")
|
||||||
|
try codesign(identity: codeSignIdentity, path: "\(frameworksPath)/QtWebEngineCore.framework")
|
||||||
|
|
||||||
|
// Time to fix notarisation issues.
|
||||||
|
// Multiple components of the app will now have the get-task-allow entitlements.
|
||||||
|
// We need to strip these out manually.
|
||||||
|
|
||||||
|
print("Code-signing Sparkle autoupdater app (without entitlements)...")
|
||||||
|
let sparkleFrameworkPath = "\(frameworksPath)/Sparkle.framework"
|
||||||
|
try codesign(identity: codeSignIdentity,
|
||||||
|
path: "\(sparkleFrameworkPath)/Resources/Autoupdate.app/Contents/MacOS/*",
|
||||||
|
options: "--timestamp --force --verbose=4 --options runtime --deep")
|
||||||
|
|
||||||
|
print("Re-codesigning Sparkle library...")
|
||||||
|
try codesign(identity: codeSignIdentity, path: "\(sparkleFrameworkPath)/Sparkle")
|
||||||
|
|
||||||
|
print("Code-signing app extensions (removing get-task-allow entitlements)...")
|
||||||
|
let fm = FileManager.default
|
||||||
|
let appExtensionPaths =
|
||||||
|
try fm.contentsOfDirectory(atPath: pluginsPath).filter(isAppExtension)
|
||||||
|
for appExtension in appExtensionPaths {
|
||||||
|
let appExtensionPath = "\(pluginsPath)/\(appExtension)"
|
||||||
|
let tmpEntitlementXmlPath =
|
||||||
|
fm.temporaryDirectory.appendingPathComponent(UUID().uuidString).path.appending(".xml")
|
||||||
|
try saveCodesignEntitlements(target: appExtensionPath, path: tmpEntitlementXmlPath)
|
||||||
|
// Strip the get-task-allow entitlement from the XML entitlements file
|
||||||
|
let xmlEntitlements = try String(contentsOfFile: tmpEntitlementXmlPath)
|
||||||
|
let entitlementKeyValuePair = "<key>com.apple.security.get-task-allow</key><true/>"
|
||||||
|
let strippedEntitlements =
|
||||||
|
xmlEntitlements.replacingOccurrences(of: entitlementKeyValuePair, with: "")
|
||||||
|
try strippedEntitlements.write(toFile: tmpEntitlementXmlPath,
|
||||||
|
atomically: true,
|
||||||
|
encoding: .utf8)
|
||||||
|
try codesign(identity: codeSignIdentity,
|
||||||
|
path: appExtensionPath,
|
||||||
|
options: "--timestamp --force --verbose=4 --options runtime --deep --entitlements \(tmpEntitlementXmlPath)")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now we do the final codesign bit
|
||||||
|
print("Code-signing Nextcloud Desktop Client binaries...")
|
||||||
|
try codesign(identity: codeSignIdentity, path: "\(clientContentsDir)/MacOS/*")
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,10 +15,8 @@
|
||||||
import ArgumentParser
|
import ArgumentParser
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
struct MacCrafter: ParsableCommand {
|
struct Build: ParsableCommand {
|
||||||
static let configuration = CommandConfiguration(
|
static let configuration = CommandConfiguration(abstract: "Client building script")
|
||||||
abstract: "A tool to easily build a fully-functional Nextcloud Desktop Client for macOS."
|
|
||||||
)
|
|
||||||
|
|
||||||
enum MacCrafterError: Error {
|
enum MacCrafterError: Error {
|
||||||
case failedEnumeration(String)
|
case failedEnumeration(String)
|
||||||
|
@ -194,14 +192,11 @@ struct MacCrafter: ParsableCommand {
|
||||||
throw MacCrafterError.craftError("Error crafting Nextcloud Desktop Client.")
|
throw MacCrafterError.craftError("Error crafting Nextcloud Desktop Client.")
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let codeSignIdentity else {
|
|
||||||
print("Crafted Nextcloud Desktop Client. Not codesigned.")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
print("Code-signing Nextcloud Desktop Client libraries and frameworks...")
|
|
||||||
let clientAppDir = "\(clientBuildDir)/image-\(buildType)-master/\(appName).app"
|
let clientAppDir = "\(clientBuildDir)/image-\(buildType)-master/\(appName).app"
|
||||||
|
if let codeSignIdentity {
|
||||||
|
print("Code-signing Nextcloud Desktop Client libraries and frameworks...")
|
||||||
try codesignClientAppBundle(at: clientAppDir, withCodeSignIdentity: codeSignIdentity)
|
try codesignClientAppBundle(at: clientAppDir, withCodeSignIdentity: codeSignIdentity)
|
||||||
|
}
|
||||||
|
|
||||||
print("Placing Nextcloud Desktop Client in \(productPath)...")
|
print("Placing Nextcloud Desktop Client in \(productPath)...")
|
||||||
if !fm.fileExists(atPath: productPath) {
|
if !fm.fileExists(atPath: productPath) {
|
||||||
|
@ -209,10 +204,37 @@ struct MacCrafter: ParsableCommand {
|
||||||
atPath: productPath, withIntermediateDirectories: true, attributes: nil
|
atPath: productPath, withIntermediateDirectories: true, attributes: nil
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
if fm.fileExists(atPath: "\(productPath)/\(appName).app") {
|
||||||
|
try fm.removeItem(atPath: "\(productPath)/\(appName).app")
|
||||||
|
}
|
||||||
try fm.copyItem(atPath: clientAppDir, toPath: "\(productPath)/\(appName).app")
|
try fm.copyItem(atPath: clientAppDir, toPath: "\(productPath)/\(appName).app")
|
||||||
|
|
||||||
print("Done!")
|
print("Done!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Codesign: ParsableCommand {
|
||||||
|
static let configuration = CommandConfiguration(abstract: "Codesigning script for the client.")
|
||||||
|
|
||||||
|
@Argument(help: "Path to the Nextcloud Desktop Client app bundle.")
|
||||||
|
var appBundlePath = "\(FileManager.default.currentDirectoryPath)/product/Nextcloud.app"
|
||||||
|
|
||||||
|
@Option(name: [.short, .long], help: "Code signing identity for desktop client and libs.")
|
||||||
|
var codeSignIdentity: String
|
||||||
|
|
||||||
|
mutating func run() throws {
|
||||||
|
try codesignClientAppBundle(at: appBundlePath, withCodeSignIdentity: codeSignIdentity)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MacCrafter: ParsableCommand {
|
||||||
|
static let configuration = CommandConfiguration(
|
||||||
|
abstract: "A tool to easily build a fully-functional Nextcloud Desktop Client for macOS.",
|
||||||
|
subcommands: [Build.self, Codesign.self],
|
||||||
|
defaultSubcommand: Build.self
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
MacCrafter.main()
|
MacCrafter.main()
|
||||||
|
|
Loading…
Reference in a new issue