The org site: https://ha-parcel-integrations.github.io/
It documents what no single carrier repo can — the shared parcel contract, the automation cookbook, and the coverage matrix across every carrier. Per-carrier installation and options stay in each repo's own README; this site links there rather than copying it.
The carrier list is generated, never written.
scripts/generate.py reads the GitHub API on every deploy and produces:
| Generated file | Built from |
|---|---|
docs/carriers.md |
Every ha-* repo in the org: manifest, release, icon |
docs/automations.md |
ha-parcel-aggregator/examples/automations/** |
docs/dashboards.md |
ha-parcel-aggregator/examples/dashboards/** |
docs/assets/icons/*.png |
Each carrier's custom_components/<domain>/brand/icon.png |
build/profile-README.md |
A general project introduction with links to the website |
All of them are gitignored. A committed copy is worse than none, because the suite gains carriers faster than anyone remembers to update a table.
Repos are included when they are public and have a published release. Private repos and repos that have never shipped are skipped automatically — you can develop a new carrier in the open without touching this repo.
scripts/sync_org.py runs after a successful build and pushes two things out:
| Target | What |
|---|---|
.github → profile/README.md |
A general project introduction directing visitors to the website |
Every carrier repo's homepage |
Set to the docs site, so the About box links here |
Both need a PAT in the PROFILE_TOKEN secret (contents:write on .github,
administration:write on the org). Without it the step prints a notice and the
site still deploys — it never blocks a release.
The one hand-maintained input is data/carriers.yml —
coverage, how you authenticate, one-line blurb. Nothing else belongs there.
If the org has a carrier repo that data/carriers.yml does not list, the build
fails. That is the tripwire that keeps this site honest; do not soften it.
The same applies to community Lovelace cards: an example dashboard that uses a
custom: card missing from CUSTOM_CARDS in scripts/generate.py fails the
build, so no snippet can quietly depend on a HACS plugin the page never names
or credits.
python -m venv .venv && .venv/bin/pip install -r requirements.txt
GITHUB_TOKEN=$(gh auth token) .venv/bin/python scripts/generate.py
.venv/bin/mkdocs serveGITHUB_TOKEN is optional but the unauthenticated rate limit (60/h) does not
cover a full run.
Umami records clicks on the View on GitHub button in a carrier's detail
dialog — the one place the carrier directory links out to a repo. Each click
sends one custom event named carrier-click:<repo>, for example
carrier-click:ha-postnl. Opening a carrier's card is not an event; the
counter has always meant "clicked through to the integration", and it still
does.
Aliases pointing to the same integration share a counter. In Umami, select the
website and date range, then view Events to compare the counts per integration.
These are clicks, not completed installations, and collection starts after deploy.
This uses standard custom events supported by the free Hobby plan, without extra event properties. Clicks count towards the plan's quota along with pageviews; blocked analytics will not be counted. See the Umami Cloud usage FAQ.
-
every push to
main -
nightly at 04:00 UTC, so a release published by hand shows up
-
repository_dispatchwith typecarrier-released, for immediate publication:gh api repos/ha-parcel-integrations/ha-parcel-integrations.github.io/dispatches \ -f event_type=carrier-released
- Add the repo to
data/carriers.yml - Push
The table row, the icon, the version badge and the early-release flag all follow from the repo itself.