Verwenden Sie xcodebuild (Xcode 8) und die automatische Signatur in CI-Umgebungen (Travis / Jenkins)

73

Mit der Veröffentlichung von Xcode 8 hat Apple eine neue Methode zur Verwaltung der Signaturkonfiguration eingeführt. Jetzt haben Sie zwei Möglichkeiten Manualund Automatic.

Laut der WWDC 2016-Sitzung zum Thema Codesignatur (WWDC 2016 - 401 - Was ist neu in der Xcode-App-Signatur) wird Xcode bei Auswahl der AutomaticSignatur Folgendes tun:

  • Erstellen Sie Signaturzertifikate
  • Erstellen und aktualisieren Sie App-IDs
  • Erstellen und aktualisieren Sie Bereitstellungsprofile

Laut den Aussagen von Apple in dieser Sitzung wird das Automatic Signingjedoch verwendet Development signingund ist auf von Xcode erstellte Bereitstellungsprofile beschränkt.

Das Problem tritt auf, wenn Sie versuchen, es Automatic Signingin einer CI-Umgebung (wie Travis CI oder Jenkins) zu verwenden. Ich bin nicht in der Lage, einen einfachen Weg zu finden, um weiterhin Automatisch zu verwenden und für die Verteilung zu signieren (da Xcode Sie dazu zwingt, von der Entwicklung und Xcode erstellte Bereitstellungsprofile zu verwenden).

Die neuen "von Xcode erstellten Bereitstellungsprofile" werden nicht im Entwicklerportal angezeigt, obwohl ich sie dann auf meinem Computer finden kann. Soll ich diese Profile auf den CI-Computer verschieben, für sie erstellen Developmentund für sie exportieren Distribution? Gibt es eine Möglichkeit, die Automatic SigningVerwendung zu überschreiben xcodebuild?

Pablobart
quelle
8
Ich habe das gleiche Problem, das mich wild macht.
Nebel
2
Ich habe ein einfaches Ruby-Skript erstellt , mit dem Sie zwischen automatischer und manueller Signatur wechseln können. Sie können auf manuelle Signierung wechseln und verwenden Sie die PROVISIONING_PROFILE_SPECIFIER, CODE_SIGN_IDENTITYKombination. Beachten Sie, dass xcodeprojGem verwendet wird, das Sie zuerst installieren müssen gem install xcodeproj. Ich hoffe, dies wird dir helfen.
thelvis
Das ist großartig, am Ende habe ich das Gleiche getan. In meinem Fall hat ein einfaches Suchen und Ersetzen gut funktioniert. Ich werde meine Erkenntnisse teilen.
Pablobart
Das Problem bleibt bestehen, auch wenn Sie zu wechseln, Manual signingmüssen Sie eine Möglichkeit finden, Ihre Zertifizierungs- und Bereitstellungsprofile (Entwicklung oder Produktion) für alle Ihre CI-Server freizugeben (da der Befehl cli xcodebuild diese nicht wie xcode verwaltet). Davon abgesehen können Sie einige Profile wieder manuell verwalten (z. B. mit Fastlane), und die automatische Funktion verliert etwas an Interesse.
Nicolas Braun
Die Wahrheit ist, dass das automatische Signieren eine großartige Funktion ist, solange Sie Xcode verwenden. Es funktioniert endlich! Der traurige Teil ist, dass es nicht funktioniert, wenn Sie Xcode nicht öffnen (wie in CI). Daher haben wir beim Entwickeln die automatische Signatur verwendet und mithilfe des obigen Skripts für Jenkins Builds auf manuell umgestellt. Es wäre jedoch großartig, wenn xcodebuildSie die automatische Signatur selbst durchführen könnten. Hoffen wir, dass die Signierung in der nächsten Version von Xcode vollständig automatisiert wird. ^^
thelvis

Antworten:

62

Grundsätzlich stoße ich mit Jenkins CI und dem Xcode Plugin auf dasselbe Problem. Am Ende habe ich das Build- und Codesigning-Zeug selbst gemacht xcodebuild.

0. Voraussetzungen

Um die folgenden Schritte erfolgreich ausführen zu können, müssen Sie die erforderlichen Bereitstellungsprofile und Zertifikate installiert haben. Das bedeutet, dass Ihre Codesignatur im Allgemeinen bereits funktionieren sollte.

