Engineering-Praxis

iOS-Signaturfehler durch erweiterte Attribute diagnostizieren

iOS-Signaturfehler durch erweiterte Attribute diagnostizieren

Lokal lässt sich das Archiv erfolgreich erstellen, auf einem Cloud-Mac schlägt der Vorgang jedoch beim Signieren mit resource fork, Finder information, or similar detritus not allowed fehl. Ursache ist in der Regel weder ein abgelaufenes Zertifikat noch ein ungültiges Provisioning Profile. Meist enthält ein Bild, ein Skriptartefakt oder ein kopiertes Verzeichnis erweiterte macOS-Attribute. Diese gelangen beim Kopieren der Ressourcen in das App-Bundle und fallen erst bei der strikten Prüfung durch das Signaturwerkzeug auf.

Zuerst die fehlerhafte Ebene bestimmen

Erstellen Sie nicht sofort neue Zertifikate, nur weil die Meldung auf einen Signaturfehler hinweist. Suchen Sie zunächst im vollständigen Build-Protokoll nach dem ersten codesign-Fehler und halten Sie fest, ob die Haupt-App, ein Framework, eine Erweiterung oder ein Ressourcen-Bundle betroffen ist. Werden im Protokoll ausdrücklich FinderInfo, ResourceFork oder detritus genannt, sollte sich die weitere Analyse auf die Dateimetadaten konzentrieren.

Erweiterte Attribute gelangen häufig über folgende Quellen in den Build:

  • Bilder, Schriftarten oder Archive, die mit einem grafischen Dateimanager in das Repository kopiert wurden;
  • Ressourcen, die in einem freigegebenen Verzeichnis entpackt und anschließend direkt eingecheckt wurden;
  • vorab erzeugte Verzeichnisse, die ein Build-Skript mit cp -R verschiebt;
  • lokale Artefakte, die nicht versioniert sind, aber lange im Arbeitsverzeichnis verbleiben;
  • Abhängigkeiten, deren Dateimetadaten bei der Wiederherstellung aus einem Cache mitgeschrieben werden.

Durch das Löschen von DerivedData werden lediglich die Build-Ausgaben entfernt. Befindet sich die Verunreinigung im Quellmaterial oder in externen Eingaben, tritt der Fehler beim nächsten Build zuverlässig erneut auf.

Speichern Sie vor der Bereinigung den fehlgeschlagenen Befehl, den Zielpfad und das Protokoll. Andernfalls lässt sich die tatsächliche Quelle selbst dann nicht mehr bestimmen, wenn der Build anschließend zufällig wieder funktioniert.

Eine schreibgeschützte Scan-Basis schaffen

Repository-Eingaben prüfen

xattr -lr listet Pfade und ihre Attribute rekursiv auf. Schreiben Sie die Ergebnisse zunächst in ein Protokoll, anstatt Attribute bereits während des Scans zu löschen:

set -euo pipefail

ROOT="${SRCROOT:-$PWD}"
REPORT="${TMPDIR:-/tmp}/ios-xattr-source.log"

xattr -lr "$ROOT" > "$REPORT" 2>&1 || true

grep -E \
  'com\.apple\.(FinderInfo|ResourceFork)' \
  "$REPORT" || true

Bei großen Repositorys können .git, DerivedData und Abhängigkeits-Caches ausgeschlossen werden. Prüfen Sie anschließend gezielt die Verzeichnisse, die tatsächlich in das Paket eingehen. Entscheidend ist nicht die Anzahl der Treffer, sondern die Antwort auf drei Fragen: An welcher Datei hängt das Attribut, wodurch wurde diese Datei erzeugt und über welche Build Phase gelangt sie in das Bundle?

Fundstelle Zuerst prüfen Vorgehensweise
Assets oder Ressourcenverzeichnis Importmethode, Entpackprogramm Quelldatei korrigieren
Skript-Ausgabeverzeichnis Parameter von cp und ditto Staging-Verzeichnis neu erstellen
DerivedData Cache-Wiederherstellung, alte Artefakte Cache leeren und Fehler reproduzieren
Innerhalb eines Frameworks Download- und Entpackschritte Neu beziehen und anschließend prüfen

