Skip to content

Commit

Permalink
move plugin-repo to verified repo
Browse files Browse the repository at this point in the history
  • Loading branch information
bwp91 committed Aug 4, 2024
1 parent 145338b commit f6f9e48
Show file tree
Hide file tree
Showing 9 changed files with 6,480 additions and 0 deletions.
25 changes: 25 additions & 0 deletions .github/workflows/maintain-tarballs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Maintain Tarballs

on:
workflow_dispatch:
schedule:
- cron: '47 12 * * *'

jobs:
build:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./tarballs
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: v20
- name: Install dependencies
run: npm install
- name: Maintain Tarballs
run: npm run maintain-tarballs
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- uses: gautamkrishnar/keepalive-workflow@v1
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.idea
.DS_Store
node_modules
work
674 changes: 674 additions & 0 deletions tarballs/LICENSE

Large diffs are not rendered by default.

85 changes: 85 additions & 0 deletions tarballs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Homebridge Plugin Repo

The purpose of this project is to help make the plugin installation process faster and more reliable for [verified Homebridge plugins](https://homebridge.io/w/Verified-Plugins).

### Why This Is Needed

Homebridge plugins are published and distributed to the NPM registry and installed using the `npm` cli tool.

While `npm` works for the most part, later versions have become increasingly resource hungry and prone to failure on low powered devices with limited RAM and slow disk I/O (such as a Raspberry Pi).

When using `npm` to install a plugin, it has to individually fetch the metadata, and download, verify and extract the tarball for every dependency a plugin has. This can result in hundreds of HTTP requests every time a plugin is installed or updated. An error during any of these operations will often result in the plugin failing to install or update.

This project pre-bundles [verified Homebridge plugins](https://homebridge.io/w/Verified-Plugins), making them to available to download, with all their dependencies, in a single tarball. Additionally a SHA256 sum of the tarball is available so the integrity of the bundle can be verified after being downloaded to the users system.

A plugin installed via a bundle from this repo can be downloaded and installed in seconds, compared the minutes it might take for some plugins on the same hardware.

### How The Bundle Generation Process Works

Every 30 minutes, a job is excuted using GitHub Actions to check for updates made to any [verified Homebridge plugins](https://homebridge.io/w/Verified-Plugins).

Plugins that require updates are then:

1. Installed using `npm` in a clean work directory, post install scripts are disabled;
2. then a `.tar.gz` bundle is created for the plugin, including all it's dependencies;
3. then a `.sha256` checksum file is generated for the bundle;
4. finally the resulting tarball and checksum file are uploaded to the [Homebridge Plugin Repo](https://github.com/homebridge/plugin-repo/releases/tag/v1).

The two most recent versions of a plugin are retained in the [Homebridge Plugin Repo](https://github.com/homebridge/plugin-repo/releases/tag/v1), older versions are purged automatically.

### How Plugins Are Installed Via Bundles

Bundles are only used on certain systems:

* Debian-based Linux ([via apt package](https://github.com/homebridge/homebridge-apt-pkg)): requires apt package update (=>1.0.27)
* Docker: requires image update (=>2022-07-07)
* Synology DSM 7: requires package update via DSM Package Center (=>3.0.7)

When a user requests a plugin to be installed or updated via the Homebridge UI the following workflow is executed:

1. Check if running on a compatible system
2. Check the plugin is verified
3. Check if a download bundle is available for the requested version
4. Download the `.sha256` checksum for the bundle
5. Download the `.tar.gz` tarball
6. Check the integrity of the tarball against the checksum
7. Create a backup of the existing plugin installation (if already installed)
8. Extract the tarball
9. Run `npm rebuild` in the plugin's root directory to have any post install scripts executed locally
10. Update the local `package.json` with the plugin and it's version

If the extraction, or `npm rebuild` steps fail, the old version of the plugin will be restored.

If at any step, the process fails, the Homebridge UI will fallback to using `npm` to complete the installation.

### Download Statistics

This project may impact the download stats for plugins provided by the NPM registry.

As such download stats are available via the [download-statistics.json](https://github.com/homebridge/plugin-repo/releases/download/v1/download-statistics.json) file. This file contains the total downloads from this repo for each verified plugin, as well as the download count for each version (including old versions that have been purged).

The `download-statistics.json` file is updated every 30 minutes.

If you are accessing the file programatically, you will need add a `nonce` query string to the URL to prevent it being redirected to an older (deleted) version of the file. Eg. `/download-statistics.json?nonce=1657193776`.

### FAQ

#### How do I get my plugin included?

All [verified Homebridge plugins](https://homebridge.io/w/Verified-Plugins) are automatically included.

#### What happens if a user attempts to install the latest version of my plugin before the bundle is created?

The plugin will be installed directly from the NPM registry instead.

#### How do I exclude my plugin from being bundled by this project?

Create a pull request adding your plugin's name to the `pluginFilter: string[]` array in the [main.ts](./main.ts) file.

## License

Copyright (C) 2022-2024 oznu

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the [GNU General Public License](./LICENSE) for more details.
45 changes: 45 additions & 0 deletions tarballs/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import antfu from '@antfu/eslint-config'

export default antfu({
rules: {
'curly': ['error', 'multi-line'],
'new-cap': 'off',
'import/extensions': ['error', 'ignorePackages'],
'import/order': 0,
'jsdoc/check-alignment': 'warn',
'jsdoc/check-line-alignment': 'warn',
'jsdoc/require-returns-check': 0,
'jsdoc/require-returns-description': 0,
'no-console': 'off',
'no-undef': 'error',
'perfectionist/sort-exports': 'error',
'perfectionist/sort-imports': [
'error',
{
groups: [
'type',
'internal-type',
'builtin',
'external',
'internal',
['parent-type', 'sibling-type', 'index-type'],
['parent', 'sibling', 'index'],
'object',
'unknown',
],
order: 'asc',
type: 'natural',
},
],
'perfectionist/sort-named-exports': 'error',
'perfectionist/sort-named-imports': 'error',
'quotes': ['error', 'single'],
'sort-imports': 0,
'style/brace-style': ['error', '1tbs', { allowSingleLine: true }],
'style/quote-props': ['error', 'consistent-as-needed'],
'test/no-only-tests': 'error',
'unicorn/no-useless-spread': 'error',
'unused-imports/no-unused-vars': ['error', { caughtErrors: 'none' }],
},
typescript: true,
})
Loading

0 comments on commit f6f9e48

Please sign in to comment.