1. Erstellen eines .xcarchive

xcodebuild -project <path/to/project.xcproj> -scheme <scheme-name> -configuration <config-name> clean archive -archivePath <output-path> DEVELOPMENT_TEAM=<dev-team-id>
  • DEVELOPMENT_TEAM: Ihre 10-stellige Entwicklerteam-ID (so etwas wie A1B2C3D4E5)

2. Exportieren nach .ipa

xcodebuild -exportArchive -archivePath <path/to/your.xcarchive> -exportOptionsPlist <path/to/exportOptions.plist> -exportPath <output-path>

Beispiel eines exportOptions.plist:

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>method</key>
    <string>development</string>
    <key>teamID</key>
    <string> A1B2C3D4E5 </string>
</dict>
</plist>
  • method: Eines von development, app-store, ad-hoc,enterprise
  • teamID: Ihre 10-stellige Entwicklerteam-ID (so etwas wie A1B2C3D4E5)

Dieser Vorgang ist ohnehin näher an dem, was Sie mit Xcode manuell tun würden, als beispielsweise an dem Jenkins Xcode Plugin.

Hinweis: Die .xcarchive-Datei wird immer von der Entwicklung signiert. Wenn Sie jedoch im zweiten Schritt "App-Store" als Methode auswählen, wird die Verteilungssignatur korrekt ausgeführt und das Verteilungsprofil als "embedded.mobileprovision" eingefügt.

Hoffe das hilft.

d4Rk
quelle
2
Wenn die Signatur auf AutomaticXcode gesetzt ist, wird Xcode iPhone Developerauch nach dem Setzen von DEVELOPMENT_TEAMund noch verwendet CODE_SIGNING_IDENTITY='Phone Distribution'. Wenn Sie das Protokoll von überprüfen xcodebuild, können Sie feststellen, dass das Codesign verwendet wird. Daher Signing Identity: "iPhone Developer: XXXX (XXXXX)"benötigt Ihre CI-Umgebung das Entwicklerzertifikat und automatisch generierte Bereitstellungsprofile. Verwenden Sie Manualoder Automatic?
Pablobart
4
Grundsätzlich, wenn Sie versuchen, das zu erzwingen, CODE_SIGNING_IDENTIYaber Sie haben die AutomaticSignatur aktiviert, erhalten Sie die folgende Fehlermeldung:<YourTarget> has conflicting provisioning settings. <YourTarget> is automatically signed, but code signing identity iPhone Distribution: ... has been manually specified. Set the code signing identity value to "iPhone Developer" in the build settings editor, or switch to manual signing in the project editor.
Pablobart
Eigentlich verwende ich Unity3D, um das Xcode-Projekt zu erstellen, aber wenn ich das Projekt öffne, kann ich sehen, dass "Signatur automatisch verwalten" aktiviert ist. Ich habe es gerade ausprobiert iPhone Distribution(bis jetzt habe ich nur Developer verwendet). Aber es funktioniert nur bei mir. Befehlszeilenausgabe: Build settings from command line: CODE_SIGNING_IDENTITY = iPhone Distribution DEVELOPMENT_TEAM = MY_TEAM_IDKönnen Sie den tatsächlich verwendeten Befehl einfügen (natürlich können Sie die Team-ID oder andere private Dinge verschleiern).
d4Rk
Wenn ich es versuche CODE_SIGNING_IDENTITY= 'iPhone Distribution', kann ich dieselbe Ausgabe sehen, die Sie sehen, aber wenn Sie die vollständige Ausgabe des Build-Protokolls überprüfen und nach der CodeSignPhase Signing Identity: "iPhone Developer:....suchen, die tatsächlich verwendet wird (versuchen Sie, die Ausgabe des xcodebuild-Terminals mit zu speichern > build.log). Wenn Sie also nicht genau mit dem Identitätsnamen für die Codesignatur übereinstimmen, wird weiterhin die Entwicklung verwendet. Wenn Sie mit Ihrem Code Signing Identity Name ( CODE_SIGNING_IDENTITY= 'iPhone Distribution: My Company Name')
übereinstimmen,
2
Und ich fürchte, Sie können derzeit nicht mit einem Tool zwischen automatischer und manueller Signatur wechseln. Ich nehme an, es funktionieren konnte , wenn Sie einen Weg zu bearbeiten finden project.pbxprojDatei und fügen Sie ProvisioningStyle = Manual;in TargetAttributesIhrem Ziel. Dies scheint jedoch schwierig zu sein, und die manuelle Verwaltung der Zertifikate und Bereitstellungsprofile scheint vorerst ein direkterer Ansatz zu sein, wenn Sie auf der CI-Umgebung aufbauen möchten.
Thelvis
37

