This page covers how uBlock Origin source is assembled into distributable browser extension packages, how versions are tracked, and how releases are published to browser stores and GitHub. For details on the MV2 filtering engine internals, see 3 For a deep dive into the MV3-specific build and ruleset generation pipeline, see 2.4 For the self-hosted update manifest system, see 2.5
The canonical version string lives in a single plain-text file: dist/version1 At the time of writing it contains 1.69.1.5. Every build script reads this file when embedding a version into manifests or naming output archives. The four-component format is major.minor.patch.build.
When the CI pipeline runs, the version is also taken from the Git tag name directly via GITHUB_REF, which must match what is in dist/version.
The primary build orchestration file is Makefile1-188 It defines named targets for every combination of product and platform. Make dependency tracking ensures targets rebuild only when their source files change.
Makefile11-19 defines three variable groups covering the full set of inputs:
| Variable | Content |
|---|---|
sources | dist/version + all files under assets/ + all files under src/ |
platform | All files matched by platform/*/* |
mv3-sources | All src/ files + platform/mv3/ files + the CodeMirror bundle |
assets | dist/build/uAssets (fetched by tools/pull-assets.sh) |
External filter list assets are not stored in the repository. tools/pull-assets.sh fetches them into dist/build/uAssets. This step happens explicitly during CI and must be run manually in local development.
Build pipeline: source files → Make targets → output artifacts
Sources: Makefile11-91
| Make target | Output path | Script invoked |
|---|---|---|
chromium | dist/build/uBlock0.chromium | tools/make-chromium.sh |
firefox | dist/build/uBlock0.firefox | tools/make-firefox.sh all |
opera | dist/build/uBlock0.opera | tools/make-opera.sh |
npm | dist/build/uBlock0.npm | tools/make-npm.sh |
dig | dist/build/uBlock0.dig | tools/make-dig.sh |
mv3-chromium | dist/build/uBOLite.chromium | tools/make-mv3.sh chromium |
mv3-firefox | dist/build/uBOLite.firefox | tools/make-mv3.sh firefox |
mv3-edge | dist/build/uBOLite.edge | tools/make-mv3.sh edge |
mv3-safari | dist/build/uBOLite.safari | tools/make-mv3.sh safari |
all | (chromium + firefox + npm) | — |
clean | removes dist/build, node_modules | — |
cleanassets | removes dist/build/mv3-data, dist/build/uAssets | — |
lint | (no artifact) | npm run lint (ESLint) |
init | installs node_modules | npm install |
The all default target Makefile24 builds only chromium, firefox, and npm. MV3 targets and the dig benchmarking tool must be invoked explicitly.
All four MV3 targets declare a dependency on ubol-codemirror Makefile76-91 This target compiles a custom CodeMirror 6 bundle by invoking the sub-Makefile at platform/mv3/extension/lib/codemirror/codemirror-ubol/. The output is written to:
platform/mv3/extension/lib/codemirror/codemirror-ubol/dist/cm6.bundle.ubol.min.js
This bundle must exist before any MV3 extension assembly step runs.
Sources: Makefile70-91
Automated releases are handled by .github/workflows/main.yml1-50 The workflow is named uBO release and triggers on the GitHub create event when the pushed ref is a tag (startsWith(github.ref, 'refs/tags/')).
CI/CD release workflow
| Step | Command / Action |
|---|---|
| Clone repository | actions/checkout@v4 |
| Fetch filter assets | tools/pull-assets.sh |
| Resolve version string | Strip refs/tags/ prefix from GITHUB_REF |
| Build Chromium package | tools/make-chromium.sh $VERSION |
| Build Firefox package | tools/make-firefox.sh $VERSION |
| Assemble release notes | Extract from CHANGELOG.md; append RELEASE.HEAD.md |
| Create GitHub release | softprops/action-gh-release@v2 |
Sources: .github/workflows/main.yml1-50
The release notes step .github/workflows/main.yml34-36 writes release.body.txt from two sources:
CHANGELOG.md excerpt — grep -m1 -B10000 -- "----------" extracts all content from the file top down to (and including) the first ---------- separator. This captures the most recent version's bullet list.RELEASE.HEAD.md — .github/workflows/RELEASE.HEAD.md1-8 is appended after substituting %version% with the tag name via sed. It contains a link to commits since the release and developer installation instructions for Firefox and Chrome.CHANGELOG.md follows the convention that each version block begins with a # X.Y.Z heading and is terminated by a ---------- line CHANGELOG.md1-11
The workflow attaches two files .github/workflows/main.yml48-50:
| File | Description |
|---|---|
dist/build/uBlock0_$VERSION.chromium.zip | MV2 Chromium extension |
dist/build/uBlock0_$VERSION.firefox.xpi | MV2 Firefox extension |
Releases are created with both draft: true and prerelease: true, requiring a manual promotion step before they are publicly visible on GitHub.
Note: MV3 (uBOLite) builds are not produced or attached by the CI workflow. They are built and published separately.
After a release is promoted, extension packages are submitted to browser stores using Node.js scripts in publish-extension/. These are not automated by CI; they are invoked locally via Makefile targets with credentials available in the local environment.
Publishing scripts and their Makefile wiring
Each script receives these parameters from its Makefile target Makefile103-171:
| Parameter | Value |
|---|---|
ghowner | gorhill |
ghrepo | uBlock |
ghtag | version string (from make ... version=X) |
ghasset | chromium or firefox |
storeid | Store-specific extension identifier |
| Makefile target | Store | Extension ID / AMO ID |
|---|---|---|
publish-chromium | Chrome Web Store (stable) | cjpalhdlnbpafiamejdnhcphjbkeiagm |
publish-dev-chromium | Chrome Web Store (dev) | cgbcahbpdhpcegmbfconppldiemgcoii |
publish-edge | Microsoft Edge Add-ons | odfafepnkmbhccpbejgmiehpchacaeak |
publish-firefox | addons.mozilla.org (listed) | [email protected] |
publish-dev-firefox | addons.mozilla.org (unlisted) | [email protected] |
The publish-edge target additionally passes datebasedmajor=1 and a productid read from the system keyring via secret-tool Makefile113-121
upload-dev-firefox Makefile162-171 differs from publish-dev-firefox in that it passes updatepath=./dist/firefox/updates.json. This instructs upload-firefox.js to write a self-hosted update manifest, enabling Firefox to serve updates for the extension outside of AMO. See 2.5 for the updates.json schema.
Sources: Makefile102-171
The npm Makefile target produces dist/build/uBlock0.npm, which is the source tree for the @gorhill/ubo-core npm package. Its manifest is at platform/npm/package.json1-35
| Property | Value |
|---|---|
| Package name | @gorhill/ubo-core |
| Version | 0.1.30 |
| Entry point | index.js |
| Node.js requirement | >=18.0.0 |
| License | GPL-3.0-or-later |
This package exposes StaticNetFilteringEngine for use in external Node.js environments. It is versioned independently of the browser extension. Publishing to the npm registry is not handled by the Makefile or CI workflow; it is a manual step.
Sources: platform/npm/package.json1-35 Makefile44-47
make lint requires running make init first Makefile53-56 to install dev dependencies declared in package.json. ESLint is invoked via npm run lint package.json7 and covers:
src/js/*.js and src/js/**/*.jsplatform/**/*.js.json fileslib/ and npm/ directories are excluded. Node.js ≥ 22 is required package.json19
The dig and dig-snfe targets Makefile58-65 build the SNFE (static network filtering engine) benchmark harness at dist/build/uBlock0.dig and run platform/dig/snfe.js against real filter lists. See 11.1 for full documentation of this tool.
Sources: Makefile53-65 package.json1-32
Refresh this wiki
This wiki was recently refreshed. Please wait 2 days to refresh again.