Rebuilds the SideCartridge Multidevice app catalogs. The script aggregates per-app *.json files in the atarist.sidecartridge.com S3 bucket, normalizes each app's tags/devices to canonical taxonomy values (see Taxonomy normalization), derives each app's previous_versions from the {uuid}-*.uf2 binaries it finds in the same bucket (md5 computed from the actual bytes), then writes two catalogs:
apps.json— every app from the bucket.apps-beta.json— only apps whose current top-levelversioncontainsalphaorbeta(case-insensitive substring). Useful for a "prerelease" channel in clients.previous_versionsinside each included app is not filtered — the full history is preserved.
Each catalog is published to its own S3 key independently, and both honour the same dry-run / test / publish semantics.
- Python 3.10
pip install boto3 packaging- AWS credentials with read/write access to the bucket exported as
AWS_ACCESS_KEY_IDandAWS_SECRET_ACCESS_KEY(CI provides these via GitHub Actions secrets).
python updateapps.py [--test] [--publish]Defaults are safe: nothing is uploaded unless you pass --publish.
| Command | Local files | S3 uploads |
|---|---|---|
python updateapps.py |
rewrites apps.json and apps-beta.json |
none (dry run) |
python updateapps.py --publish |
rewrites apps.json and apps-beta.json |
uploads each catalog only if its own diff shows a new UUID or a top-level version bump (existing objects backed up to {key}.DDMMYYYY.bak first) |
python updateapps.py --test |
rewrites apps-test.json and apps-beta-test.json |
none (dry run) |
python updateapps.py --test --publish |
rewrites apps-test.json and apps-beta-test.json |
always uploads both (no diff gate) — production apps.json / apps-beta.json untouched |
Use --test while iterating: it routes both local files and both S3 objects to the *-test.json variants, so you can inspect the results at https://atarist.sidecartridge.com/apps-test.json and https://atarist.sidecartridge.com/apps-beta-test.json without affecting the live catalogs.
.github/workflows/build.yml— runs on every PR in dry-run mode (no upload). Useful for catching script errors before merge..github/workflows/nightly.yml— runs daily at 06:00 UTC with--publish. This is the only path that writes to productionapps.json/apps-beta.json.
Per-app JSON files often use slightly different spellings for the same tags / devices
value (Atari ST, AtariST, ST, …). To keep the catalog consistent, every app's
tags and devices are rewritten to a canonical value on each build, using the alias
dictionary in taxonomies.json:
{
"tags": { "Catalogs": ["catalog", "catalogue", "catalogues"] },
"devices": { "ST": ["Atari ST", "AtariST", "Atari-ST"] }
}tagsanddeviceshave separate maps, so a device alias never rewrites a tag.- Each entry is
canonical -> [aliases]. Matching is case-insensitive, so a canonical key already matches its own casing — only list genuinely different spellings/words. - Unknown values are left unchanged; results are de-duplicated, preserving order.
- Edit
taxonomies.jsonto add new canonical terms or aliases — no code change needed. A missing or invalid file simply disables normalization for that run.
Each app object in apps.json (and apps-beta.json):
{
"uuid": "...",
"name": "...",
"description": "... (may contain HTML <a> tags)",
"image": "https://...",
"tags": ["..."],
"devices": ["..."],
"binary": "https://atarist.sidecartridge.com/{uuid}-{version}.uf2",
"md5": "...",
"version": "v1.2.3",
"previous_versions": [
{ "version": "v1.2.2", "binary": "https://...", "md5": "..." }
]
}previous_versions is sorted newest-first using PEP 440 ordering and excludes the current version.