Nachdem ich einige Optionen ausprobiert hatte, waren dies die Lösungen, die ich auf meinem CI-Server verwenden konnte:

  • Fügen Sie das Entwicklerzertifikat und den privaten Schlüssel sowie die automatisch generierten Bereitstellungsprofile in die CI-Umgebung ein:

Die Verwendung von Automatic signingerzwingt die Verwendung eines DeveloperZertifikats und auto-generated provisioning profiles. Eine Möglichkeit besteht darin, Ihr Entwicklungszertifikat und Ihren privaten Schlüssel (Anwendung -> Dienstprogramme -> Schlüsselbundzugriff) sowie die automatisch generierten Bereitstellungsprofile auf den CI-Computer zu exportieren. Eine Möglichkeit, die automatisch generierten Bereitstellungsprofile zu finden, besteht darin, zu navigieren ~/Library/MobileDevice/Provisioning\ Profiles/, alle Dateien in einen Sicherungsordner zu verschieben, Xcode zu öffnen und das Projekt zu archivieren. Xcode erstellt automatisch generierte Entwicklungsbereitstellungsprofile und kopiert sie in den Provisioning ProfilesOrdner.

xcodebuild archive ...erstellt ein .xcarchivesigniertes für Development. xcodebuild -exportArchive ...kann dann den Build für zurücktretenDistribution

  • Ersetzen Sie "Automatisch" durch "Manuell", wenn Sie auf einer CI-Umgebung aufbauen

Vor dem Aufruf xcodebuildeine Abhilfe ist alle Instanzen ersetzen ProvisioningStyle = Automaticmit ProvisioningStyle = Manualin der Projektdatei. sedkann für eine einfache Suche nach einem Ersatz in der pbxprojDatei verwendet werden:

sed -i '' 's/ProvisioningStyle = Automatic;/ProvisioningStyle = Manual;/' <ProjectName>.xcodeproj/project.pbxproj

@thelvis hat auch ein Ruby-Skript erstellt , um dies mit dem xcodeprojEdelstein zu tun . Das Skript gibt Ihnen eine bessere Kontrolle darüber, was geändert wird.

xcodebuildverwendet dann die CODE_SIGN_IDENTITYim Projekt festgelegte Codesignaturidentität ( PROVISIONING_PROFILE_SPECIFIER) sowie die Bereitstellungsprofile ( ). Diese Einstellungen können auch als Parameter für bereitgestellt werden xcodebuildund überschreiben die im Projekt festgelegte Codesignaturidentität und / oder das Bereitstellungsprofil.

EDIT: mit Xcode 9, xcodebuildhat einen neuen Build - Einstellungen Parameter CODE_SIGN_STYLEzwischen auszuwählen Automaticund Manualso gibt es keine Notwendigkeit Instanzen der automatischen zum Suchen und Ersetzen mit manuellen in der Projektdatei, weitere Informationen in der WWDC 2017 Session 403 Was für Xcode und Xcode Server in Signing Neuen

  • Wechseln Sie zur manuellen Signatur

Die manuelle Signatur bietet vollständige Kontrolle über die verwendeten Codesignaturidentitäten und Bereitstellungsprofile. Es ist wahrscheinlich die sauberste Lösung, aber mit dem Nachteil, alle Vorteile der automatischen Signatur zu verlieren.

Um mehr über das Signieren von Code mit Xcode 8 zu erfahren, empfehle ich diesen Artikel sowie die WWDC2016-Sitzung 401 - Was ist neu beim Signieren von Xcode- Apps ?

