Skip to content
Open
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
9 changes: 9 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,14 @@ jobs:
github-token: ${{ secrets.GITHUB_TOKEN }}
path: ./artifacts

- name: Download Linux-inclusive Stream Deck Plugin
uses: actions/download-artifact@v4
with:
name: com.chrisregado.googlemeet-linux.streamDeckPlugin
run-id: ${{ steps.get-workflow-id.outputs.plugin_run_id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
path: ./artifacts

- name: Attach artifacts to release
uses: softprops/action-gh-release@v2
with:
Expand All @@ -89,3 +97,4 @@ jobs:
./artifacts/chrome-extension-${{ github.event.release.tag_name }}.zip
./artifacts/firefox-extension-${{ github.event.release.tag_name }}.xpi
./artifacts/com.chrisregado.googlemeet.streamDeckPlugin
./artifacts/com.chrisregado.googlemeet-linux.streamDeckPlugin
50 changes: 50 additions & 0 deletions .github/workflows/streamdeck-plugin-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ jobs:
runs_on: macos-latest
- os: windows
runs_on: windows-latest
- os: linux
runs_on: ubuntu-latest
name: Build ${{ matrix.os }} Stream Deck Plugin
# Since we run on both branch pushes and PRs, don't do a duplicated run if the PR is for a branch in the local repo:
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
Expand Down Expand Up @@ -93,6 +95,20 @@ jobs:
name: windows-plugin-intermediate-build
path: com.chrisregado.googlemeet.sdPlugin/dist/windows

- name: Strip Linux-specific manifest entries for Elgato validation
run: |
cd com.chrisregado.googlemeet.sdPlugin
cp manifest.json manifest-full.json
python3 -c "
import json
with open('manifest.json', 'r') as f:
m = json.load(f)
m.pop('CodePathLin', None)
m['OS'] = [o for o in m.get('OS', []) if o.get('Platform') != 'linux']
with open('manifest.json', 'w') as f:
json.dump(m, f, indent='\t')
"

- name: Run Elgato linter
run: streamdeck validate --no-update-check com.chrisregado.googlemeet.sdPlugin

Expand All @@ -110,8 +126,42 @@ jobs:
VERSION_NUMBER="${GIT_TAG#v}"
streamdeck pack --output ./build/ --no-update-check --force --version "${VERSION_NUMBER}" com.chrisregado.googlemeet.sdPlugin

- name: Download Linux plugin artifact
uses: actions/download-artifact@v4
with:
name: linux-plugin-intermediate-build
path: com.chrisregado.googlemeet.sdPlugin/dist/linux

- name: Set executable permissions on Linux binary
run: chmod +x com.chrisregado.googlemeet.sdPlugin/dist/linux/main/main

- name: Build Linux-inclusive package for OpenDeck
run: |
cd com.chrisregado.googlemeet.sdPlugin
cp manifest-full.json manifest.json
rm manifest-full.json
if [[ "${{ github.ref_type }}" == "tag" ]]; then
GIT_TAG="${{ github.ref_name }}"
VERSION_NUMBER="${GIT_TAG#v}"
python3 -c "
import json
with open('manifest.json', 'r') as f:
m = json.load(f)
m['Version'] = '${VERSION_NUMBER}'
with open('manifest.json', 'w') as f:
json.dump(m, f, indent='\t')
"
fi
zip -r ../build/com.chrisregado.googlemeet-linux.streamDeckPlugin . -x ".*"

- name: Upload final plugin binary
uses: actions/upload-artifact@v4
with:
name: com.chrisregado.googlemeet.streamDeckPlugin
path: ./build/com.chrisregado.googlemeet.streamDeckPlugin

- name: Upload Linux-inclusive plugin package
uses: actions/upload-artifact@v4
with:
name: com.chrisregado.googlemeet-linux.streamDeckPlugin
path: ./build/com.chrisregado.googlemeet-linux.streamDeckPlugin
70 changes: 52 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,46 @@ This is a plugin that allows the [Elgato Stream Deck](https://www.elgato.com/en/

This plugin works in conjuction with our Google Chrome / Mozilla Firefox browser extension, which is required for this plugin to function.

Developed and tested primarily on macOS 15.0, Python 3.13.0, Chrome 130, and Stream Deck app v6.6. It should work on Windows or in Firefox as well.
Developed and tested primarily on macOS 15.0, Python 3.13.0, Chrome 130, and Stream Deck app v6.6. It should work on Windows or in Firefox as well. Linux is supported via [OpenDeck](https://github.com/nekename/OpenDeck).

## Installing

### macOS / Windows

1. If you're running on an Apple Silicon Mac (e.g. an M1 chip), you must have Apple's [Rosetta 2](https://support.apple.com/en-us/HT211861) installed. If you don't (or if you're not sure), open Terminal and run this command:

```
softwareupdate --install-rosetta --agree-to-license
```

2. From the [Releases page](https://github.com/ChrisRegado/streamdeck-googlemeet/releases), download the `com.chrisregado.googlemeet.streamDeckPlugin` package and open it. The Stream Deck desktop software will prompt you to install the plugin.
3. The browser extension is not in the web store, so we'll install it manually:

**For Google Chrome:**
1. From the [Releases page](https://github.com/ChrisRegado/streamdeck-googlemeet/releases), download the `chrome-extension` zip file and extract it somewhere you can keep it. (If you move the folder after installing, Chrome will uninstall the extension from your browser and you'll have to reinstall it.)
2. From Chrome's extension settings page (`chrome://extensions/`), turn on "Developer mode" using the toggle at the top-right corner of the page.
3. Click the "Load unpacked" button at the top-left corner, and select the folder you extracted the zip to earlier.
4. You can turn Developer mode back off now if you want.
### Linux (via OpenDeck)

1. Install [OpenDeck](https://github.com/nekename/OpenDeck), an open-source Stream Deck application that supports Elgato SDK plugins on Linux.
2. From the [Releases page](https://github.com/ChrisRegado/streamdeck-googlemeet/releases), download the `com.chrisregado.googlemeet-linux.streamDeckPlugin` package (the Linux-inclusive build) and install it through OpenDeck.

### Browser Extension

The browser extension is not in the web store, so we'll install it manually:

**For Google Chrome:**
1. From the [Releases page](https://github.com/ChrisRegado/streamdeck-googlemeet/releases), download the `chrome-extension` zip file and extract it somewhere you can keep it. (If you move the folder after installing, Chrome will uninstall the extension from your browser and you'll have to reinstall it.)
2. From Chrome's extension settings page (`chrome://extensions/`), turn on "Developer mode" using the toggle at the top-right corner of the page.
3. Click the "Load unpacked" button at the top-left corner, and select the folder you extracted the zip to earlier.
4. You can turn Developer mode back off now if you want.

**For Mozilla Firefox:**
1. From the [Releases page](https://github.com/ChrisRegado/streamdeck-googlemeet/releases), download the Firefox extension `.xpi` file.
2. From Firefox's extension settings page (`about:addons`), click the Settings cogwheel at the top-right of the page, click "Install Add-on From File...", and select the `.xpi` file that you just downloaded.
3. Click "Add" on the Firefox popup to allow the extension to install.
**For Mozilla Firefox:**
1. From the [Releases page](https://github.com/ChrisRegado/streamdeck-googlemeet/releases), download the Firefox extension `.xpi` file.
2. From Firefox's extension settings page (`about:addons`), click the Settings cogwheel at the top-right of the page, click "Install Add-on From File...", and select the `.xpi` file that you just downloaded.
3. Click "Add" on the Firefox popup to allow the extension to install.

4. If you use an ad blocker (such as uBlock Origin with the EasyPrivacy filter list), you may have to add meet.google.com as a trusted site in your blocker's settings to allow the browser Extension to work. (Some filters block websockets to 127.0.0.1, which this extension needs to communicate with the Stream Deck.)
5. Add some buttons to your Stream Deck, and start a Google Meet call to try them out!
### Final Steps

It's safe to delete the `com.chrisregado.googlemeet.streamDeckPlugin` file once it's installed. However, on Windows, you may need to quit the Stream Deck desktop software (by right clicking its icon in the Windows task tray and clicking Quit) and re-launch it to avoid "action can't be completed because the file is open" errors.
1. If you use an ad blocker (such as uBlock Origin with the EasyPrivacy filter list), you may have to add meet.google.com as a trusted site in your blocker's settings to allow the browser Extension to work. (Some filters block websockets to 127.0.0.1, which this extension needs to communicate with the Stream Deck.)
2. Add some buttons to your Stream Deck, and start a Google Meet call to try them out!

It's safe to delete the `.streamDeckPlugin` file once it's installed. However, on Windows, you may need to quit the Stream Deck desktop software (by right clicking its icon in the Windows task tray and clicking Quit) and re-launch it to avoid "action can't be completed because the file is open" errors.

## Updating

Expand Down Expand Up @@ -67,7 +79,7 @@ The Stream Deck plugin code is in the `streamdeck-plugin` directory. The browser

The plugin is written in Python. Create a venv to hold your package's dependencies, and install those dependencies:

**MacOS:**
**macOS / Linux:**

```
cd streamdeck-plugin
Expand All @@ -89,7 +101,7 @@ Remember that virtualenvs are not portable. If you move this folder at all, you'

### Running Unit Tests

**MacOS:**
**macOS / Linux:**

```
cd streamdeck-plugin
Expand All @@ -113,7 +125,7 @@ Our plugin code is written in Python, but the Elgato CLI tool is distributed as

To build the plugin:

**MacOS:**
**macOS:**

```
cd streamdeck-plugin
Expand All @@ -123,6 +135,16 @@ pyinstaller --clean --dist "../com.chrisregado.googlemeet.sdPlugin/dist/macos" s
rm -rf build
```

**Linux:**

```
cd streamdeck-plugin
source venv/bin/activate
rm -rf ../com.chrisregado.googlemeet.sdPlugin/dist/linux
pyinstaller --clean --dist "../com.chrisregado.googlemeet.sdPlugin/dist/linux" src/main.py
rm -rf build
```

**Windows:**

```
Expand All @@ -133,22 +155,34 @@ pyinstaller --clean --dist "..\com.chrisregado.googlemeet.sdPlugin\dist\windows"
rmdir /q /s build
```

Note that the resulting executable is only valid for the OS you built it on. MacOS and Windows bundles must be created separately from a machine/VM of that OS, and then combined into the `com.chrisregado.googlemeet.sdPlugin/dist/` folder with `macos` and `windows` subdirectories for release.
Note that the resulting executable is only valid for the OS you built it on. macOS, Linux, and Windows bundles must be created separately from a machine/VM of that OS, and then combined into the `com.chrisregado.googlemeet.sdPlugin/dist/` folder with `macos`, `linux`, and `windows` subdirectories for release.

If you're just testing locally (so you only care about one OS), you can place any file in the other OS's executable location (`CodePath`s from `manifest.json`) to appease the Elgato packaging tool. Example:

```
# If you're running macOS:
mkdir -p com.chrisregado.googlemeet.sdPlugin/dist/windows/main
touch com.chrisregado.googlemeet.sdPlugin/dist/windows/main/main.exe
mkdir -p com.chrisregado.googlemeet.sdPlugin/dist/linux/main
touch com.chrisregado.googlemeet.sdPlugin/dist/linux/main/main

# If you're running Linux:
mkdir -p com.chrisregado.googlemeet.sdPlugin/dist/macos/main
touch com.chrisregado.googlemeet.sdPlugin/dist/macos/main/main
mkdir -p com.chrisregado.googlemeet.sdPlugin/dist/windows/main
touch com.chrisregado.googlemeet.sdPlugin/dist/windows/main/main.exe

# If you're running Windows:
mkdir com.chrisregado.googlemeet.sdPlugin\dist\macos\main
type nul > com.chrisregado.googlemeet.sdPlugin\dist\macos\main\main
mkdir com.chrisregado.googlemeet.sdPlugin\dist\linux\main
type nul > com.chrisregado.googlemeet.sdPlugin\dist\linux\main\main
```

Or, if you don't ever plan on publishing your local builds, delete the other OS's CodePath and `OS` entry in manifest.json so you don't have to worry about multi-OS support.

Note that the Elgato `streamdeck` CLI does not recognize `CodePathLin` (it's an OpenDeck extension). If you need to run `streamdeck validate` or `streamdeck pack` locally, temporarily remove the `CodePathLin` entry from manifest.json first.

Finally, use Elgato's `streamdeck` CLI tool to bundle everything into the Stream Deck plugin distributable that you can install or send to users. From the root of this git repo, run:

```
Expand Down
6 changes: 3 additions & 3 deletions RELEASE_INSTRUCTIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@ Follow these steps each time you want to release a new version of the plugin and
1. Tag the commit you wish to release and push it to GitHub. We use semantic versioning with a "v" prefix for our releases. For example: `git checkout master && git tag v1.2.3 && git push origin tag v1.2.3`
* Our CI jobs will update version numbers automatically to match that tag for both the plugin and browser extensions. You don't need to manually change any version numbers in code/config.
2. CI jobs should automatically launch against that tag to build the [Stream Deck plugin](https://github.com/ChrisRegado/streamdeck-googlemeet/actions/workflows/streamdeck-plugin-build.yml) and [browser extensions](https://github.com/ChrisRegado/streamdeck-googlemeet/actions/workflows/browser-extension-build.yml). (The list of workflow runs should show one copy of each of those two jobs with your `v1.2.3` tag.) Wait for them to complete successfully.
3. Click into those two build jobs, and on each job's "Summary" tab, download our build artifacts. The browser extension build job should have `chrome-extension` and `firefox-extension-signed` artifacts, and the plugin build job should have `com.chrisregado.googlemeet.streamDeckPlugin`.
4. Do a final manual validation of those release artifacts. Install the plugin, Firefox extension, and Chrome extension, and verify basic functionality.
3. Click into those two build jobs, and on each job's "Summary" tab, download our build artifacts. The browser extension build job should have `chrome-extension` and `firefox-extension-signed` artifacts, and the plugin build job should have `com.chrisregado.googlemeet.streamDeckPlugin` (macOS/Windows, Elgato-validated) and `com.chrisregado.googlemeet-linux.streamDeckPlugin` (Linux-inclusive, for OpenDeck).
4. Do a final manual validation of those release artifacts. Install the plugin, Firefox extension, and Chrome extension, and verify basic functionality. If you have access to a Linux machine with OpenDeck, test the Linux-inclusive package as well.
5. On the Github page for your repo, click "Releases". (https://github.com/ChrisRegado/streamdeck-googlemeet/releases)
6. Click "Draft a new release".
7. Click the "Tag" button and select the tag you made in the previous step.
8. Use the your tag name as the "Release title", and enter a description summarizing notable changes in this release.
9. Select the "Set as a pre-release" checkbox near the bottom of the page.
10. Click "Publish release".
11. Our [release CI job](https://github.com/ChrisRegado/streamdeck-googlemeet/actions/workflows/release.yaml) should automatically start and attach our tag's artifacts to the GitHub Release. Wait for it to complete. If all goes well, in a minute or two you should see 3 attachments appear on the release: the `com.chrisregado.googlemeet.streamDeckPlugin` plugin, a zip of the Chrome extension, and an `.xpi` file for the Firefox extension.
11. Our [release CI job](https://github.com/ChrisRegado/streamdeck-googlemeet/actions/workflows/release.yaml) should automatically start and attach our tag's artifacts to the GitHub Release. Wait for it to complete. If all goes well, in a minute or two you should see 4 attachments appear on the release: the `com.chrisregado.googlemeet.streamDeckPlugin` plugin (macOS/Windows), the `com.chrisregado.googlemeet-linux.streamDeckPlugin` (Linux-inclusive, for OpenDeck), a zip of the Chrome extension, and an `.xpi` file for the Firefox extension.
12. Edit the release, uncheck the "Set as a pre-release" checkbox at the bottom of the page, select the "Set as the latest release" checkbox, and click "Update release".
4 changes: 4 additions & 0 deletions com.chrisregado.googlemeet.sdPlugin/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,7 @@
"CodePath": "dist/macos/main/main",
"CodePathMac": "dist/macos/main/main",
"CodePathWin": "dist/windows/main/main.exe",
"CodePathLin": "dist/linux/main/main",
"Description": "A Stream Deck plugin to manage your Google Meet calls.",
"Name": "Google Meet",
"UUID": "com.chrisregado.googlemeet",
Expand All @@ -441,6 +442,9 @@
{
"Platform": "windows",
"MinimumVersion": "10"
},
{
"Platform": "linux"
}
],
"Software": {
Expand Down
4 changes: 2 additions & 2 deletions streamdeck-plugin/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
altgraph==0.17.4
macholib==1.16.3
altgraph==0.17.4; sys_platform == 'darwin'
macholib==1.16.3; sys_platform == 'darwin'
packaging==25.0
pyinstaller==6.14.2
pyinstaller-hooks-contrib==2025.8
Expand Down