Von der Custom Integration zum HACS Store: Mein Weg zur Veröffentlichung

Heute habe ich meine Home Assistant Custom Integration für die Raspberry Pi Pico W NeoPixel-Steuerung fit für den HACS Store gemacht. Was auf den ersten Blick trivial klingt — ein paar Dateien anpassen, fertig — entpuppt sich bei genauerem Hinsehen als ein sauber definierter Prozess mit einigen Stolpersteinen.

Ausgangslage

Meine Integration steuert NeoPixel-LED-Strips über einen Raspberry Pi Pico W per REST-API. Die Codebasis stand: Config Flow, Coordinator, Light/Select/Button/Number/Sensor-Plattformen, Übersetzungen. Was fehlte, war die Konformität mit den HACS-Anforderungen für eine Aufnahme als Default Repository.

Die HACS-Checkliste

HACS verlangt für Integrations mehr als nur funktionierenden Code. Die Anforderungen gliedern sich in drei Bereiche: Repository-Metadaten, Dateistruktur und CI/CD.

1. manifest.json

Die manifest.json im Integration-Verzeichnis muss mindestens sechs Felder definieren:

{
    "domain": "picow_neopixel",
    "name": "PicoW NeoPixel",
    "codeowners": ["@maxi07"],
    "documentation": "https://github.com/maxi07/PicoW-Neopixel-Homeassistant-Integration",
    "issue_tracker": "https://github.com/maxi07/PicoW-Neopixel-Homeassistant-Integration/issues",
    "version": "1.0.0"
}

Fehlt eines davon, schlägt die Hassfest-Validierung fehl. documentation und issue_tracker müssen auf erreichbare URLs zeigen.

2. hacs.json

Die hacs.json im Repository-Root war bei mir minimal. Für die Aufnahme in den Default Store habe ich render_readme ergänzt, damit HACS die README direkt im Store anzeigt:

{
  "name": "PicoW NeoPixel",
  "homeassistant": "2024.1.0",
  "render_readme": true
}

3. Brand Assets

Das war der Punkt, den ich anfangs übersehen hatte. HACS prüft, ob Brand Assets existieren — entweder im zentralen home-assistant/brands-Repository oder lokal in der Integration. Für Custom Integrations ist der lokale Weg der richtige:

custom_components/picow_neopixel/brand/icon.png

Ich hatte bereits ein Icon (picow_neopixel.png) im Root — also musste ich es nur in das richtige Verzeichnis kopieren.

4. GitHub Actions

HACS verlangt zwei GitHub Actions, die beide fehlerfrei durchlaufen müssen, bevor man einen PR einreichen kann:

HACS Validation — nutzt denselben Code wie HACS selbst:

name: HACS Validation
on:
  push:
  pull_request:
  schedule:
    - cron: "0 0 * * *"
  workflow_dispatch:
permissions: {}
jobs:
  validate-hacs:
    runs-on: "ubuntu-latest"
    steps:
      - uses: "actions/checkout@v4"
      - name: HACS validation
        uses: "hacs/action@main"
        with:
          category: "integration"

Hassfest — die offizielle Home Assistant Manifest-Validierung:

name: Validate with hassfest
on:
  push:
  pull_request:
  schedule:
    - cron: "0 0 * * *"
  workflow_dispatch:
permissions: {}
jobs:
  validate-hassfest:
    runs-on: "ubuntu-latest"
    steps:
      - uses: "actions/checkout@v4"
      - uses: "home-assistant/actions/hassfest@master"

5. README aufräumen

Ein “Coming soon”-Banner im README wirkt bei einer Einreichung nicht gerade vertrauenerweckend. Ich habe es durch HACS- und Hassfest-Badges ersetzt und die Installationsanleitung mit einem My Home Assistant-Button versehen:

[![hacs_badge](https://img.shields.io/badge/HACS-Default-41BDF5.svg)](https://github.com/hacs/integration)

Dazu kommt ein My Home Assistant-Link, der Nutzer direkt zur Integration in ihrem HACS führt — deutlich niedrigere Einstiegshürde als eine manuelle Installation.

Verbleibende manuelle Schritte

Nicht alles lässt sich automatisieren. Vor dem PR an hacs/default musste ich noch:

  1. GitHub-Repository-Metadaten setzen — Description, Topics (home-assistant, hacs, neopixel, raspberry-pi-pico-w) und Issues müssen aktiv sein
  2. Actions durchlaufen lassen — beide Workflows müssen grün sein
  3. Ein GitHub Release erstellen — ein Tag allein reicht nicht, es muss ein vollständiges Release sein
  4. Den PR einreichen — Fork von hacs/default, neuer Branch von master, Repository-URL alphabetisch in die integration-Datei einfügen

Fazit

Ein kleiner Fehler passierte mir noch: Ich hatte den Pull-Request aus meinem Haupt-Fork in den Remote-Haupt-Fork gestellt – das akzeptiert HACS jedoch nicht und so wurde mein erster PR prompt abgelehnt. Der Pull-Request muss direkt aus einem Branch im eigenen Fork erfolgen. Wer die offizielle Dokumentation Schritt für Schritt befolgt, wird jedoch problemlos ans Ziel kommen.

Jetzt heißt es abwarten!