Pablobart
quelle
Nach dem Deaktivieren der manuellen Signatur für alle meine Ziele treten immer noch Probleme auf. Der Fehler in der Jenkins-Konsolenausgabe lautet: ### Codesigning '' mit 'iPhone Distribution' + / usr / bin / Codesign --force --preserve-metadata = Kennung, Berechtigungen, Ressourcenregeln - iPhone-Verteilung signieren. --resource-rules = / var / folders / 9v /.../ Payload / YourApp.app / ResourceRules.plist --entitlements /var/folders/9v/.../entitlements_plistHBx8AyjS / var / folders / 9v / .. ./Payload/YourApp.app Programm / usr / bin / Codesign zurückgegeben 1: [Warnung: Verwendung von --preserve-Metadaten mit der Option "Ressourcenregeln" (veraltet in Mac OS X> = 10.10)!
C0D3
Wenn Sie verwenden, die AutomaticSie nicht iPhone Distributionzum Erstellen verwenden können, müssen Sie eine der oben genannten Optionen
ausführen
Tut mir leid, dass ich das falsch geschrieben habe, ich meinte nach dem Ausschalten der automatischen Signatur
C0D3
Ihr Problem scheint nicht mit der Neuunterzeichnung zu tun zu haben , einer schnellen Google-Suche, die mit dieser Website verknüpft ist und Ihnen möglicherweise helfen kann, jayway.com/2015/05/21/fixing-your-ios-build-scripts Auch seit Xcode 7, using xcrun PackageApplicationist veraltet, und Sie sollten xcodebuild -exportArchivestattdessen verwenden
pablobart
1
PROVISIONING_PROFILE_SPECIFIERkann nicht verwendet werden, wenn Sie zu Manual Provisioning wechseln ...
Wolffan
2

Ich denke über eine andere Option nach, die ich hier noch nicht erwähnt habe. Richten Sie zwei identische Ziele ein, die sich nur in ihren Signatureinstellungen unterscheiden.

  • Development Target verwendet die automatische Signatur, um all diese Vorteile zu nutzen, wenn neue Geräte / Entwickler hinzugefügt werden
  • CI Target verwendet die manuelle Signatur

Nachteil ist, dass Sie zwei identische Ziele verwalten müssten. Der Vorteil ist, dass Sie die Vorteile der automatischen Signatur für die Entwicklung nutzen und keine potenziell spröden Skripte verwalten müssen, die Ihr Projekt kurz vor der Erstellungszeit ändern.

Paul Buchanan
quelle
2

Wenn Sie Xcode 8.x und Jenkins für CI verwenden. Dann würden Sie wahrscheinlich Probleme mit "Das Signieren für" YourProjectName "erfordert ein Entwicklungsteam. Wählen Sie im Projekteditor ein Entwicklungsteam aus.

Für den Produkttyp 'Anwendung' im SDK 'iOS 10.1' ist eine Codesignatur erforderlich. ** BUILD FAILED ** beim Ausführen des Jobs.

Was ist die Lösung?.

Lösung ist:

  1. Setzen Sie das Bereitstellungsprofil in den Xcode-Projekterstellungseinstellungen auf Keine.

  2. Erstellen Sie in Jenkins eine Ausführungsshell vor der Xcode-Einstellung und schreiben Sie den folgenden Befehl

    sed -i '' 's/ProvisioningStyle = Automatic;/ProvisioningStyle = Manual;/' ProjectName.xcodeproj/project.pbxproj 
    

    Denken Sie daran: Behalten Sie diese Ausführungsshell vor den Xcode-Einstellungen im Abschnitt "Erstellen" von Jenkins bei.

Das funktioniert.

Ajeet Sharma
quelle
1

Für mich hat nichts funktioniert. Ich habe mein Problem gelöst, indem ich eine Datei in der Xcode-App geändert habe, die auf Ihrem Mac Mini (CI-Server mit Jenkins) installiert ist, wie in diesem Link gezeigt:
https://www.jayway.com/2015/05/21/fixing-your-ios -build-scripts /
Zusätzlich habe ich die automatische Signatur von Xcode deaktiviert .

Alles erledigt! Endlich funktioniert!

Marcelo dos Santos
quelle
In Ihrem Fall, wo ist Ihr Jenkins-Server? meins ist auf AWS Instanz Ubuntu und Mac Laptop als Slave
Ashish Karpe
0

