This page documents how uBlock Origin distributes extension updates outside of browser extension stores, focusing on the self-hosted update manifest used for Firefox and the version string conventions that tie the build system, release artifacts, and update checks together.
For how the CI/CD pipeline creates GitHub release artifacts that the update system links to, see CI/CD Pipeline. For how individual platform builds are assembled, see MV2 Build Process.
uBlock Origin is distributed through multiple channels:
| Platform | Update Mechanism |
|---|---|
| Chrome, Edge, Opera | Browser store automatic updates (Chrome Web Store, Edge Add-ons, Opera add-ons) |
| Firefox | Mozilla AMO and a self-hosted update manifest (updates.json) |
| Thunderbird | Self-hosted update manifest |
For Firefox, a self-hosted update URL is declared in the extension manifest's browser_specific_settings.gecko section. When Firefox checks for updates, it fetches that URL, reads the updates.json manifest, and compares the listed version against the installed version.
The canonical version string is stored in dist/version which contains a single line:
1.69.1.5
The format is MAJOR.MINOR.PATCH.BUILD. The fourth component (build number) is used differently depending on context:
| Usage | Format | Example |
|---|---|---|
dist/version (internal) | M.m.p.b | 1.69.1.5 |
updates.json "version" field | M.m.p.b | 1.69.1.4 |
| GitHub release tag | M.m.pbB (beta notation) | 1.69.1b4 |
| XPI filename | uBlock0_M.m.pbB.firefox.signed.xpi | uBlock0_1.69.1b4.firefox.signed.xpi |
The conversion rule: the dotted fourth component .b becomes the suffix bB appended to the patch number. So 1.69.1.4 → 1.69.1b4.
Note:
dist/versionalways reflects the current working version. Theupdates.jsonfile trails by one build and is updated as part of the release process when the previous release is signed and uploaded to GitHub.
Sources: dist/version1 dist/firefox/updates.json1-17
The file at dist/firefox/updates.json is the self-hosted update manifest consumed by Firefox's extension update checker.
Update manifest structure:
dist/firefox/updates.json
└── addons
└── [email protected] ← extension ID
└── updates[]
├── version ← dotted version (M.m.p.b)
├── browser_specific_settings
│ └── gecko
│ └── strict_min_version ← minimum Firefox version
└── update_link ← URL to signed .xpi on GitHub Releases
The current content of dist/firefox/updates.json1-17 as a reference:
| Field | Value |
|---|---|
| Addon ID | [email protected] |
version | 1.69.1.4 |
strict_min_version (Gecko) | 115.0 |
update_link | https://github.com/gorhill/uBlock/releases/download/1.69.1b4/uBlock0_1.69.1b4.firefox.signed.xpi |
The update_link URL pattern is:
https://github.com/gorhill/uBlock/releases/download/{TAG}/{FILENAME}
where {TAG} = 1.69.1b4 and {FILENAME} = uBlock0_1.69.1b4.firefox.signed.xpi.
Sources: dist/firefox/updates.json1-17
Diagram: Firefox self-hosted update check lifecycle
Sources: dist/firefox/updates.json1-17
Diagram: Version data flow from source to update manifest
Sources: dist/version1 dist/firefox/updates.json1-17
updates.json fields| Field | Type | Description |
|---|---|---|
addons | object | Top-level key; maps addon ID to update entries |
[email protected] | object | The Firefox extension ID |
updates | array | List of available update objects |
version | string | Dotted version string (M.m.p.b) matching the installed version or newer |
browser_specific_settings.gecko.strict_min_version | string | Minimum Firefox/Gecko version required to install this update |
update_link | string | Direct URL to the signed .xpi artifact on GitHub Releases |
dist/version: 1.69.1.4
M m p b
↓
update_link: 1.69.1b4
M m pb
The fourth dotted component b is concatenated to the patch component as bN, without a separator.
Sources: dist/firefox/updates.json1-17 dist/version1
The dist/firefox/updates.json file is committed to the repository. During a release:
.xpi is uploaded to GitHub Releases under a tag matching the beta notation (e.g., 1.69.1b4).updates.json is updated to point to the new release's update_link URL, and the version field is set to the dotted form of the previous release (which is now being published as the stable signed artifact).updates.json is pushed back to the repository, where it is accessible to Firefox as the self-hosted update URL.This one-release lag between dist/version and the version field in updates.json is intentional: the signing step (required for Firefox's self-hosted distribution) happens after a build is tagged, so the manifest is updated once the signed artifact is available.
Refresh this wiki
This wiki was recently refreshed. Please wait 2 days to refresh again.