Archiv-Bundle prüfen

Wurde bereits ein Archiv erstellt, lässt sich durch einen direkten Scan der .app feststellen, ob die unerwünschten Attribute in das auszuliefernde Artefakt gelangt sind:

ARCHIVE_PATH="$PWD/build/App.xcarchive"
APP_PATH="$ARCHIVE_PATH/Products/Applications/App.app"
REPORT="$PWD/build/xattr-app.log"

test -d "$APP_PATH"
xattr -lr "$APP_PATH" > "$REPORT" 2>&1 || true

if grep -Eq 'com\.apple\.(FinderInfo|ResourceFork)' "$REPORT"; then
  echo "forbidden extended attributes found"
  exit 1
fi

Hier wird ein fester Beispielpfad verwendet. In einer echten Pipeline sollte die einzige .app aus dem Archivverzeichnis ermittelt werden. Wird keine oder werden mehrere mögliche Apps gefunden, muss der Vorgang sofort fehlschlagen, damit nicht versehentlich das falsche Bundle geprüft wird.

Bei der Bereinigung die Nachvollziehbarkeit wahren

Es ist nicht empfehlenswert, sofort xattr -cr auf das gesamte Arbeitsverzeichnis anzuwenden. Der Befehl entfernt sämtliche erweiterten Attribute, vergrößert damit unnötig den Änderungsumfang und kann Fehler in Download-, Entpack- oder Cache-Schritten verdecken. Robuster ist es, ausschließlich die beiden Attributtypen zu löschen, die nachweislich die Signatur beeinträchtigen:

TARGET="$PWD/StagingPayload"

find "$TARGET" -print0 |
while IFS= read -r -d '' item; do
  xattr -d com.apple.FinderInfo "$item" 2>/dev/null || true
  xattr -d com.apple.ResourceFork "$item" 2>/dev/null || true
done

TARGET sollte möglichst auf eine temporäre Staging-Kopie und nicht auf das ursprüngliche Arbeitsverzeichnis des Entwicklers verweisen. Führen Sie nach der Bereinigung einen erneuten Scan durch. Gibt es weiterhin Treffer, muss der Build abgebrochen werden. Verwenden Sie || true nicht für die abschließende Abnahmebedingung.

Stammen die Attribute aus einem Archiv, muss die Prüfung nach dem Entpacken korrigiert werden. Liegt die Ursache in einem Build-Skript, sollte dieses bei jedem Lauf ein leeres Staging-Verzeichnis erstellen und anschließend nur eine ausdrücklich definierte Dateiliste kopieren. Ein zusätzlicher rekursiver Bereinigungsbefehl am Ende lässt die eigentliche Verunreinigung bestehen und führt dazu, dass sie in anderen Jobs erneut auftritt.

Die Prüfung in den Archivierungsprozess integrieren

Eingaben vor dem Build prüfen

Das Gate vor dem Build muss nur die Ressourcenverzeichnisse scannen, die in die App gelangen, nicht das gesamte Home-Verzeichnis. Bei einem Treffer sollte es den relativen Pfad und den Attributnamen ausgeben und mit einem Status ungleich null enden. So schlägt der Prozess bereits vor Beginn der zeitaufwendigen Archivierung fehl, und kürzlich vorgenommene Änderungen lassen sich leichter zuordnen.

Das Prüfskript sollte versioniert und in einer fest definierten Umgebung ausgeführt werden:

  1. Das Stammverzeichnis des Repositorys anhand des Speicherorts des Skripts bestimmen;
  2. für Pfade mit Leerzeichen Nullzeichen als Trennzeichen verwenden;
  3. den Bericht in ein eigenes Artefaktverzeichnis des jeweiligen Jobs schreiben;
  4. während des Scans keine Dateien verändern;
  5. bei einem nicht vorhandenen Zielverzeichnis sofort einen Fehler melden.