Ich habe festgestellt, dass mein Unity-Build meinem XCode-Projekt niemals einen ProvisioningStyle-Schlüssel hinzugefügt hat. Ich habe dann eine Möglichkeit gefunden, den ProvisioningStyle mithilfe eines Build-Skripts "PostProcessBuild" manuell hinzuzufügen. dh eine Codeeinheit, die aufgerufen wird, nachdem das IOS XCode-Projekt von Unity erstellt wurde.

Zuerst habe ich mir angesehen, wie die Datei project.pbxproj aussehen sollte - wenn sie auf Manuelle Bereitstellung eingestellt ist:

/* Begin PBXDictionary section */
    29B97313FDCFA39411CA2CEA /* Project object */ = {
        isa = PBXProject;
        attributes = {
            TargetAttributes = {
                1D6058900D05DD3D006BFB54 /* Unity-iPhone */ = {
                    ProvisioningStyle = Manual;
                };
                5623C57217FDCB0800090B9E /* Unity-iPhone Tests */ = {
                    TestTargetID = 1D6058900D05DD3D006BFB54 /* Unity-iPhone     */;
                };
            };
        };

Dann habe ich meinen Code erstellt, um die "Struktur" der oben gezeigten Datei zu replizieren. (Verwenden des hier gefundenen XCodeEditor-Projekts: XCodeEditor )

[PostProcessBuild]
public static void OnPostProcessBuild(BuildTarget target, string path)
{
    // Create a new project object from build target
    XCProject project = new XCProject(path);

    if (target == BuildTarget.iOS)
    {
        //Add Manual ProvisioningStyle - this is to force manual signing of the XCode project
        bool provisioningSuccess = AddProvisioningStyle(project, "Manual");

        if (provisioningSuccess)
            project.Save();
    }
}

private static bool AddProvisioningStyle(XCProject project, string style)
{
    var pbxProject = project.project;

    var attr = pbxProject.data["attributes"] as PBXDictionary;
    var targetAttributes = attr["TargetAttributes"] as PBXDictionary;

    var testTargetIDGuid = FindValue(targetAttributes, "TestTargetID");

    if (!string.IsNullOrEmpty(testTargetIDGuid))
    {
        var settings = new PBXDictionary();
        //here we set the ProvisioningStyle value
        settings.Add("ProvisioningStyle", style);

        targetAttributes.Add(testTargetIDGuid, settings);

        var masterTest = FindValue(targetAttributes, "ProvisioningStyle");

        if (masterTest == style)
        {
            return true;
        }
    }

    return false;
}

private static string FindValue(PBXDictionary targetAttributes, string key)
{
    foreach (var item in targetAttributes)
    {
        var ma = item.Value as PBXDictionary;

        foreach (var di in ma)
        {
            var lookKey = di.Key;

            if (lookKey == key)
            {
                return di.Value.ToString();
            }
        }
    }

    return "";
}
UberGeoff
quelle
-1

Es gibt ein Tool namens Fastlane, das die Verwendung von xcodebuild erheblich vereinfacht und beibehalten wird . Dies bedeutet, dass neue Updates weiterhin Unterstützung für Änderungen an xcode bieten. Es macht es viel einfacher, Skripte und Konfigurationen für das Erstellen und Codesignieren Ihrer App unter vielen anderen unterstützten Xcode-Automatisierungstools zu erstellen. Ich würde empfehlen, einen Blick darauf zu werfen.

letzter Link
quelle
3
fastlaneund jedes andere Tool, das behauptet, all diese Komplexität zu automatisieren, hinterlässt eine Black Box, die Sie nicht verstehen. Sie funktionieren einwandfrei, bis sie kaputt gehen. Dann müssen Sie herausfinden, wie sowohl die Codesignatur- als auch die Fastlane-Prozesse funktionieren.
Alfwatt
Jeder, der zwei Sekunden lang sucht, kennt sich mit Fastlane, Match und Fitnessstudio aus. Dies sind äußerst komplizierte Lösungen, die viele seiner eigenen Probleme mit sich bringen. Meine Erfahrung mit Fastlane und Match ist, dass Ihr Projekt auf manuelles Signieren vor Ort eingestellt werden muss, was in vielen Fällen nicht akzeptabel ist.
Krähe