Trigger sources¶
A support matrix only stays current if new versions are noticed. Trigger detection is pluggable in the same way as publishing: each detector watches one kind of source, and all of them feed the same queue.
Detector types¶
| Detector | Runs | Watches | Typical triggers |
|---|---|---|---|
| Scheduled image check | Cron, e.g. daily | The cloud provider's image catalogue | A newer machine image for a supported OS, version and architecture |
| GitHub releases watcher | Cron (webhooks only work for repositories you control) | Releases and tags of upstream projects | A new product agent or CLI version, Kubernetes, container runtimes, network plugins, Helm charts |
| Vendor page check | Cron | Release notes and changelog pages | Vendors that publish versions only as web pages |
| Manual request | On demand | An engineer or customer-facing team | Specific combinations, or a customer's exact environment |
What was built, and what's design
The original framework had two automatic detectors, both running on a schedule: a scheduled image check for new OS images, and a GitHub version check for new agent and CLI releases. Specific combinations were requested manually. The version ledger, the vendor page check and the common detector interface on this page are the design I'd build on top of that today.
Detectors ran on a schedule through the CI system, the neutral entry point across clouds. When the ledger finds something new, the detector starts a run through the CI system's API, so it looks exactly like any other run.
Scheduled image check¶
The most useful detector for host and node topologies. On a schedule, it runs the same image resolution the framework uses at provisioning time: for each supported OS, version and architecture, find the newest published image. If the result differs from the last image tested, that's a trigger.
Reusing the resolver means detection and provisioning always agree on what "latest" means.
GitHub releases watcher¶
Most of the components in a cloud-native support matrix publish their releases on GitHub, including Kubernetes, container runtimes, network plugins and Helm charts, and often the product's own agent or CLI. The watcher asks the GitHub releases and tags API for each repository in its watch list, and compares the newest stable version with the last one seen.
A few rules keep this detector useful:
- Filter pre-releases (
-rc,-beta,-alpha) unless the matrix tracks them deliberately. - Compare versions as versions, not strings, so
1.10sorts after1.9. - Authenticate to avoid low anonymous rate limits, and use conditional requests so unchanged repositories cost nothing.
Vendor page check¶
The fallback for vendors without an API or feed: fetch a release notes or changelog page and extract version numbers. It's the most fragile detector, because a page redesign can break it silently. Give it an alert for when it finds nothing at all, not just for when it finds something new.
The version ledger¶
Every detector reports candidates, and the ledger decides which ones become triggers:
- it stores the last version seen for each source and axis, such as
ubuntu 24.04 arm64orcontainer-runtime; - it drops candidates it has already seen, so a daily check doesn't re-run the same image every day;
- it records when each version was first seen, which also shows how long a release waited before being validated.
A small key-value table or a JSON file in object storage is enough.
One interface per detector¶
class Detector(Protocol):
name: str
def candidates(self) -> list[Candidate]: ... # what this source says is current
The scheduler runs each detector, passes its candidates through the ledger, and turns anything new into a trigger with the same structure as a manual request. Adding a new source means writing one detector. The framework, topologies and publishing don't change.
Choosing what to detect¶
| Detect automatically | Leave to manual requests |
|---|---|
| Axes that release often and predictably (OS images, the product's own agent or CLI) | Rare or customer-specific combinations |
| Components customers upgrade without asking | Components that need a judgement call about scope |
| Sources with an API or a stable feed | Sources that are only on web pages and change layout often |