Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve distribution of Chromium extension outside the Stores #1030

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions .github/workflows/Release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,12 @@ on:
workflow_dispatch:
inputs:
target:
type: choice
description: Do you wish to build release or nightly?
required: false
options:
- release
- nightly
default: 'nightly'
version:
description: If building a release version, please set the version number here, like 9.9 (ignored if you selected nightly build)
Expand Down Expand Up @@ -77,8 +81,8 @@ jobs:
MOZILLA_API_KEY: ${{ secrets.MOZILLA_API_KEY }}
TAG_NAME: ${{ github.event.release.tag_name }}
CRON_LAUNCHED: ${{ github.event.schedule }}
INPUT_TARGET: ${{ github.event.inputs.target }}
RELEASE_VERSION: ${{ github.event.inputs.version }}
INPUT_TARGET: ${{ inputs.target }}
RELEASE_VERSION: ${{ inputs.version }}
shell: bash
# Switch -t indicates a tag release (public release); add -d for dry run (for testing)
# BEFORE the -v switch (because $TAG_NAME is empty for non-public builds)
Expand Down
18 changes: 11 additions & 7 deletions .github/workflows/publish-extension.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,12 @@ on:
required: false
default: ''
target:
type: choice
description: 'Set the target to update: "ghpages" or "docker" (will update GitHub Pages by default)'
required: false
options:
- ghpages
- docker
default: ghpages

jobs:
Expand All @@ -40,26 +44,26 @@ jobs:
- uses: actions/checkout@v3
- name: Modify version in source files
env:
INPUT_VERSION: ${{ github.event.inputs.version }}
INPUT_VERSION: ${{ inputs.version }}
TAG_VERSION: ${{ github.event.release.tag_name }}
EVENT_NAME: ${{ github.event_name }}
run: |
chmod +x ./scripts/rewrite_app_version_number.sh
./scripts/rewrite_app_version_number.sh
- name: Build app with src bundle
if: github.event.inputs.target == 'ghpages' || github.event_name == 'push'
if: inputs.target == 'ghpages' || github.event_name == 'push'
run: |
npm ci
npm run build-src
- name: Build app with production bundle (src bundle also provided)
if: github.event.inputs.target == 'docker' || github.event_name == 'release'
if: inputs.target == 'docker' || github.event_name == 'release'
run: |
npm ci
npm run build
echo "After deployment the production app will be available at https://browser-extension.kiwix.org"
# Publish to docker only if explicitly requested or we are releasing
- name: Build and push to docker
if: github.event.inputs.target == 'docker' || github.event_name == 'release'
if: inputs.target == 'docker' || github.event_name == 'release'
uses: openzim/docker-publish-action@v8
with:
image-name: kiwix/kiwix-moz-extension
Expand All @@ -71,18 +75,18 @@ jobs:
dockerfile: docker/dockerfile-browser-extension.pwa
restrict-to: kiwix/kiwix-js
registries: ghcr.io
manual-tag: ${{ github.event.inputs.version }}
manual-tag: ${{ inputs.version }}
# Restart live webapp only if we pushed an image to registry
- name: Restart live webapp
if: github.event.inputs.target == 'docker' || github.event_name == 'release'
if: inputs.target == 'docker' || github.event_name == 'release'
uses: actions-hub/kubectl@master
env:
KUBE_CONFIG: ${{ secrets.KUBE_CONFIG }}
with:
args: rollout restart deployments mozext-deployment -n pwa
# Publish to GitHub Pages if explicitly requested, or if releasing, or if pushing to main
- name: Publish to GitHub Pages
if: github.event.inputs.target == 'ghpages' || github.event_name == 'release' || github.event_name == 'push'
if: inputs.target == 'ghpages' || github.event_name == 'release' || github.event_name == 'push'
run: |
# Set up username and email
echo "Publishing to GitHub pages..."
Expand Down
73 changes: 40 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ Mediawiki-based content (Wikipedia, Wikivoyage, Wikitionary, etc.), StackExchang
## Usage

