jobfeed-watchdog
A tiny, dependency-light GitHub Action template that watches a job feed (or any JSON/YAML endpoint that returns a list of records) and fails the build when the feed silently breaks — schema change, record-count collapse, or outage. No server, no billing, no secrets required.
Why
Job-board operators and feed consumers discover silent breakage too late: a parser change returns a handful of records, or a required field disappears, and nothing pages anyone. This runs a structural fingerprint on every schedule and turns the Actions run red when something regresses.
What it checks, per feed
| Signal | What it catches |
|---|---|
| Top-level container type change | list -> dict (or vice-versa) |
| Record key set diff | a required field removed/renamed |
Record-count floor (count_ratio, min_count) |
"parser broke, returns 5 of 300" |
| Fetch / parse / HTTP error | feed down or malformed |
Install (30 seconds)
git clone https://github.com/earnnova-dev/jobfeed-watchdog
cd jobfeed-watchdog
cp -r watchfeed.py .github/feeds.json /path/to/your/repo
Then edit feeds.json in your repo to list the feeds you want watched:
{
"feeds": [
{
"id": "my-job-feed",
"url": "https://example.com/api/jobs",
"record_path": "results",
"count_ratio": 0.5,
"min_count": 5,
"timeout": 30,
"headers": { "Authorization": "Bearer ***" }
}
]
}
record_path(optional): dotted path to the list of records, e.g.results.jobs. Omit when the response is the list, or when it's under a conventional key (results/records/data/jobs/items/payload).count_ratio(default0.5): current count must be ≥ baseline × ratio.min_count(default0): absolute floor.headers(optional): auth, etc.
How it works
- On each schedule (
0 */6 * * *= every 6h, orworkflow_dispatchfor a manual run),watchfeed.pyfetches each feed and computes a fingerprint:{top-level container, sorted record key set, record count}. - It compares against the last-known-good baseline stored in
state/<id>.baseline.json(committed to your repo, so runs are reproducible and you cangit diffexactly what changed). - If any feed reports a problem, the step exits non-zero → the run turns red → your normal Actions notification (email/Slack/Discord from repo settings) fires.
- Only when healthy does it commit the new baseline — so it never "blesses" a broken feed as the new normal.
Run it locally
python3 watchfeed.py feeds.json /tmp/state # JSON feed: no deps
python3 watchfeed.py feeds.yml /tmp/state # YAML feed: needs `pip install pyyaml`
python3 -m pytest tests/ # run the offline test suite
Exit codes: 0 all healthy · 1 breakage detected · 2 config/usage error.
Design
- stdlib-only core (
urllib): runs in any CI runner with no heavy install. - YAML optional: JSON feeds need nothing extra; pyyaml only if a feed is YAML.
- deterministic + offline-testable: the fingerprint/compare functions have no
network dependency, covered by
tests/.
Example report
[
{
"id": "my-job-feed",
"url": "https://example.com/api/jobs",
"ok": false,
"count": 3,
"problems": [
"record count dropped: 300 -> 3 (floor 150)",
"records missing keys (possibly removed): salary, location"
]
}
]
License
MIT — use it anywhere. See LICENSE.
Metadata
Release files for jobfeed-watchdog 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| jobfeed_watchdog-1.0.0.tar.gz | 9.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| jobfeed_watchdog-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 17.5 kB
Release files / jobfeed_watchdog-1.0.0.tar.gz
| Download URL | jobfeed_watchdog-1.0.0.tar.gz |
|---|---|
| Size | 9.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a6e62d548458a3e170f39755c57d03c6f9b93daa9982fac08736948ac8cc5c5a
|
|
BLAKE2b-256 checksum How to use checksums |
3dd6b68826450383e612ee65cb7efeac545de1d4ae9fd31505334c4612459c96
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.5
|
Release files / jobfeed_watchdog-1.0.0-py3-none-any.whl
| Download URL | jobfeed_watchdog-1.0.0-py3-none-any.whl |
|---|---|
| Size | 8.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
aec4181a53eb08de25dfabe908dff9e61108681b3dd3615be98d10c1b4a45852
|
|
BLAKE2b-256 checksum How to use checksums |
c08400c87cd31c6a62e15dfb0b56ba9d0237886b99b2b2c911f97f6440802eb3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.5
|