fix(website): rebuild the API reference from the generated schema - #3281
Conversation
The API page reads `site.Data.openapi`, which was a snapshot committed once during the Hugo migration and never touched again. Nothing regenerated it: generate-openapi-schema.yaml uploads `anthias-api-schema.json` as a workflow artifact and stops, and deploy-website.yaml never fetched it. A year of API work therefore never reached the published reference — it was missing nine endpoints (display, viewer playlist/settings, network ip-addresses, asset recheck, the four integrations import/migrate paths) and eight component schemas, most recently the display-schedule fields. - Replace website/data/openapi.yaml with openapi.json, generated off current master. Hugo resolves site.Data.openapi from either extension, so the layout is unchanged and there is no conversion step; both files must not coexist, hence the delete. - deploy-website.yaml fetches the artifact from the latest successful master run and overwrites the committed copy before `hugo`, in the shape the marketing-screenshots step already established. A missing run is a soft fail (ship the committed schema); a corrupt artifact is not, so it is validated into a temp file and only moved into place once it parses and carries the keys api-schema.html dereferences. - Trigger the deploy off the schema workflow. An API-only commit touches no `website/**` path, so the existing filter would never fire and the page would drift again — the fetch step alone only makes freshness possible, this is what makes it happen. The cost is that the site redeploys on most master merges. The committed copy stays a real fallback rather than a placeholder: it keeps `hugo server` working offline and degrades a missing artifact to a slightly stale page instead of a broken build. Also fix a latent bug the real schema exposes. api-schema.html printed a union type straight into the template, so /api/v2/info's `display_power` rendered as Go's `[string null]`. The frozen snapshot happened to contain no multi-type field, so shipping an accurate schema is what surfaced it. Joined to `string | null`, matching the `| null` suffix the nullable branch already renders. Verified by building the site locally with Hugo 0.157.0: 22 pages, the new endpoints and schedule fields present, refs resolving, no remaining slice-formatting artifacts, llms:generate still indexing 19 pages. actionlint 1.7.7 clean on the workflow. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
|
There was a problem hiding this comment.
Pull request overview
This PR updates the marketing website’s API reference to stay in sync with Anthias’ generated OpenAPI schema by switching the committed snapshot to a generated JSON schema, fetching the latest schema artifact during deploys, and fixing a Hugo template rendering issue exposed by the newer schema.
Changes:
- Replace the stale committed OpenAPI snapshot (
website/data/openapi.yaml) with a freshly generated JSON schema (website/data/openapi.json). - Update the website deploy workflow to (a) redeploy on successful “Generate OpenAPI Schema” runs and (b) download/validate the latest
anthias-api-schemaartifact before building Hugo. - Fix union-type rendering in the API schema Hugo partial so
[string null]becomesstring | null.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
website/layouts/partials/api-schema.html |
Renders OpenAPI union types cleanly by detecting slice-valued type and joining with |. |
website/data/openapi.yaml |
Removes the obsolete YAML snapshot to avoid coexisting with the new JSON source. |
website/data/openapi.json |
Adds the regenerated, current OpenAPI schema consumed by site.Data.openapi. |
.github/workflows/deploy-website.yaml |
Fetches and validates the latest schema artifact on deploy; triggers redeploys from successful schema workflow runs. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #3281 +/- ##
=========================================
Coverage ? 90.47%
=========================================
Files ? 79
Lines ? 8932
Branches ? 950
=========================================
Hits ? 8081
Misses ? 627
Partials ? 224 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|



Issue
The API reference on anthias.screenly.io is a snapshot of
website/data/openapi.yamlcommitted once during the Hugo migration and never regenerated. Nothing keeps it current:generate-openapi-schema.ymluploadsanthias-api-schema.jsonas a workflow artifact and stops — no commit, no push, nothing downstream consumes it.deploy-website.yamlfetches marketing screenshots andrpi-imager.json, but never the schema.So the published reference has been frozen while the API moved on. Measured against a schema generated from current master, it was missing 9 endpoints and 8 component schemas:
/api/v2/display/{state}DisplayPowerViewSerializerMixin/api/v2/viewer/playlistViewerPlaylistSerializerV2/api/v2/viewer/settingsViewerSettingsSerializerV2/api/v2/network/ip-addressesScreenRotationEnum/api/v2/assets/{asset_id}/recheckImportItemSerializerV2/api/v2/integrations/import/{provider}/itemImportValidateSerializerV2/api/v2/integrations/import/{provider}/validateScreenlyTokenSerializerV2/api/v2/integrations/screenly/migrateScreenlyMigrateAssetSerializerV2/api/v2/integrations/screenly/validateField-level, it also predates
play_days/play_time_from/play_time_to,prefer_dark_mode,verify_ssl, and the fourdisplay_power_*schedule fields.The old snapshot is a strict subset of the generated one — nothing was in it that is not in the fresh schema — so it was never hand-curated, just stale.
Changes
Data file.
website/data/openapi.yaml→website/data/openapi.json, generated off current master. Hugo resolvessite.Data.openapifrom either extension, solayouts/_default/api.htmlis untouched and no conversion step is needed. The two must not coexist, hence the delete rather than an addition.Fetch on deploy. A new step pulls the
anthias-api-schemaartifact from the latest successful master run of the schema workflow and overwrites the committed copy beforehugoruns, in the shape theFetch marketing screenshotsstep already established.The soft/hard-fail split is deliberate and differs from that step: a missing run is a soft fail, because the committed file is a real fallback and shipping a slightly stale page beats failing the deploy. A corrupt artifact is not, because it would replace a good file with a bad one — the JSON is validated into a temp file and only moved into place once it parses and carries
pathsandcomponents.schemas, both of whichapi-schema.htmldereferences when resolving a$ref. Without that assert a truncated download renders a blank page instead of failing.Trigger. The fetch step alone only makes freshness possible. An API-only commit touches no
website/**path, so the existing filter never fires and the page drifts again — which is how it got a year behind. The deploy now also chains offworkflow_runforGenerate OpenAPI Schemaon master, guarded so a failed or cancelled schema run cannot trigger a deploy that would silently republish the committed fallback.generate-openapi-schema.ymlruns on nearly every non-website master push, so the site will now redeploy on most merges rather than only on website changes and releases. That is the price of the page never being stale. Drop theworkflow_runblock if you would rather bound deploy frequency and accept refresh-on-next-website-change.Layout fix.
api-schema.htmlprinted a union type straight into the template, so/api/v2/info'sdisplay_powerrendered as Go's[string null]. The frozen snapshot happened to contain no multi-type field, so shipping an accurate schema is what surfaced it. Now joined tostring | null, matching the| nullsuffix the nullable branch already renders.Testing
Built the site locally with the same Hugo version CI pins (0.157.0 extended):
display_power_*fields render on/api/.$refresolution works against the new file (DisplayPowerViewSerializerMixinresolves in 5 places).display_powerrendersstring | null; a sweep for remaining[... ...]slice artifacts across the page returns nothing.bun run llms:generatestill indexes 19 pages.actionlint1.7.7 clean ondeploy-website.yaml.Not exercised: the fetch step itself, which only runs on a master push — it cannot execute on a PR. Its
gh run list/gh run downloadcalls are copied from the working screenshots step, and the samerun_idlookup was run by hand against this repo while preparing the committed schema.Checklist
The device boxes are not applicable: this changes the marketing site build only and ships no code to a device.
🤖 Generated with Claude Code