Skip to content

About

Android OTA archive (getprop submissions + resolved firmware metadata, served via jsDelivr)

Resources

Stars

5 stars

Watchers

0 watching

Forks

Latest commit

 

History

9,014 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ota-archive

Android OTA archive: collected device getprop + resolved firmware metadata, served to the app via cdn.jsdelivr.net. See the design in android-ota-finder/docs/server.md.

Layout

Paths are lowercased; {group} = ro.product.manufacturer (falling back to ro.product.brand), so e.g. SBM801FJ lives under sharp/, not sbm/.

OTA/Google/{group}/{model}/
  index.json                      # {firmware:[...], builds:[...]} (regenerated by Actions)
  getprop/{sha1(fingerprint)}.json    # submitted by the app via the Worker
  firmware/{sha1(postBuild)}.json     # resolved by Actions (one per OTA)

The chain links by fingerprint, the only id present in both the device props (ro.build.fingerprint) and OTA metadata (pre-build/post-build) — so it works even when ro.build.date.utc is missing. A firmware's identity is its postBuild (the build it installs); preBuild is just the build it updates from. Each firmware records otaType (full | incremental, from metadata pre-build presence).

Read URLs (app uses these; no Worker, no auth)

https://cdn.jsdelivr.net/gh/mouseos/ota-archive@main/OTA/Google/{group}/{model}/index.json

The app fetches this once and walks the chain in memory: match the device fingerprint against firmware[].preBuild, follow postBuild → next.

Components

  • worker/ — Cloudflare Worker, write-only POST /v1/getprop (commits getprop by fingerprint hash under the manufacturer group).
  • scripts/ — Python run by Actions: resolve.py (fingerprint-linked checkin chain with ro.product.device fallback + HTTP-Range metadata, writes firmware by postBuild hash + otaType), regen_index.py (per-model index.json), list_pending.py, ia_upload.py (archive.org). checkin*.py / *_pb2.py are the android-checkin reference protobufs.
  • .github/workflows/pipeline.yml — cron (6h): resolve → regen index → commit → purge jsDelivr; then a matrix job uploads pending firmware to archive.org. The web site (mouseos/ota-archive-web) polls this repo on its own schedule — there is no cross-repo trigger (GITHUB_TOKEN gets 403 on other repos) — and the verify job fails visibly if the published web snapshot is older than 30 hours.

Setup (manual steps — credentials)

1. Cloudflare Worker (write API)

cd worker
npm install
npx wrangler login                       # browser auth (human)
npx wrangler secret put GH_TOKEN         # paste a fine-grained PAT (Contents: R/W on this repo)
# optional rate limit:
#   npx wrangler kv namespace create RL  # then uncomment kv_namespaces in wrangler.toml
npx wrangler deploy                      # -> https://ota-getprop.<sub>.workers.dev/v1/getprop

Put that endpoint URL into the app.

2. GitHub Actions secrets (this repo → Settings → Secrets → Actions)

3. archive.org

Create an account; generate S3 keys (above). One item per device — ota-google-{group}-{model} — with each firmware stored inside under its original package filename.

4. App

  • Set the Worker endpoint URL.
  • Read timestamps.json / firmware.json from the jsDelivr URLs above.

No credentials are needed for Google checkin (anonymous) or jsDelivr.

About

Android OTA archive (getprop submissions + resolved firmware metadata, served via jsDelivr)

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages