APK-Releases veröffentlichen
Laden Sie ein signiertes Android-APK direkt aus Ihrer Release-Pipeline hoch und verfolgen Sie es, bis es in der Bibliothek Ihres Unternehmens erscheint.
So funktioniert die Veröffentlichung
Erstellen Sie mit der Nomid API eine mehrteilige Upload-Sitzung, senden Sie die APK-Bytes über kurzlebige URLs für die einzelnen Teile direkt an S3, schließen Sie die Sitzung ab und fragen Sie per Polling das endgültige Verarbeitungsergebnis ab.
LIBRARY_MANAGE deckt jetzt APK-Uploads und die App-Verwaltung ab, einschließlich Lesen, Bearbeiten, Ausblenden und Wiederherstellen von Apps und Releases. Öffentliche APIs für Dateien, Kontakte und andere Bibliotheksressourcen sind weiterhin nicht verfügbar. Die Berechtigung umfasst weder die Zuweisung von Richtlinien noch Gerätebefehle, die Bereitstellung oder die Kontoverwaltung.
Apps der Unternehmensbibliothek lesen und verwalten sowie signierte APK-Releases veröffentlichen. LIBRARY_MANAGE ist eine sensible, unternehmensweite Berechtigung für APK-Uploads und die App-Verwaltung. Sie umfasst weder die Zuweisung von Richtlinien noch Gerätebefehle, die Bereitstellung oder Kontovorgänge.
Eine abgeschlossene Veröffentlichung legt das Release in der Bibliothek ab und kann die bestehende Verteilung für Richtlinien auslösen, die die zugehörige App und den Track verwenden. Sie bestätigt nicht, dass ein Gerät das Release installiert hat.
Bevor Sie beginnen
- Erstellen Sie einen eigenen API-Schlüssel mit LIBRARY_MANAGE. Ein Portal-Benutzer, der diese Berechtigung erteilt, benötigt API_KEY_MANAGE, einen uneingeschränkten Richtlinienbereich des Unternehmens, LIBRARY_VIEW und LIBRARY_EDIT. Die sensible Berechtigung ist standardmäßig nicht ausgewählt; bestehende Schlüssel erhalten sie nicht automatisch.
- Erteilen Sie die Berechtigung nur vertrauenswürdiger Automatisierung, die diese unternehmensweiten Bibliotheksvorgänge benötigt. LIBRARY_MANAGE erlaubt APK-Uploads und die App-Verwaltung, einschließlich des Zugriffs auf Upload-Sitzungen, die von anderen autorisierten Unternehmensschlüsseln oder Benutzern gestartet wurden. Bewahren Sie den Schlüssel im Secret-Speicher Ihrer CI auf und rotieren oder widerrufen Sie ihn, wenn sich der Zugriff ändert.
- Verwenden Sie für den Beispiel-Uploader Python 3.11 oder neuer. Erstellen und signieren Sie das APK vor dem Upload mit der vorgesehenen Signaturidentität und einem passenden Android-Versionscode. Die API signiert keine APKs und veröffentlicht nicht in Google Play.
- Senden Sie X-API-Key an die Nomid API. Der validierte Schlüssel bestimmt das Unternehmen; Anfragen haben keinen Mandanten- oder Unternehmensparameter. Für die APK-Veröffentlichung ist weder DEVICES_READ noch POLICIES_READ erforderlich.
Endpunkte
https://api.nomid.tech/emm/api/v1
Alle acht untenstehenden Routen erfordern X-API-Key mit LIBRARY_MANAGE; eine Upload-Sitzung gehört zum Unternehmen des Schlüssels.
| Methode | Endpunkt | Beschreibung |
|---|---|---|
| POST | /library/apps/uploads/check | Prüft die Zulässigkeit, doppelte Inhalte und eine vorhandene fortsetzbare Sitzung. Ein Duplikat ist nur ein Hinweis. |
| POST | /library/apps/uploads/start | Startet einen Upload und liefert sessionId, partSize und expiresAt. |
| POST | /library/apps/uploads/parts/sign | Liefert eine kurzlebige direkte S3-PUT-URL und requiredHeaders für ein Teil. |
| GET | /library/apps/uploads/parts/{sessionId} | Listet wiederverwendbare hochgeladene Teile und ihre exakten ETags für dieselbe Sitzung auf. |
| POST | /library/apps/uploads/complete | Übermittelt die geordnete Teileliste und optionale tracks, um das APK zusammenzusetzen und zu verarbeiten. |
| GET | /library/apps/uploads/status/{sessionId} | Fragt die Sitzung per Polling ab, bis status completed oder failed ist. |
| DELETE | /library/apps/uploads/abort/{sessionId} | Bricht eine unfertige Sitzung ab; Sitzungen, die verarbeitet werden oder abgeschlossen sind, lassen sich nicht abbrechen. |
| GET | /library/apps/{packageName}/versions/{versionCode}/check-report | Liest den neuesten Upload-Prüfbericht eines Releases. Erforderlich sind packageName und versionCode des Releases sowie seine Umgebung, sofern sie nicht leer ist. |
Upload-Ablauf
- POST /check mit filename, der tatsächlichen positiven Bytegröße, dem zulässigen mime und dem SHA-256 des APK. Prüfen Sie allowed und reason; duplicateOf und existingSessionId können vorhanden sein.
- POST /start mit denselben Feldern. Speichern Sie die zurückgegebenen Werte sessionId und partSize sicher, damit dieser Lauf bei einer Unterbrechung fortgesetzt werden kann.
- Senden Sie für jedes fehlende Teil POST /parts/sign mit sessionId und einer partNumber von 1 bis 10000.
- Teilen Sie die Datei in aufeinanderfolgende Blöcke von je partSize Bytes; nur der letzte Block darf kürzer sein. Senden Sie jeden Block per PUT an seine signierte URL mit requiredHeaders und behalten Sie den Antwort-Header ETag genau so, wie er zurückgegeben wird.
- POST /complete mit sessionId, jedem Paar aus partNumber/etag und optionalen tracks. Der Abschluss startet die APK-Verarbeitung im Hintergrund; die unmittelbare Antwort kann weiterhin processing lauten.
- Rufen Sie den Status-Endpunkt mit der Sitzungs-ID per GET ab, bis der kleingeschriebene status completed oder failed ist. Abgeschlossene Antworten enthalten app; fehlgeschlagene Antworten enthalten eine errorMessage. Andere Zustände sind kein Veröffentlichungserfolg.
Die Größe muss größer als null sein und innerhalb des konfigurierten Upload-Limits liegen. mime ist application/vnd.android.package-archive oder application/octet-stream; sha256 ist der kleingeschriebene hexadezimale Digest des APK mit 64 Zeichen, berechnet über die APK-Bytes. Die Ablaufzeiten von Sitzung und signierter URL gelten.
Die signierte URL gilt für S3, nicht für die Nomid API: Senden Sie mit dem PUT nur requiredHeaders, niemals X-API-Key. Protokollieren Sie die signierte URL nicht. Wenn sie abgelaufen ist, signieren Sie dieses Teil erneut.
Beispiele für Anfragen und Antworten
Diese Beispiele zeigen Feldnamen und kleingeschriebene status-Werte. Kennungen, Digest, Zeit, Teilgröße, ETags und URL sind beispielhaft; verwenden Sie die Werte, die für Ihre eigene Sitzung zurückgegeben werden.
Anfrage POST /check oder /start
{
"filename": "app-release.apk",
"size": 33554432,
"mime": "application/vnd.android.package-archive",
"sha256": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
} Antwort POST /check (zulässig)
{
"allowed": true,
"recommendedPartSize": 16777216
} Antwort POST /start
{
"sessionId": "123e4567-e89b-12d3-a456-426614174000",
"partSize": 16777216,
"expiresAt": "2026-10-28T12:00:00Z"
} Anfrage POST /parts/sign
{
"sessionId": "123e4567-e89b-12d3-a456-426614174000",
"partNumber": 1
} Antwort POST /parts/sign
{
"url": "https://<presigned-part-url>",
"requiredHeaders": {}
} Antwort GET hochgeladene Teile
{
"status": "uploading",
"partSize": 16777216,
"parts": [{ "partNumber": 1, "etag": "\"example-etag\"" }]
} Anfrage POST /complete
{
"sessionId": "123e4567-e89b-12d3-a456-426614174000",
"parts": [
{ "partNumber": 1, "etag": "\"example-etag-1\"" },
{ "partNumber": 2, "etag": "\"example-etag-2\"" }
],
"tracks": ["prod"]
} Antwort POST /complete (processing)
{
"status": "processing",
"sessionId": "123e4567-e89b-12d3-a456-426614174000"
} requiredHeaders kann Header enthalten, die für die S3-Signatur erforderlich sind. Wenden Sie die zurückgegebene Map exakt an, einschließlich aller Werte, und erfassen Sie den Antwort-Header ETag jedes erfolgreichen PUT.
Upload-Prüfungen
Jeder Upload wird geprüft, bevor sein Release erstellt wird: die Signatur und das Manifest des APK, frühere Releases desselben Pakets in Ihrem Unternehmen sowie die Geräte Ihres Unternehmens (ihre Android-API-Level und die darauf installierten Apps mit ihren Signaturzertifikaten). Das Ergebnis ist ein Prüfbericht, den Sie über die API lesen können.
Die Prüfungen melden Befunde. Befunde werden gespeichert und zurückgegeben, und der Upload wird dennoch abgeschlossen; nur VERSION_CODE_CONFLICT weist einen Upload ab. Ein Befund mit dem Schweregrad ERROR beschreibt ein APK, dessen Installation oder Update Geräte möglicherweise verweigern; ein WARNING beschreibt ein APK, das sich installieren lässt, aber ein erwähnenswertes Risiko birgt. Keines von beiden stoppt den Upload.
Ein abgeschlossener Upload enthält checkReport in der Antwort von GET /status sowie in der Antwort von POST /complete, wenn diese eine beendete Sitzung zurückgibt (zum Beispiel bei einem wiederholten Aufruf). Ein von einer Prüfung abgewiesener Upload hat den status failed und enthält ebenfalls checkReport. Der Bericht fehlt, solange der Upload verarbeitet wird, und wenn der Upload aus einem anderen Grund fehlgeschlagen ist. Die errorMessage eines fehlgeschlagenen Uploads ist allgemein gehalten; lesen Sie daher die Befunde mit blocking true in checkReport, um zu erfahren, warum eine Prüfung ihn abgewiesen hat.
Releases, die von den Versions-Routen der Bibliothek zurückgegeben werden (die Versionsliste und eine einzelne Version, dokumentiert im Leitfaden zu Bibliotheks-Apps), enthalten checkSummary: den status des neuesten Berichts, errorCount (ERROR-Befunde) und warningCount (WARNING-Befunde). Für Releases, die vor Einführung der Prüfungen hochgeladen wurden, ist der Wert null. Die Route check-report in der obigen Tabelle liefert den vollständigen Bericht eines Releases in derselben Form wie checkReport und antwortet mit 404, wenn das Release keinen hat. Wie die Upload-Routen erfordert sie X-API-Key mit LIBRARY_MANAGE.
Berichtsfelder
- status: PASSED (keine Befunde), WARNINGS (das Release wurde erstellt und hat Befunde, einschließlich ERROR-Befunden, die nicht blockiert haben) oder BLOCKED (ein Befund hat den Upload gestoppt und es wurde kein Release erstellt).
- findings: ERROR-Befunde zuerst. Jeder hat code, severity (ERROR oder WARNING), params, blocking und affectedDeviceCount, wenn sich der Befund auf Geräte bezieht. blocking ist nur bei einem Befund true, der den Upload gestoppt hat.
- params: Werte, die aus dem hochgeladenen APK oder aus den eigenen Releases Ihres Unternehmens gelesen werden, etwa Versionen, SDK-Level, Namen von Berechtigungen und ABIs sowie Zertifikat-Fingerprints. Die Schlüssel hängen vom code ab.
- affectedDeviceCount: auf wie viele Geräte Ihres Unternehmens der Befund zutrifft. Bei MIN_SDK_ABOVE_FLEET und TARGET_SDK_TOO_LOW ist params.scope gleich INSTALLED, wenn die Geräte gezählt werden, auf denen das Paket installiert ist, oder COMPANY, wenn kein Gerät es installiert hat und alle Geräte des Unternehmens gezählt werden.
- checkerVersion kennzeichnet den Satz von Prüfungen, der den Bericht erzeugt hat. createdAt ist der Zeitpunkt, zu dem der Bericht gespeichert wurde, in UTC.
Prüfcodes
Die Codes sind stabil: Neue können hinzukommen, bestehende werden nicht umbenannt. Lesen Sie severity und blocking aus jedem Befund und nicht aus dieser Tabelle.
| Code | Schweregrad | Bedeutung |
|---|---|---|
| SIGNATURE_INVALID | ERROR | Das APK ist nicht signiert oder seine Signatur lässt sich nicht verifizieren. params.issues listet die gefundenen Probleme auf. |
| SIGNATURE_SCHEME_V1_ONLY | ERROR | Das APK zielt auf Android 11 (API 30) oder höher, hat aber nur eine v1-Signatur (JAR), die Android 11 und neuer ablehnen. Signieren Sie es mit APK Signature Scheme v2 oder höher. params.targetSdk. |
| SIGNING_KEY_CHANGED | ERROR | Das Signaturzertifikat weicht von dem des vorherigen Releases ab und kein v3-Schlüsselrotationsnachweis verknüpft beide (params.previousVersionCode, previousCertSha256, newCertSha256), oder es weicht von den Zertifikaten ab, die auf affectedDeviceCount Geräten installiert sind (params.installedCertSha1, newCertSha1, als SHA-1-Hex, so wie Geräte es melden). Geräte verweigern das Update einer App auf einen mit einem anderen Schlüssel signierten Build. |
| TEST_ONLY | WARNING | Das Manifest setzt android:testOnly="true", was einen Entwicklungs-Build kennzeichnet. Keine params. |
| VERSION_CODE_CONFLICT | ERROR | Ein Release mit demselben versionCode und derselben Umgebung wurde bereits mit einer anderen Binärdatei hochgeladen. Dies ist der einzige Befund, der einen Upload abweist. params.versionCode. |
| VERSION_DOWNGRADE | WARNING | Der versionCode ist niedriger als bei Ihrem neuesten veröffentlichten Release (params.latestVersionCode) oder niedriger als der auf affectedDeviceCount Geräten installierte (params.installedVersionCode, der höchste installierte). Geräte aktualisieren normalerweise nicht auf einen niedrigeren Versionscode. |
| MIN_SDK_ABOVE_FLEET | WARNING | Das minSdk des APK liegt über dem Android-API-Level von affectedDeviceCount Geräten, die es nicht installieren können. params.minSdk, scope. |
| TARGET_SDK_TOO_LOW | WARNING | Das targetSdk des APK liegt unter 23, und Android 14 und neuer verweigern die Installation. affectedDeviceCount zählt die Geräte im Geltungsbereich, auf denen Android 14 oder neuer läuft. params.targetSdk, minimumTargetSdk, scope. |
| MISSING_ARM64 | WARNING | Das APK enthält native Bibliotheken, aber keine für arm64-v8a. params.abis listet die ABIs auf, die es enthält. |
| DEBUGGABLE | WARNING | Das Manifest setzt android:debuggable="true". Keine params. |
| NEW_DANGEROUS_PERMISSIONS | WARNING | Das APK fordert Laufzeitberechtigungen (gefährliche Berechtigungen) an, die das vorherige Release nicht angefordert hat. params.permissions, previousVersionCode. |
Beispiele für Prüfberichte
Das erste Beispiel ist die GET-Statusantwort eines abgeschlossenen Uploads mit Befunden; andere Felder wie app sind weggelassen. Das zweite ist ein fehlgeschlagener Upload, den eine Prüfung abgewiesen hat. Kennungen, Anzahlen, Fingerprints und Zeiten sind beispielhaft.
Abgeschlossener Upload mit Befunden
{
"status": "completed",
"sessionId": "123e4567-e89b-12d3-a456-426614174000",
"checkReport": {
"status": "WARNINGS",
"findings": [
{
"code": "SIGNING_KEY_CHANGED",
"severity": "ERROR",
"params": {
"installedCertSha1": ["0123456789abcdef0123456789abcdef01234567"],
"newCertSha1": ["89abcdef0123456789abcdef0123456789abcdef"]
},
"affectedDeviceCount": 2,
"blocking": false
},
{
"code": "MIN_SDK_ABOVE_FLEET",
"severity": "WARNING",
"params": { "minSdk": 28, "scope": "INSTALLED" },
"affectedDeviceCount": 3,
"blocking": false
},
{
"code": "MISSING_ARM64",
"severity": "WARNING",
"params": { "abis": ["armeabi-v7a"] },
"blocking": false
}
],
"checkerVersion": "2",
"createdAt": "2026-11-03T09:30:00Z"
}
} Von einer Prüfung abgewiesener Upload
{
"status": "failed",
"sessionId": "123e4567-e89b-12d3-a456-426614174000",
"errorMessage": "Upload processing failed",
"checkReport": {
"status": "BLOCKED",
"findings": [
{
"code": "VERSION_CODE_CONFLICT",
"severity": "ERROR",
"params": { "versionCode": 42 },
"blocking": true
}
],
"checkerVersion": "2",
"createdAt": "2026-11-03T09:30:00Z"
}
} checkSummary bei einem Release in einer Versionsliste
{
"versionCode": 42,
"environment": "",
"status": "PUBLISHED",
"displayName": "Kiosk",
"displayVersion": "1.4.2",
"createdAt": "2026-11-03T09:30:00Z",
"sha256": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
"fileSizeBytes": 33554432,
"tracks": ["prod"],
"checkSummary": { "status": "WARNINGS", "errorCount": 1, "warningCount": 2 }
} Tracks und Wiederholungen
Wenn tracks weggelassen wird, gilt prod. Das erste Release einer neuen App enthält immer prod, auch wenn ein anderer Track angefordert wird. Spätere Releases können explizite Track-Namen mit höchstens 10 Zeichen verwenden. In dieser API gibt es keine Entwurfs- oder Freigabestufe.
Eine übereinstimmende Prüfsumme kann eine vorhandene App/Version identifizieren, weist dieses Release aber nicht dem Track zu, den dieser Lauf angefordert hat. Behandeln Sie ein Duplikat-Ergebnis von /check nicht als Veröffentlichungserfolg für einen neuen Track.
Setzen Sie nur die Sitzungs-ID fort, die in diesem Veröffentlichungslauf gespeichert wurde, mit demselben APK und denselben tracks. Rufen Sie den Endpunkt für hochgeladene Teile mit dieser Sitzungs-ID per GET ab, um Teile wiederzuverwenden. Fragen Sie nach einem unklaren /complete-Ergebnis diese Sitzung per Polling ab, bevor Sie den Abschluss wiederholen. Eine abgebrochene oder abgelaufene Sitzung erfordert einen neuen Upload.
Aus der CI veröffentlichen
Laden Sie auf einem Linux-CI-Runner mit Python 3.11 oder neuer und sha256sum den Python-Standardbibliothek-Uploader herunter und prüfen Sie seine festgelegte Prüfsumme, bevor Sie ihn ausführen. Prüfen und versionieren Sie die verifizierte Kopie in Ihrem Pipeline-Repository für künftige Läufe. Stellen Sie NOMID_API_KEY über die Secret-Umgebungsinjektion Ihrer CI-Plattform bereit. Der Uploader beendet sich bei Fehler oder Zeitüberschreitung mit einem Wert ungleich null.
curl --fail --silent --show-error --output publish_apk.py \
https://www.nomidmdm.com/developers/publish_apk.py &&
printf '%s %s\n' '8d9ba2a4432e6e6db05ba2411bfb6bfa85c85a79d1ce480d97e0014f965f12d2' publish_apk.py | sha256sum --check --status &&
python3 publish_apk.py app-release.apk --track prod Um einen unterbrochenen Lauf fortzusetzen, übergeben Sie die gespeicherte Sitzungs-ID explizit mit demselben APK und denselben tracks:
python3 publish_apk.py app-release.apk --track prod \
--session-id SESSION_ID_FROM_PREVIOUS_RUN Geben Sie den API-Schlüssel weder im Befehl noch im Repository oder in den Logs an; aktivieren Sie kein Shell-Tracing. Halten Sie vorsignierte URLs und ihre erforderlichen Header aus den CI-Logs heraus. Veröffentlichungserfolg und Geräteinstallation sind getrennte Prüfungen.
GitHub Actions: ein APK veröffentlichen, wenn ein Release veröffentlicht wird
Dieser vollständige Workflow lädt ein bereits signiertes APK herunter, das an das auslösende GitHub-Release angehängt ist, verifiziert den Nomid-Uploader und wartet auf die Veröffentlichung in der Bibliothek Ihres Unternehmens. Er verwendet das Release-Asset, nicht ein Actions-Build-Artefakt, und baut oder signiert Ihre App nicht.
- Erstellen Sie einen eigenen Nomid-API-Schlüssel mit LIBRARY_MANAGE. Öffnen Sie in Ihrem GitHub-Repository Settings → Secrets and variables → Actions und fügen Sie ein Repository-Secret mit dem Namen NOMID_API_KEY hinzu, das den Schlüssel enthält. Geräte- oder Richtlinienberechtigungen sind nicht erforderlich.
- Speichern Sie das YAML unten als .github/workflows/publish-to-nomid.yml in Ihrem Repository, bevor Sie das Release-Tag erstellen, damit der getaggte Commit den Workflow enthält. Ändern Sie APK_ASSET_NAME auf den exakten Namen des signierten APK, das Sie an jedes Release anhängen.
- Bauen und signieren Sie das APK in Ihrer bestehenden Pipeline. Hängen Sie es als app-release.apk (oder Ihren konfigurierten Asset-Namen) an ein GitHub-Release im Entwurfsstatus an und veröffentlichen Sie dann das Release. Das Beispiel unterstützt über das integrierte GitHub-Token mit contents: read auch private Repositories. Das APK muss bereits angehängt sein, wenn das Release veröffentlicht wird; andernfalls schlägt der Download-Schritt fehl.
name: Publish APK to Nomid
on:
release:
types: [published]
permissions:
contents: read
concurrency:
group: nomid-apk-${{ github.event.release.id }}
cancel-in-progress: false
jobs:
publish:
runs-on: ubuntu-24.04
timeout-minutes: 30
env:
APK_ASSET_NAME: app-release.apk
NOMID_TRACK: ${{ github.event.release.prerelease && 'beta' || 'prod' }}
steps:
- name: Set up Python
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
with:
python-version: '3.12'
- name: Download the signed APK from this release
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
RELEASE_TAG: ${{ github.event.release.tag_name }}
shell: bash
run: |
set -euo pipefail
gh release download --repo "$GH_REPO" \
--pattern "$APK_ASSET_NAME" --output app-release.apk -- "$RELEASE_TAG"
test -s app-release.apk
- name: Download and verify the Nomid uploader
shell: bash
run: |
set -euo pipefail
curl --fail --silent --show-error --output publish_apk.py \
https://www.nomidmdm.com/developers/publish_apk.py
printf '%s %s\n' '8d9ba2a4432e6e6db05ba2411bfb6bfa85c85a79d1ce480d97e0014f965f12d2' publish_apk.py \
| sha256sum --check --status
- name: Publish to the Nomid company library
env:
NOMID_API_KEY: ${{ secrets.NOMID_API_KEY }}
shell: bash
run: |
set -euo pipefail
if [[ -z "$NOMID_API_KEY" ]]; then
echo "Configure the NOMID_API_KEY repository secret before publishing." >&2
exit 1
fi
python3 publish_apk.py app-release.apk --track "$NOMID_TRACK" --timeout 1200 Stabile Releases werden auf prod veröffentlicht; GitHub-Prereleases auf beta. Bei einer neuen App nimmt Nomid bei der ersten Veröffentlichung immer prod mit auf, auch wenn beta angefordert wird. Ein Prerelease eines neuen Pakets ist daher nicht von prod isoliert. Spätere Releases behalten die explizite Track-Auswahl bei. Wählen Sie Release-Typ und Track, bevor Sie veröffentlichen.
Der Nomid-Schlüssel wird nur dem Veröffentlichungsschritt über dessen Umgebung bereitgestellt. Ein fehlender Schlüssel, ein fehlendes APK, eine abweichende Prüfsumme, eine fehlgeschlagene Veröffentlichung oder eine Zeitüberschreitung bei der Veröffentlichung lässt den Job fehlschlagen. Ein erfolgreicher Job bestätigt die Veröffentlichung im Store, nicht die Installation auf Geräten. Verwenden Sie bei einer Unterbrechung die gespeicherte sessionId mit demselben APK und Track wie oben beschrieben; ein erneuter Lauf des gesamten Workflows startet einen neuen Upload.
Wenn ein anderer Workflow das GitHub-Release mit seinem integrierten GITHUB_TOKEN veröffentlicht, löst GitHub diesen Release-Workflow nicht aus. Führen Sie in diesem Fall den verifizierten Uploader direkt im bestehenden Release-Job aus, nachdem das APK angehängt wurde, oder veröffentlichen Sie das Release mit einem angemessen eingeschränkten GitHub-App-Token oder persönlichen Zugriffstoken. Halten Sie das GH_TOKEN des Download-Schritts getrennt vom Nomid-API-Schlüssel.
GitHub-Dokumentation: einen Workflow aus einem Workflow auslösen
Fehler und Wiederherstellung
- 401: Der Schlüssel fehlt, ist ungültig, abgelaufen oder widerrufen. Prüfen Sie die Secret-Injektion der CI, ohne den Wert auszugeben.
- 403: Dem Schlüssel fehlt LIBRARY_MANAGE. Erstellen Sie einen ordnungsgemäß autorisierten Schlüssel; nicht zugehörige Lese- oder Schreibberechtigungen genügen nicht.
- 404 bei einer Sitzungs-ID, die im Unternehmen des Schlüssels unbekannt ist. Prüfen Sie die ID und den an das Unternehmen gebundenen Schlüssel; wechseln Sie nicht zu einem anderen Unternehmen, um danach zu suchen.
- 400 bei ungültigen Anfragefeldern, einschließlich Bytegröße oder MIME. Korrigieren Sie die Anfrage; wiederholen Sie ungültige Eingaben nicht unverändert.
- 410: Die Upload-Sitzung ist abgelaufen. Starten Sie einen neuen Upload; zuvor signierte URLs für Teile können nicht wiederverwendet werden.
- 409 von /abort bedeutet, dass der Upload bereits verarbeitet wird oder abgeschlossen ist. Prüfen Sie seinen Status, anstatt ihn abbrechen zu wollen.
- 422 von /complete bedeutet, dass die übermittelten Teile die Datei nicht bilden können. Vergleichen Sie die vollständige Teileliste und die exakten ETags mit dem Endpunkt für hochgeladene Teile.
- Signieren Sie bei einem vorübergehenden Netzwerk- oder S3-Fehler die abgelaufene URL eines Teils erneut und verwenden Sie erfolgreiche Teile wieder. Fragen Sie bei einem unklaren /complete-Ergebnis zuerst dieselbe Sitzung per Polling ab. Ein finalisierter, aber fehlgeschlagener Upload kann über denselben Abschlusspfad wiederholt werden, solange seine Sitzung gültig ist.