Install "Kiwix JS" from your browser's add-on store. This is the best way to get the extension, because it will be kept up to date automatically. If
you would rather not use a store, you can get a file-based version of the extension from http://download.kiwix.org/release/browsers/, but you will
have to update this manually.
you would rather not use a store, you can get a file-based version of the extension from http://download.kiwix.org/release/browsers/ (and follow
[instructions below](#installing-signed-or-unsigned-extension-files-in-chromium)), but you will have to update this manually.

Alternatively, you can bookmark or install the PWA version from https://browser-extension.kiwix.org/current/ (it will auto-update), or try our dedicated
PWA version at https://pwa.kiwix.org. To install the PWA (in Chromium browsers), go to Settings -> Apps -> Install this site as an app.
Expand All @@ -42,28 +42,12 @@ these separately, store them in your filesystem, and manually select them after
Please note that certain "Zimit"-based archives (available from the "zimit" directory on https://download.kiwix.org/zim/) are not (yet) compatible
with this reader. There is experimental support for these in our sister app https://pwa.kiwix.org.

## Some technical details

Technically, after reading an article from a ZIM file, it is necessary to "inject" the dependencies (images, css, etc). For compatibility reasons,
there are two main ways of doing this:

- "ServiceWorker" mode (the default) uses a Service Worker to catch any HTTP request the page may send and reply with content read from
the ZIM file. It is a generic and clean way of serving content to the browser. It works in any recent browser, but not in older ones.
Service Workers are currently disabled by Mozilla in Firefox extensions, but we use a workaround (an offline-first PWA version) as a
substitute within the extension;
- "JQuery" mode (deprecated) parses the DOM to find the HTML tags of the dependencies and modifies them to point to content we extract
from the ZIM. This mode is compatible with any browser, but it cannot run JavaScript inside the ZIM file, so some ZIMs with dynamic
content do not work well (if at all). However, Mediawiki-based content (e.g. Wikipedia) works fine in this mode.

You can switch between these content injection modes in Configuration, but if your browser supports ServiceWorker mode, you are strongly
advised to remain in this mode.

## Compatibility

Since the app is written in HTML/JavaScript, it should work in most recent browser engines and many older ones too, depending on the Content
Injection mode supported by the specific browser engine. Archives containing dynamic content (most non-Wikimedia archives) work much better
in ServiceWorker mode (see above), but unfortunately this is not available in many older browsers. If you wish to read such archives, we
would suggest that you upgrade to a browser that supports Service Workers (Chrome 58+, Firefox 61+ [not ESR versions], Edge 17+, Safari 12+).
in ServiceWorker mode ([see below](#some-technical-details)), but unfortunately this is not available in many older browsers. If you wish to read such archives, we
would suggest that you upgrade to a browser that supports Service Workers (Chrome 58+, Firefox 61+ [not ESR versions], Edge 17+, Safari 11.3+).

### Officially supported platforms

Expand All @@ -72,7 +56,8 @@ would suggest that you upgrade to a browser that supports Service Workers (Chrom
- Chromium / Chrome / Edge >= 88 (as a Manifest V3 extension):
+ Google Chrome >=88: <img src="images/googlechrome-color.svg" width="20" /> [Chrome Web Store](https://chrome.google.com/webstore/detail/kiwix/donaljnlmapmngakoipdmehbfcioahhk)
+ Microsoft Edge >=88: <img src="images/microsoftedge-color.svg" width="20" /> [Edge Add-ons Store](https://microsoftedge.microsoft.com/addons/detail/kiwix/jlepddlenlljlnnhjinfaciabanbnjbp)
- Chromium / Chrome / Edge 58-87 (as a Manifest V2 extension): use unsigned MV2 zip from the `chrome` or `edge` directory in https://download.kiwix.org/release/browsers/, and follow [instructions below](#installing-unsigned-extensions-in-chromium)
- Chromium / Chrome / Edge 58-87 (as a Manifest V2 extension): use the MV2 zip from the `chrome` or `edge` directory in https://download.kiwix.org/release/browsers/, and follow [instructions below](#installing-signed-or-unsigned-extension-files-in-chromium)
- Safari >=11.3 on macOS or iOS: <img src="images/safari-color.svg" width="20" /> no extension available, but use https://browser-extension.kiwix.org and install to Home screen; for a more fully featured PWA, use https://pwa.kiwix.org
- Electron >=1.8.0 and NWJS >=0.14.7 (as an application): https://kiwix.github.io/kiwix-js-windows/kiwix-js-electron.html
- Universal Windows Platform (UWP) >=10.0.10240 (as an HTML/JS application): [Microsoft Store](https://www.microsoft.com/store/apps/9P8SLZ4J979J)
- Ubuntu Touch (as an application): [Ubuntu OpenStore](https://open-store.io/app/kiwix)
Expand All @@ -81,24 +66,46 @@ would suggest that you upgrade to a browser that supports Service Workers (Chrom

These platforms/browsers are deprecated. We still partially test against them, and we'll try to keep compatibility as long as it's not too complicated:

- Firefox OS >=1.2 (needs to be installed manually on the device with WebIDE)
- Microsoft Edge Legacy >=15 (needs to run a bundled version of the source code)
- Microsoft Internet Explorer 11 (needs to run a bundled version of the source code)
- Firefox OS >=1.2: needs to be installed manually on the device with WebIDE
- Microsoft Edge Legacy >=17: no extension available, but bookmark https://browser-extension.kiwix.org or https://pwa.kiwix.org
- Microsoft Edge Legacy 15-16: needs to run a bundled version of the source code in jQuery mode only
- Microsoft Internet Explorer 11: needs to run a bundled version of the source code in jQuery mode only

You can build a bundled version by running `npm install` and `npm run build` in the root directory of this repo. Alternatively, a bundled version is served
**_You can build a bundled version by running `npm install` and `npm run build` in the root directory of this repo._** Alternatively, a bundled version is served
as a web app for testing from https://kiwix.github.io/kiwix-js/dist/ (also available on the `gh-pages` branch of this repo, under `/dist`).

### Installing unsigned extensions in Chromium
### Installing signed or unsigned extension files in Chromium

If you need to install Chromium (Chrome or Edge) extension from a file instead of from a Store, e.g. if your browser doesn't support Manifest V3, then you will need to download a
signed or unsigned CRX or ZIP file from a relevant directory in https://download.kiwix.org/release/browsers/, or else a nightly version from https://download.kiwix.org/nightly/.
Files with `mv2` in their filename are in the legacy Manifest V2 format.

If you need to install an unsigned extension version, e.g. if your browser doesn't support Manifest V3, then you will need to download an unsigned ZIP file from
a relevant directory in https://download.kiwix.org/release/browsers/, or else a nightly version from https://download.kiwix.org/nightly/. Open the extension
management page in your browser, e.g. chrome://extensions/ or edge://extensions/, and turn on Developer mode. Now, you should be able to drag and drop the ZIP
file into this page. Verify the extension is showing in the management page.
To install your CRX or ZIP, open the extension management page in your browser, e.g. chrome://extensions/ or edge://extensions/, and turn on Developer mode. Now, you should be
able to drag and drop the ZIP file into this page. Verify the extension is showing in the management page.

Alternatively, if drag-and-drop is difficult, you can instead unzip the extension ZIP into a folder, and note the location. Then select "Load unpacked" and choose
the folder that contains the unzipped extension.
Files that we deliver with a `.crx` file extension are files that have been validated by the Edge or Chrome Stores, and you should be able to install these as "first-class" apps.
ZIP files provided in https://download.kiwix.org/release/browsers/, or the ones labelled `signed` in nightly, are actually signed CRX files that have been renamed with a `.zip`
extension to facilitate downloading and installing them in Chromium browsers. Although signed, you cannot install them as CRX files, because they have not been validated by the
Chrome or Edge Stores. **_For this reason, the browser will periodically ask you if you want to turn off developer-mode extensions. Just choose "ask again in two weeks"._**

The browser will periodically ask you if you want to keep developer mode extensions installed.
If drag-and-drop is difficult, you can instead unzip the extension ZIP into a folder, and note the location. Then select "Load unpacked" and choose the folder that contains the
unzipped extension. To unzip the MV2 files with a utility like 7Zip, you will need to change the extension name to `.crx`. On Linux, `unzip` can read them without changing the filename.

## Some technical details

Technically, after reading an article from a ZIM file, it is necessary to "inject" the dependencies (images, css, etc). For compatibility reasons,
there are two main ways of doing this:

- "ServiceWorker" mode (the default) uses a Service Worker to catch any HTTP request the page may send and reply with content read from
the ZIM file. It is a generic and clean way of serving content to the browser. It works in any recent browser, but not in older ones.
Service Workers are currently disabled by Mozilla in Firefox extensions, but we use a workaround (an offline-first PWA version) as a
substitute within the extension;
- "JQuery" mode (deprecated) parses the DOM to find the HTML tags of the dependencies and modifies them to point to content we extract
from the ZIM. This mode is compatible with any browser, but it cannot run JavaScript inside the ZIM file, so some ZIMs with dynamic
content do not work well (if at all). However, Mediawiki-based content (e.g. Wikipedia) works fine in this mode.

You can switch between these content injection modes in Configuration, but if your browser supports ServiceWorker mode, you are strongly
advised to remain in this mode.

### Limitations

Expand Down
1 change: 1 addition & 0 deletions images/safari-color.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions scripts/create_all_packages.sh
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,8 @@ if [ -n "$TAG" ]; then
echo -e "\nUploading the files to https://download.kiwix.org/release/"
scp -P 30022 -r -p -o StrictHostKeyChecking=no -i ./scripts/ssh_key build/kiwix-firefoxos* [email protected]:/data/download/release/firefox-os
scp -P 30022 -r -p -o StrictHostKeyChecking=no -i ./scripts/ssh_key build/kiwix-ubuntu-touch* [email protected]:/data/download/release/ubuntu-touch
scp -P 30022 -r -p -o StrictHostKeyChecking=no -i ./scripts/ssh_key build/kiwix-chrome*mv2*.zip [email protected]:/data/download/release/browsers/chrome/kiwix-chrome-mv2_$VERSION.zip
scp -P 30022 -r -p -o StrictHostKeyChecking=no -i ./scripts/ssh_key build/kiwix-chrome*mv2*.zip [email protected]:/data/download/release/browsers/edge/kiwix-edge-mv2_$VERSION.zip
scp -P 30022 -r -p -o StrictHostKeyChecking=no -i ./scripts/ssh_key build/kiwix-chrome-signed*mv2*.zip [email protected]:/data/download/release/browsers/chrome/kiwix-chrome-mv2_$VERSION.zip
scp -P 30022 -r -p -o StrictHostKeyChecking=no -i ./scripts/ssh_key build/kiwix-chrome-signed*mv2*.zip [email protected]:/data/download/release/browsers/edge/kiwix-edge-mv2_$VERSION.zip
else
echo -e "\n[DRRUN] Would have uploaded these files to https://download.kiwix.org/release/ :\n"
ls -l build/kiwix-firefoxos*
Expand Down
30 changes: 15 additions & 15 deletions scripts/package_chrome_extension.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,20 @@ else
fi
cd ..
ls -l build/kiwix-chrome-unsigned-extension-$VERSION.zip
if [ -z $TAG ]; then
# Package the extension with Chrome or Chromium, if we're not packaging a public version
if hash chromium-browser 2>/dev/null
then
echo "Chromium is available"
CHROME_BIN=chromium-browser
else
echo "Chromium is not available: trying to use Chrome"
CHROME_BIN=google-chrome-stable
fi
echo "Signing the extension for $CHROME_BIN, version $VERSION"
$CHROME_BIN --no-sandbox --pack-extension=tmp --pack-extension-key=./scripts/kiwix-html5.pem
mv tmp.crx build/kiwix-chrome-signed-extension-$VERSION.crx
ls -l build/kiwix-chrome-signed-extension-$VERSION.crx
else
if [ -n $TAG ]; then
echo "This unsigned extension must be manually uploaded to Google to be signed and distributed from their store"
fi
# Package the extension with Chrome or Chromium and sign it
if hash chromium-browser 2>/dev/null
then
echo "Chromium is available"
CHROME_BIN=chromium-browser
else
echo "Chromium is not available: trying to use Chrome"
CHROME_BIN=google-chrome-stable
fi
echo "Signing the extension for $CHROME_BIN, version $VERSION"
$CHROME_BIN --no-sandbox --pack-extension=tmp --pack-extension-key=./scripts/kiwix-html5.pem
mv tmp.crx build/kiwix-chrome-signed-extension-$VERSION.zip
ls -l build/kiwix-chrome-signed-extension-$VERSION.zip
echo "This signed extension can be installed by dragging and dropping it into Chromium with developer mode turned on. It is a .crx file renamed to .zip, so that it can be downloaded."