Signatur nach der Archivierung verifizieren

Nachdem der Scan auf erweiterte Attribute erfolgreich war, sollte das Archiv zusätzlich mit dem Signaturwerkzeug des Systems geprüft werden:

APP_PATH="$PWD/build/App.xcarchive/Products/Applications/App.app"

codesign --verify \
  --strict \
  --verbose=2 \
  "$APP_PATH"

Enthält die App eigenständige Frameworks oder Erweiterungen, müssen auch diese verschachtelten Codeobjekte einzeln durchlaufen und geprüft werden. Aus einer erfolgreichen Prüfung des Haupt-Bundles darf nicht geschlossen werden, dass sämtliche internen Komponenten ebenfalls fehlerfrei sind. Speichern Sie das Prüfprotokoll, den Archivpfad und die Commit-ID des Quellcodes zusammen. Dadurch lassen sich Fälle unterscheiden, in denen der Quellcode identisch ist, aber unterschiedliche Eingabe-Caches verwendet wurden.

Die Analyse mit einer Abnahmecheckliste abschließen

Eine belastbare Korrektur muss alle folgenden Bedingungen erfüllen:

  • Die Scan-Ergebnisse für den Quellcode und die externen Eingaben wurden archiviert;
  • der Erzeugungs- oder Kopierpfad der verunreinigten Datei wurde bestimmt;
  • die Bereinigung betrifft nur ausdrücklich festgelegte Attribute oder eine temporäre Staging-Kopie;
  • nach dem Löschen von DerivedData und der zugehörigen Caches lässt sich erneut ein Archiv erstellen;
  • das endgültige App-Bundle enthält weder FinderInfo noch ResourceFork;
  • die Haupt-App und alle verschachtelten Codeobjekte bestehen die strikte Signaturprüfung;
  • derselbe Commit besteht die Prüfung wiederholt in einem vollständig neuen Arbeitsverzeichnis.

Fehler durch erweiterte Attribute sind nicht deshalb schwer zu analysieren, weil die Befehle kompliziert wären. Das Problem erstreckt sich vielmehr über vier Ebenen: Quellcode, Dateisystemmetadaten, Caches und Signatur. Wird das Verfahren „zuerst protokollieren, dann lokalisieren, anschließend bereinigen und abschließend prüfen“ als festes Gate etabliert, müssen Verantwortliche nicht mehr manuell auf einem Knoten provisorische Korrekturen vornehmen. Außerdem gehen die für die Analyse erforderlichen Hinweise beim Wechsel des Arbeitsverzeichnisses nicht verloren.

Häufig gestellte Fragen

Warum bleibt der Signaturfehler nach dem Löschen von DerivedData bestehen?

Befinden sich FinderInfo oder ResourceFork in Quellressourcen, Downloads oder von Skripten kopierten Ordnern, übernimmt jeder neue Build die Attribute erneut. Prüfen Sie zuerst sämtliche Eingaben.

Sollte xattr -cr über das gesamte Repository laufen?

Nein. Erfassen Sie zuerst alle Treffer und entfernen Sie nur FinderInfo und ResourceFork. Eine vollständige rekursive Bereinigung gehört ausschließlich in eine entbehrliche Arbeitskopie.

Wie wird das bereinigte Archiv abgenommen?

Scannen Sie das App-Bundle erneut und führen Sie danach codesign --verify --strict aus. Prüfprotokoll und Prüfsumme des Archivs sollten gemeinsam gespeichert werden.

NowMini M4

Die nächste Aufgabe auf einem exklusiven physischen Knoten ausführen

Cloud-Mac mit M4, 16 GB RAM und 256 GB SSD – wählen Sie je nach Aufgabenzeitraum einen Knoten in Singapur, Tokio, Seoul oder Hongkong.

Cloud-Mac jetzt mieten